ducky/devices
ducky/devices/storer_test.go
Add more interface tests. Add a test to ensure that, when retrieving Devices, no error is returned if a Device cannot be found. Add a test to ensure that, when adding Devices, adding a Device that shares an ID with a Device already in the Storer returns an ErrDeviceAlreadyExists error. This involved creating the ErrDeviceAlreadyExists error, and modifying the in-memory implementation to properly return it. Fix a go vet issue in our previous test, wherein we forgot to pass the storer to a log message, resulting in a mismatch between the number of variables expected and the number of variables provided. Rename our tests to be better reflective of what they actually test.
1.1 --- a/storer_test.go Thu Nov 12 23:26:26 2015 -0800 1.2 +++ b/storer_test.go Sat Nov 14 05:56:04 2015 -0800 1.3 @@ -35,7 +35,7 @@ 1.4 return true, "", nil, nil 1.5 } 1.6 1.7 -func TestGetDevicesHappyPath(t *testing.T) { 1.8 +func TestCreateAndGetDevices(t *testing.T) { 1.9 for _, storer := range storers { 1.10 storer, err := storer.Factory(context.TODO()) 1.11 if err != nil { 1.12 @@ -50,7 +50,7 @@ 1.13 1.14 err = storer.CreateDevices(devices, context.TODO()) 1.15 if err != nil { 1.16 - t.Errorf("Error creating devices in %T: %+v\n", err) 1.17 + t.Errorf("Error creating devices in %T: %+v\n", storer, err) 1.18 } 1.19 1.20 ids := make([]uuid.ID, 0, len(devices)) 1.21 @@ -78,3 +78,72 @@ 1.22 } 1.23 } 1.24 } 1.25 + 1.26 +func TestGetDevicesNoErrorForMissing(t *testing.T) { 1.27 + for _, storer := range storers { 1.28 + storer, err := storer.Factory(context.TODO()) 1.29 + if err != nil { 1.30 + t.Fatalf("Fatal error creatng %T: %+v\n", storer, err) 1.31 + } 1.32 + 1.33 + results, err := storer.GetDevices([]uuid.ID{uuid.NewID()}, context.TODO()) 1.34 + if err != nil { 1.35 + t.Errorf("Unexpected error retrieving devices from %T: %+v\n", storer, err) 1.36 + } 1.37 + if len(results) != 0 { 1.38 + t.Errorf("Expected results to be empty, got %+v from %T instead\n", results, storer) 1.39 + } 1.40 + err = storer.Destroy(context.TODO()) 1.41 + if err != nil { 1.42 + t.Errorf("Error cleaning up after %T: %+v\n", storer, err) 1.43 + } 1.44 + } 1.45 +} 1.46 + 1.47 +func TestCreateDevicesDuplicates(t *testing.T) { 1.48 + for _, storer := range storers { 1.49 + storer, err := storer.Factory(context.TODO()) 1.50 + if err != nil { 1.51 + t.Fatalf("Fatal error creating %T: %+v\n", storer, err) 1.52 + } 1.53 + 1.54 + devices := []Device{ 1.55 + {ID: uuid.NewID(), Name: "Test 1", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, 1.56 + {ID: uuid.NewID(), Name: "Test 2", Owner: uuid.NewID(), Type: TypeAndroidTablet, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, 1.57 + {ID: uuid.NewID(), Name: "Test 3", Owner: uuid.NewID(), Type: TypeChromeExtension, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, 1.58 + } 1.59 + 1.60 + err = storer.CreateDevices(devices, context.TODO()) 1.61 + if err != nil { 1.62 + t.Errorf("Unexpected error creating devices in %T: %+v\n", storer, err) 1.63 + } 1.64 + 1.65 + newDevices := []Device{ 1.66 + {ID: uuid.NewID(), Name: "Test 4", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, 1.67 + {ID: uuid.NewID(), Name: "Test 5", Owner: uuid.NewID(), Type: TypeAndroidPhone, Created: time.Now(), LastSeen: time.Now(), PushToken: "test token"}, 1.68 + } 1.69 + 1.70 + err = storer.CreateDevices([]Device{newDevices[0], devices[1], newDevices[1]}, context.TODO()) 1.71 + daeErr, ok := err.(ErrDeviceAlreadyExists) 1.72 + if !ok { 1.73 + t.Errorf("Expected ErrDeviceAlreadyExists creating duplicate device in %T, got %+v\n", storer, err) 1.74 + } 1.75 + if !uuid.ID(daeErr).Equal(devices[1].ID) { 1.76 + t.Errorf("Expected ErrDeviceAlreadyExists to be %+v, got %+v from %T\n", devices[1].ID, daeErr, storer) 1.77 + } 1.78 + 1.79 + // inserts should be a transaction; they either all make it, or none do 1.80 + results, err := storer.GetDevices([]uuid.ID{newDevices[0].ID, newDevices[1].ID}, context.TODO()) 1.81 + if err != nil { 1.82 + t.Errorf("Error retrieving devices from %T: %+v\n", storer, err) 1.83 + } 1.84 + if len(results) != 0 { 1.85 + t.Errorf("Expected new inserts to not be in results, got %+v from %T\n", results, storer) 1.86 + } 1.87 + 1.88 + err = storer.Destroy(context.TODO()) 1.89 + if err != nil { 1.90 + t.Errorf("Error cleaning up after %T: %+v\n", storer, err) 1.91 + } 1.92 + } 1.93 +}