7 // A TestableVolumeManagerFactory creates a volume manager with at least two TestableVolume instances.
8 // The factory function, and the TestableVolume instances it returns, can use "t" to write
9 // logs, fail the current test, etc.
10 type TestableVolumeManagerFactory func(t TB) (*RRVolumeManager, []TestableVolume)
12 // DoHandlersWithGenericVolumeTests runs a set of handler tests with a
13 // Volume Manager comprised of TestableVolume instances.
14 // It calls factory to create a volume manager with TestableVolume
15 // instances for each test case, to avoid leaking state between tests.
16 func DoHandlersWithGenericVolumeTests(t TB, factory TestableVolumeManagerFactory) {
17 testGetBlock(t, factory, TestHash, TestBlock)
18 testGetBlock(t, factory, EmptyHash, EmptyBlock)
19 testPutRawBadDataGetBlock(t, factory, TestHash, TestBlock, []byte("baddata"))
20 testPutRawBadDataGetBlock(t, factory, EmptyHash, EmptyBlock, []byte("baddata"))
21 testPutBlock(t, factory, TestHash, TestBlock)
22 testPutBlock(t, factory, EmptyHash, EmptyBlock)
23 testPutBlockCorrupt(t, factory, TestHash, TestBlock, []byte("baddata"))
24 testPutBlockCorrupt(t, factory, EmptyHash, EmptyBlock, []byte("baddata"))
27 // Setup RRVolumeManager with TestableVolumes
28 func setupHandlersWithGenericVolumeTest(t TB, factory TestableVolumeManagerFactory) []TestableVolume {
29 vm, testableVolumes := factory(t)
32 for _, v := range testableVolumes {
37 return testableVolumes
40 // Put a block using PutRaw in just one volume and Get it using GetBlock
41 func testGetBlock(t TB, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
42 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
44 // Put testBlock in one volume
45 testableVolumes[1].PutRaw(testHash, testBlock)
48 buf, err := GetBlock(testHash)
50 t.Fatalf("Error while getting block %s", err)
52 if bytes.Compare(buf, testBlock) != 0 {
53 t.Errorf("Put succeeded but Get returned %+v, expected %+v", buf, testBlock)
57 // Put a bad block using PutRaw and get it.
58 func testPutRawBadDataGetBlock(t TB, factory TestableVolumeManagerFactory,
59 testHash string, testBlock []byte, badData []byte) {
60 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
62 // Put bad data for testHash in both volumes
63 testableVolumes[0].PutRaw(testHash, badData)
64 testableVolumes[1].PutRaw(testHash, badData)
67 _, err := GetBlock(testHash)
69 t.Fatalf("Expected error while getting corrupt block %v", testHash)
73 // Invoke PutBlock twice to ensure CompareAndTouch path is tested.
74 func testPutBlock(t TB, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
75 setupHandlersWithGenericVolumeTest(t, factory)
78 if _, err := PutBlock(testBlock, testHash); err != nil {
79 t.Fatalf("Error during PutBlock: %s", err)
82 // Check that PutBlock succeeds again even after CompareAndTouch
83 if _, err := PutBlock(testBlock, testHash); err != nil {
84 t.Fatalf("Error during PutBlock: %s", err)
87 // Check that PutBlock stored the data as expected
88 buf, err := GetBlock(testHash)
90 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
91 } else if bytes.Compare(buf, testBlock) != 0 {
92 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)
96 // Put a bad block using PutRaw, overwrite it using PutBlock and get it.
97 func testPutBlockCorrupt(t TB, factory TestableVolumeManagerFactory,
98 testHash string, testBlock []byte, badData []byte) {
99 testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
101 // Put bad data for testHash in both volumes
102 testableVolumes[0].PutRaw(testHash, badData)
103 testableVolumes[1].PutRaw(testHash, badData)
105 // Check that PutBlock with good data succeeds
106 if _, err := PutBlock(testBlock, testHash); err != nil {
107 t.Fatalf("Error during PutBlock for %q: %s", testHash, err)
110 // Put succeeded and overwrote the badData in one volume,
111 // and Get should return the testBlock now, ignoring the bad data.
112 buf, err := GetBlock(testHash)
114 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
115 } else if bytes.Compare(buf, testBlock) != 0 {
116 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)