ducky/devices
ducky/devices/storer_test.go
Set up DeleteDevices in Memstore. Implement the DeleteDevices method for our Memstore, removing the Devices specified by the passed IDs. Also, create a simple test that verifies that when Devices are deleted, only the Devices you intend to delete are actually deleted. Further tests should be written to verify that this extends to ListDevicesByOwner (e.g., deleted devices will not be returned when listing them), CreateDevices (e.g., will not result in an ErrDeviceAlreadyExists error), and UpdateDevice (e.g., will return an ErrDeviceNotFound error after the Device is deleted). But for now, we're confident that it works in the simplest possible case.
| paddy@2 | 1 package devices |
| paddy@2 | 2 |
| paddy@2 | 3 import ( |
| paddy@10 | 4 "fmt" |
| paddy@2 | 5 "testing" |
| paddy@2 | 6 "time" |
| paddy@2 | 7 |
| paddy@2 | 8 "code.secondbit.org/uuid.hg" |
| paddy@2 | 9 "golang.org/x/net/context" |
| paddy@2 | 10 ) |
| paddy@2 | 11 |
| paddy@9 | 12 type StorerFactory interface { |
| paddy@9 | 13 NewStorer(ctx context.Context) (Storer, error) |
| paddy@9 | 14 TeardownStorer(storer Storer, ctx context.Context) error |
| paddy@9 | 15 } |
| paddy@9 | 16 |
| paddy@9 | 17 var storerFactories []StorerFactory |
| paddy@2 | 18 |
| paddy@10 | 19 const ( |
| paddy@10 | 20 changeName = 1 << iota |
| paddy@10 | 21 changeOwner |
| paddy@10 | 22 changeType |
| paddy@10 | 23 changeCreated |
| paddy@10 | 24 changeLastSeen |
| paddy@10 | 25 changePushToken |
| paddy@10 | 26 changeVariations |
| paddy@10 | 27 ) |
| paddy@10 | 28 |
| paddy@2 | 29 func compareDevices(device1, device2 Device) (ok bool, field string, expected, result interface{}) { |
| paddy@2 | 30 if !device1.ID.Equal(device2.ID) { |
| paddy@2 | 31 return false, "ID", device1.ID, device2.ID |
| paddy@2 | 32 } |
| paddy@2 | 33 if device1.Name != device2.Name { |
| paddy@2 | 34 return false, "Name", device1.Name, device2.Name |
| paddy@2 | 35 } |
| paddy@2 | 36 if !device1.Owner.Equal(device2.Owner) { |
| paddy@2 | 37 return false, "Owner", device1.Owner, device2.Owner |
| paddy@2 | 38 } |
| paddy@2 | 39 if device1.Type != device2.Type { |
| paddy@2 | 40 return false, "Type", device1.Type, device2.Type |
| paddy@2 | 41 } |
| paddy@2 | 42 if !device1.Created.Equal(device2.Created) { |
| paddy@2 | 43 return false, "Created", device1.Created, device2.Created |
| paddy@2 | 44 } |
| paddy@2 | 45 if !device1.LastSeen.Equal(device2.LastSeen) { |
| paddy@2 | 46 return false, "LastSeen", device1.LastSeen, device2.LastSeen |
| paddy@2 | 47 } |
| paddy@2 | 48 if device1.PushToken != device2.PushToken { |
| paddy@2 | 49 return false, "PushToken", device1.PushToken, device2.PushToken |
| paddy@2 | 50 } |
| paddy@2 | 51 return true, "", nil, nil |
| paddy@2 | 52 } |
| paddy@2 | 53 |
| paddy@5 | 54 func TestCreateAndGetDevices(t *testing.T) { |
| paddy@9 | 55 for _, factory := range storerFactories { |
| paddy@10 | 56 ctx := context.Background() |
| paddy@10 | 57 storer, err := factory.NewStorer(ctx) |
| paddy@2 | 58 if err != nil { |
| paddy@9 | 59 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@2 | 60 } |
| paddy@2 | 61 |
| paddy@2 | 62 devices := []Device{ |
| paddy@2 | 63 {ID: uuid.NewID(), Name: "Test 1", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@2 | 64 {ID: uuid.NewID(), Name: "Test 2", Owner: uuid.NewID(), Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@2 | 65 {ID: uuid.NewID(), Name: "Test 3", Owner: uuid.NewID(), Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@2 | 66 } |
| paddy@3 | 67 |
| paddy@10 | 68 err = storer.CreateDevices(devices, ctx) |
| paddy@3 | 69 if err != nil { |
| paddy@5 | 70 t.Errorf("Error creating devices in %T: %+v\n", storer, err) |
| paddy@3 | 71 } |
| paddy@3 | 72 |
| paddy@2 | 73 ids := make([]uuid.ID, 0, len(devices)) |
| paddy@2 | 74 for _, device := range devices { |
| paddy@2 | 75 ids = append(ids, device.ID) |
| paddy@2 | 76 } |
| paddy@2 | 77 |
| paddy@10 | 78 results, err := storer.GetDevices(ids, ctx) |
| paddy@2 | 79 if err != nil { |
| paddy@2 | 80 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err) |
| paddy@2 | 81 } |
| paddy@2 | 82 for _, device := range devices { |
| paddy@2 | 83 d, returned := results[device.ID.String()] |
| paddy@2 | 84 if !returned { |
| paddy@2 | 85 t.Errorf("Expected device %s to be in results from %T, but wasn't present\n", device.Name, storer) |
| paddy@2 | 86 } |
| paddy@2 | 87 ok, field, expected, result := compareDevices(device, d) |
| paddy@2 | 88 if !ok { |
| paddy@2 | 89 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, device.Name, expected, result, storer) |
| paddy@2 | 90 } |
| paddy@2 | 91 } |
| paddy@10 | 92 err = factory.TeardownStorer(storer, ctx) |
| paddy@2 | 93 if err != nil { |
| paddy@2 | 94 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@2 | 95 } |
| paddy@2 | 96 } |
| paddy@2 | 97 } |
| paddy@5 | 98 |
| paddy@5 | 99 func TestGetDevicesNoErrorForMissing(t *testing.T) { |
| paddy@9 | 100 for _, factory := range storerFactories { |
| paddy@10 | 101 ctx := context.Background() |
| paddy@10 | 102 storer, err := factory.NewStorer(ctx) |
| paddy@5 | 103 if err != nil { |
| paddy@9 | 104 t.Fatalf("Fatal error creatng Storer from %T: %+v\n", factory, err) |
| paddy@5 | 105 } |
| paddy@5 | 106 |
| paddy@10 | 107 results, err := storer.GetDevices([]uuid.ID{uuid.NewID()}, ctx) |
| paddy@5 | 108 if err != nil { |
| paddy@5 | 109 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err) |
| paddy@5 | 110 } |
| paddy@5 | 111 if len(results) != 0 { |
| paddy@5 | 112 t.Errorf("Expected results to be empty, got %+v from %T instead\n", results, storer) |
| paddy@5 | 113 } |
| paddy@10 | 114 err = factory.TeardownStorer(storer, ctx) |
| paddy@5 | 115 if err != nil { |
| paddy@5 | 116 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@5 | 117 } |
| paddy@5 | 118 } |
| paddy@5 | 119 } |
| paddy@5 | 120 |
| paddy@5 | 121 func TestCreateDevicesDuplicates(t *testing.T) { |
| paddy@9 | 122 for _, factory := range storerFactories { |
| paddy@10 | 123 ctx := context.Background() |
| paddy@10 | 124 storer, err := factory.NewStorer(ctx) |
| paddy@5 | 125 if err != nil { |
| paddy@9 | 126 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@5 | 127 } |
| paddy@5 | 128 |
| paddy@5 | 129 devices := []Device{ |
| paddy@5 | 130 {ID: uuid.NewID(), Name: "Test 1", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@5 | 131 {ID: uuid.NewID(), Name: "Test 2", Owner: uuid.NewID(), Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@5 | 132 {ID: uuid.NewID(), Name: "Test 3", Owner: uuid.NewID(), Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@5 | 133 } |
| paddy@5 | 134 |
| paddy@10 | 135 err = storer.CreateDevices(devices, ctx) |
| paddy@5 | 136 if err != nil { |
| paddy@5 | 137 t.Errorf("Unexpected error creating devices in %T: %+v\n", storer, err) |
| paddy@5 | 138 } |
| paddy@5 | 139 |
| paddy@5 | 140 newDevices := []Device{ |
| paddy@5 | 141 {ID: uuid.NewID(), Name: "Test 4", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@5 | 142 {ID: uuid.NewID(), Name: "Test 5", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@5 | 143 } |
| paddy@5 | 144 |
| paddy@10 | 145 err = storer.CreateDevices([]Device{newDevices[0], devices[1], newDevices[1]}, ctx) |
| paddy@5 | 146 daeErr, ok := err.(ErrDeviceAlreadyExists) |
| paddy@5 | 147 if !ok { |
| paddy@5 | 148 t.Errorf("Expected ErrDeviceAlreadyExists creating duplicate device in %T, got %+v\n", storer, err) |
| paddy@5 | 149 } |
| paddy@5 | 150 if !uuid.ID(daeErr).Equal(devices[1].ID) { |
| paddy@5 | 151 t.Errorf("Expected ErrDeviceAlreadyExists to be %+v, got %+v from %T\n", devices[1].ID, daeErr, storer) |
| paddy@5 | 152 } |
| paddy@5 | 153 |
| paddy@5 | 154 // inserts should be a transaction; they either all make it, or none do |
| paddy@10 | 155 results, err := storer.GetDevices([]uuid.ID{newDevices[0].ID, newDevices[1].ID}, ctx) |
| paddy@5 | 156 if err != nil { |
| paddy@5 | 157 t.Errorf("Error retrieving devices from %T: %+v\n", storer, err) |
| paddy@5 | 158 } |
| paddy@5 | 159 if len(results) != 0 { |
| paddy@5 | 160 t.Errorf("Expected new inserts to not be in results, got %+v from %T\n", results, storer) |
| paddy@5 | 161 } |
| paddy@5 | 162 |
| paddy@10 | 163 err = factory.TeardownStorer(storer, ctx) |
| paddy@5 | 164 if err != nil { |
| paddy@5 | 165 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@5 | 166 } |
| paddy@5 | 167 } |
| paddy@5 | 168 } |
| paddy@8 | 169 |
| paddy@8 | 170 func TestCreateAndListDevicesByOwner(t *testing.T) { |
| paddy@9 | 171 for _, factory := range storerFactories { |
| paddy@10 | 172 ctx := context.Background() |
| paddy@10 | 173 storer, err := factory.NewStorer(ctx) |
| paddy@8 | 174 if err != nil { |
| paddy@9 | 175 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@8 | 176 } |
| paddy@8 | 177 |
| paddy@8 | 178 owner1, owner2 := uuid.NewID(), uuid.NewID() |
| paddy@8 | 179 devices := []Device{ |
| paddy@8 | 180 {ID: uuid.NewID(), Name: "Test 1", Owner: owner1, Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@8 | 181 {ID: uuid.NewID(), Name: "Test 2", Owner: owner2, Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@8 | 182 {ID: uuid.NewID(), Name: "Test 3", Owner: owner1, Type: TypeChromeExtension, Created: time.Now().Add(time.Minute), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@8 | 183 } |
| paddy@8 | 184 |
| paddy@10 | 185 err = storer.CreateDevices(devices, ctx) |
| paddy@8 | 186 if err != nil { |
| paddy@8 | 187 t.Errorf("Error creating devices in %T: %+v\n", storer, err) |
| paddy@8 | 188 } |
| paddy@8 | 189 |
| paddy@10 | 190 results, err := storer.ListDevicesByOwner(owner1, ctx) |
| paddy@8 | 191 if err != nil { |
| paddy@8 | 192 t.Errorf("Error listing devices for owner1 from %T: %+v\n", storer, err) |
| paddy@8 | 193 } |
| paddy@8 | 194 if len(results) != 2 { |
| paddy@8 | 195 t.Errorf("Expected %d results for owner1, got %d from %T\n", 2, len(results), storer) |
| paddy@8 | 196 } |
| paddy@8 | 197 resultMap := ToMap(results) |
| paddy@8 | 198 d, ok := resultMap[devices[0].ID.String()] |
| paddy@8 | 199 if !ok { |
| paddy@8 | 200 t.Errorf("Expected to get %s in results, got %+v from %T\n", devices[0].Name, results, storer) |
| paddy@8 | 201 } |
| paddy@8 | 202 ok, field, expected, result := compareDevices(devices[0], d) |
| paddy@8 | 203 if !ok { |
| paddy@8 | 204 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[0].Name, expected, result, storer) |
| paddy@8 | 205 } |
| paddy@8 | 206 d, ok = resultMap[devices[2].ID.String()] |
| paddy@8 | 207 if !ok { |
| paddy@8 | 208 t.Errorf("Expected to get %s in results, got %+v from %T\n", devices[2].Name, results, storer) |
| paddy@8 | 209 } |
| paddy@8 | 210 ok, field, expected, result = compareDevices(devices[2], d) |
| paddy@8 | 211 if !ok { |
| paddy@8 | 212 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[2].Name, expected, result, storer) |
| paddy@8 | 213 } |
| paddy@8 | 214 |
| paddy@10 | 215 results, err = storer.ListDevicesByOwner(owner2, ctx) |
| paddy@8 | 216 if err != nil { |
| paddy@8 | 217 t.Errorf("Error listing devices for owner2 from %T: %+v\n", storer, err) |
| paddy@8 | 218 } |
| paddy@8 | 219 if len(results) != 1 { |
| paddy@8 | 220 t.Errorf("Expected %d results for owner2, got %d from %T\n", 1, len(results), storer) |
| paddy@8 | 221 } |
| paddy@8 | 222 ok, field, expected, result = compareDevices(devices[1], results[0]) |
| paddy@8 | 223 if !ok { |
| paddy@8 | 224 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, devices[1].Name, expected, result, storer) |
| paddy@8 | 225 } |
| paddy@8 | 226 |
| paddy@10 | 227 err = factory.TeardownStorer(storer, ctx) |
| paddy@8 | 228 if err != nil { |
| paddy@8 | 229 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@8 | 230 } |
| paddy@8 | 231 } |
| paddy@8 | 232 } |
| paddy@10 | 233 |
| paddy@10 | 234 func TestUpdateDevicesHappyPath(t *testing.T) { |
| paddy@10 | 235 device := Device{ |
| paddy@10 | 236 ID: uuid.NewID(), |
| paddy@10 | 237 Name: "Test 1", |
| paddy@10 | 238 Owner: uuid.NewID(), |
| paddy@10 | 239 Type: TypeAndroidPhone, |
| paddy@10 | 240 Created: time.Now(), |
| paddy@10 | 241 LastSeen: time.Now(), |
| paddy@10 | 242 PushToken: "test token", |
| paddy@10 | 243 } |
| paddy@10 | 244 for _, factory := range storerFactories { |
| paddy@10 | 245 ctx := context.Background() |
| paddy@10 | 246 storer, err := factory.NewStorer(ctx) |
| paddy@10 | 247 if err != nil { |
| paddy@10 | 248 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@10 | 249 } |
| paddy@10 | 250 for i := 1; i < changeVariations; i++ { |
| paddy@10 | 251 var change DeviceChange |
| paddy@10 | 252 var owner uuid.ID |
| paddy@10 | 253 var name, pushToken string |
| paddy@10 | 254 var created, lastSeen time.Time |
| paddy@10 | 255 var deviceType DeviceType |
| paddy@10 | 256 |
| paddy@10 | 257 device.ID = uuid.NewID() |
| paddy@10 | 258 |
| paddy@10 | 259 expectation := device |
| paddy@10 | 260 result := device |
| paddy@10 | 261 |
| paddy@10 | 262 change.DeviceID = device.ID |
| paddy@10 | 263 |
| paddy@10 | 264 if i&changeName != 0 { |
| paddy@10 | 265 name = fmt.Sprintf("name-%d", i) |
| paddy@10 | 266 change.Name = &name |
| paddy@10 | 267 expectation.Name = name |
| paddy@10 | 268 } |
| paddy@10 | 269 if i&changeOwner != 0 { |
| paddy@10 | 270 owner = uuid.NewID() |
| paddy@10 | 271 change.Owner = &owner |
| paddy@10 | 272 expectation.Owner = owner |
| paddy@10 | 273 } |
| paddy@10 | 274 if i&changeType != 0 { |
| paddy@10 | 275 deviceType = DeviceType(fmt.Sprintf("type-%d", i)) |
| paddy@10 | 276 change.Type = &deviceType |
| paddy@10 | 277 expectation.Type = deviceType |
| paddy@10 | 278 } |
| paddy@10 | 279 if i&changeCreated != 0 { |
| paddy@10 | 280 created = time.Now().Add(time.Hour * time.Duration(i)) |
| paddy@10 | 281 change.Created = &created |
| paddy@10 | 282 expectation.Created = created |
| paddy@10 | 283 } |
| paddy@10 | 284 if i&changeLastSeen != 0 { |
| paddy@10 | 285 lastSeen = time.Now().Add(time.Minute * time.Duration(i*-1)) |
| paddy@10 | 286 change.LastSeen = &lastSeen |
| paddy@10 | 287 expectation.LastSeen = lastSeen |
| paddy@10 | 288 } |
| paddy@10 | 289 if i&changePushToken != 0 { |
| paddy@10 | 290 pushToken = fmt.Sprintf("push-token-%d", i) |
| paddy@10 | 291 change.PushToken = &pushToken |
| paddy@10 | 292 expectation.PushToken = pushToken |
| paddy@10 | 293 } |
| paddy@10 | 294 result = ApplyChange(result, change) |
| paddy@10 | 295 ok, field, expectedVal, resultVal := compareDevices(expectation, result) |
| paddy@10 | 296 if !ok { |
| paddy@10 | 297 t.Errorf("Expected %s of %s to be %v, got %v after applying DeviceChange %+v\n", field, device.Name, expectedVal, resultVal, change) |
| paddy@10 | 298 } |
| paddy@10 | 299 |
| paddy@10 | 300 err = storer.CreateDevices([]Device{device}, ctx) |
| paddy@10 | 301 if err != nil { |
| paddy@10 | 302 t.Errorf("Unexpected error creating devices in %T: %+v\n", storer, err) |
| paddy@10 | 303 } |
| paddy@10 | 304 |
| paddy@10 | 305 err = storer.UpdateDevice(change, ctx) |
| paddy@10 | 306 if err != nil { |
| paddy@10 | 307 t.Errorf("Unexpected error updating device in %T: %+v\n", storer, err) |
| paddy@10 | 308 } |
| paddy@10 | 309 |
| paddy@10 | 310 retrieved, err := storer.GetDevices([]uuid.ID{device.ID}, ctx) |
| paddy@10 | 311 if err != nil { |
| paddy@10 | 312 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err) |
| paddy@10 | 313 } |
| paddy@10 | 314 retrievedDevice, ok := retrieved[device.ID.String()] |
| paddy@10 | 315 if !ok { |
| paddy@10 | 316 t.Errorf("Expected retrieved devices to contain %s, got %+v from %T\n", device.Name, retrieved, storer) |
| paddy@10 | 317 } |
| paddy@10 | 318 ok, field, expectedVal, resultVal = compareDevices(expectation, retrievedDevice) |
| paddy@10 | 319 if !ok { |
| paddy@10 | 320 t.Errorf("Expected %s of %s to be %v, got %v from %T\n", field, device.Name, expectedVal, resultVal, storer) |
| paddy@10 | 321 } |
| paddy@10 | 322 } |
| paddy@10 | 323 |
| paddy@10 | 324 err = factory.TeardownStorer(storer, ctx) |
| paddy@10 | 325 if err != nil { |
| paddy@10 | 326 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@10 | 327 } |
| paddy@10 | 328 } |
| paddy@10 | 329 } |
| paddy@11 | 330 |
| paddy@11 | 331 func TestUpdateDeviceNotFound(t *testing.T) { |
| paddy@11 | 332 for _, factory := range storerFactories { |
| paddy@11 | 333 ctx := context.Background() |
| paddy@11 | 334 storer, err := factory.NewStorer(ctx) |
| paddy@11 | 335 if err != nil { |
| paddy@11 | 336 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@11 | 337 } |
| paddy@11 | 338 |
| paddy@11 | 339 deviceID := uuid.NewID() |
| paddy@11 | 340 name := "my new name" |
| paddy@11 | 341 change := DeviceChange{DeviceID: deviceID, Name: &name} |
| paddy@11 | 342 |
| paddy@11 | 343 err = storer.UpdateDevice(change, ctx) |
| paddy@11 | 344 if err != ErrDeviceNotFound { |
| paddy@11 | 345 t.Errorf("Expected error to be ErrDeviceNotFound, %T returned %+v\n", storer, err) |
| paddy@11 | 346 } |
| paddy@11 | 347 |
| paddy@11 | 348 results, err := storer.GetDevices([]uuid.ID{deviceID}, ctx) |
| paddy@11 | 349 if err != nil { |
| paddy@11 | 350 t.Errorf("Error retrieving devices from %T: %+v\n", storer, err) |
| paddy@11 | 351 } |
| paddy@11 | 352 if len(results) != 0 { |
| paddy@11 | 353 t.Errorf("Expected no devices in %T, got %+v\n", storer, results) |
| paddy@11 | 354 } |
| paddy@11 | 355 |
| paddy@11 | 356 err = factory.TeardownStorer(storer, ctx) |
| paddy@11 | 357 if err != nil { |
| paddy@11 | 358 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@11 | 359 } |
| paddy@11 | 360 } |
| paddy@11 | 361 } |
| paddy@14 | 362 |
| paddy@14 | 363 func TestDeleteDevicesHappyPath(t *testing.T) { |
| paddy@14 | 364 for _, factory := range storerFactories { |
| paddy@14 | 365 ctx := context.Background() |
| paddy@14 | 366 storer, err := factory.NewStorer(ctx) |
| paddy@14 | 367 if err != nil { |
| paddy@14 | 368 t.Fatalf("Fatal error creating Storer from %T: %+v\n", factory, err) |
| paddy@14 | 369 } |
| paddy@14 | 370 |
| paddy@14 | 371 owner1, owner2 := uuid.NewID(), uuid.NewID() |
| paddy@14 | 372 |
| paddy@14 | 373 devices := []Device{ |
| paddy@14 | 374 {ID: uuid.NewID(), Name: "Test 1", Owner: owner1, Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@14 | 375 {ID: uuid.NewID(), Name: "Test 2", Owner: owner2, Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@14 | 376 {ID: uuid.NewID(), Name: "Test 3", Owner: owner1, Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, |
| paddy@14 | 377 } |
| paddy@14 | 378 |
| paddy@14 | 379 err = storer.CreateDevices(devices, ctx) |
| paddy@14 | 380 if err != nil { |
| paddy@14 | 381 t.Errorf("Error creating devices in %T: %+v\n", storer, err) |
| paddy@14 | 382 } |
| paddy@14 | 383 |
| paddy@14 | 384 err = storer.DeleteDevices([]uuid.ID{devices[0].ID, devices[1].ID}, ctx) |
| paddy@14 | 385 if err != nil { |
| paddy@14 | 386 t.Errorf("Error deleting devices from %T: %+v\n", storer, err) |
| paddy@14 | 387 } |
| paddy@14 | 388 |
| paddy@14 | 389 results, err := storer.GetDevices([]uuid.ID{devices[0].ID, devices[1].ID, devices[2].ID}, ctx) |
| paddy@14 | 390 if err != nil { |
| paddy@14 | 391 t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err) |
| paddy@14 | 392 } |
| paddy@14 | 393 |
| paddy@14 | 394 if len(results) != 1 { |
| paddy@14 | 395 t.Errorf("Expected %d results, got %d from %T\n", 1, len(results), storer) |
| paddy@14 | 396 } |
| paddy@14 | 397 |
| paddy@14 | 398 device, ok := results[devices[0].ID.String()] |
| paddy@14 | 399 if ok { |
| paddy@14 | 400 t.Errorf("Retrieved first device (which was deleted!) from %T: %+v\n", storer, device) |
| paddy@14 | 401 } |
| paddy@14 | 402 |
| paddy@14 | 403 device, ok = results[devices[1].ID.String()] |
| paddy@14 | 404 if ok { |
| paddy@14 | 405 t.Errorf("Retrieved second device (which was deleted!) from %T: %+v\n", storer, device) |
| paddy@14 | 406 } |
| paddy@14 | 407 |
| paddy@14 | 408 device, ok = results[devices[2].ID.String()] |
| paddy@14 | 409 if !ok { |
| paddy@14 | 410 t.Errorf("Didn't retrieve third device (which wasn't deleted!) from %T. Got %+v\n", storer, results) |
| paddy@14 | 411 } |
| paddy@14 | 412 |
| paddy@14 | 413 err = factory.TeardownStorer(storer, ctx) |
| paddy@14 | 414 if err != nil { |
| paddy@14 | 415 t.Errorf("Error cleaning up after %T: %+v\n", storer, err) |
| paddy@14 | 416 } |
| paddy@14 | 417 } |
| paddy@14 | 418 } |