8 // A TestableVolumeManagerFactory creates a volume manager with at least two TestableVolume instances.
9 // The factory function, and the TestableVolume instances it returns, can use "t" to write
10 // logs, fail the current test, etc.
11 type TestableVolumeManagerFactory func(t *testing.T) (*RRVolumeManager, []TestableVolume)
13 // DoHandlersWithGenericVolumeTests runs a set of handler tests with a
14 // Volume Manager comprised of TestableVolume instances.
15 // It calls factory to create a volume manager with TestableVolume
16 // instances for each test case, to avoid leaking state between tests.
17 func DoHandlersWithGenericVolumeTests(t *testing.T, factory TestableVolumeManagerFactory) {
18 testGetBlock(t, factory, TestHash, TestBlock)
19 testGetBlock(t, factory, EmptyHash, EmptyBlock)
20 testPutRawBadDataGetBlock(t, factory, TestHash, TestBlock, []byte("baddata"))
21 testPutRawBadDataGetBlock(t, factory, EmptyHash, EmptyBlock, []byte("baddata"))
22 testPutBlock(t, factory, TestHash, TestBlock)
23 testPutBlock(t, factory, EmptyHash, EmptyBlock)
24 testPutBlockCorrupt(t, factory, TestHash, TestBlock, []byte("baddata"))
25 testPutBlockCorrupt(t, factory, EmptyHash, EmptyBlock, []byte("baddata"))
28 // Setup RRVolumeManager with TestableVolumes
29 func setupHandlersWithGenericVolumeTest(t *testing.T, factory TestableVolumeManagerFactory) []TestableVolume {
30 vm, testableVolumes := factory(t)
33 for _, v := range testableVolumes {
38 return testableVolumes
41 // Put a block using PutRaw in just one volume and Get it using GetBlock
42 func testGetBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
43 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
45 // Put testBlock in one volume
46 testableVolumes[1].PutRaw(testHash, testBlock)
49 buf, err := GetBlock(testHash)
51 t.Fatalf("Error while getting block %s", err)
53 if bytes.Compare(buf, testBlock) != 0 {
54 t.Errorf("Put succeeded but Get returned %+v, expected %+v", buf, testBlock)
58 // Put a bad block using PutRaw and get it.
59 func testPutRawBadDataGetBlock(t *testing.T, factory TestableVolumeManagerFactory,
60 testHash string, testBlock []byte, badData []byte) {
61 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
63 // Put bad data for testHash in both volumes
64 testableVolumes[0].PutRaw(testHash, badData)
65 testableVolumes[1].PutRaw(testHash, badData)
68 _, err := GetBlock(testHash)
70 t.Fatalf("Expected error while getting corrupt block %v", testHash)
74 // Invoke PutBlock twice to ensure CompareAndTouch path is tested.
75 func testPutBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
76 setupHandlersWithGenericVolumeTest(t, factory)
79 if err := PutBlock(testBlock, testHash); err != nil {
80 t.Fatalf("Error during PutBlock: %s", err)
83 // Check that PutBlock succeeds again even after CompareAndTouch
84 if err := PutBlock(testBlock, testHash); err != nil {
85 t.Fatalf("Error during PutBlock: %s", err)
88 // Check that PutBlock stored the data as expected
89 buf, err := GetBlock(testHash)
91 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
92 } else if bytes.Compare(buf, testBlock) != 0 {
93 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)
97 // Put a bad block using PutRaw, overwrite it using PutBlock and get it.
98 func testPutBlockCorrupt(t *testing.T, factory TestableVolumeManagerFactory,
99 testHash string, testBlock []byte, badData []byte) {
100 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
102 // Put bad data for testHash in both volumes
103 testableVolumes[0].PutRaw(testHash, badData)
104 testableVolumes[1].PutRaw(testHash, badData)
106 // Check that PutBlock with good data succeeds
107 if err := PutBlock(testBlock, testHash); err != nil {
108 t.Fatalf("Error during PutBlock for %q: %s", testHash, err)
111 // Put succeeded and overwrote the badData in one volume,
112 // and Get should return the testBlock now, ignoring the bad data.
113 buf, err := GetBlock(testHash)
115 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
116 } else if bytes.Compare(buf, testBlock) != 0 {
117 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)