8 // A TestableVolumeManagerFactory creates a volume manager with one or more TestableVolumes.
9 // The factory function, and the TestableVolumes it returns, can use "t" to write
10 // logs, fail the current test, etc.
11 type TestableVolumeManagerFactory func(t *testing.T) []TestableVolume
13 // DoGenericVolumeTests runs a set of tests that every TestableVolume
14 // is expected to pass. It calls factory to create a new TestableVolume
15 // for each test case, to avoid leaking state between tests.
16 func DoGenericVolumeFunctionalTests(t *testing.T, 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 // Put a block using PutRaw in just one volume and Get it using GetBlock
28 func testGetBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
29 testableVolumes := factory(t)
30 defer testableVolumes[0].Teardown()
31 defer testableVolumes[1].Teardown()
34 // Put testBlock in one volume
35 testableVolumes[1].PutRaw(testHash, testBlock)
38 buf, err := GetBlock(testHash)
40 t.Fatalf("Error while getting block %s", err)
42 if bytes.Compare(buf, testBlock) != 0 {
43 t.Errorf("Put succeeded but Get returned %+v, expected %+v", buf, testBlock)
47 // Put a bad block using PutRaw and get it.
48 func testPutRawBadDataGetBlock(t *testing.T, factory TestableVolumeManagerFactory,
49 testHash string, testBlock []byte, badData []byte) {
50 testableVolumes := factory(t)
51 defer testableVolumes[0].Teardown()
52 defer testableVolumes[1].Teardown()
55 // Put bad data for testHash in both volumes
56 testableVolumes[0].PutRaw(testHash, badData)
57 testableVolumes[1].PutRaw(testHash, badData)
60 _, err := GetBlock(testHash)
62 t.Fatalf("Expected error while getting corrupt block %v", testHash)
66 // Invoke PutBlock twice to ensure CompareAndTouch path is tested.
67 func testPutBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
68 testableVolumes := factory(t)
69 defer testableVolumes[0].Teardown()
70 defer testableVolumes[1].Teardown()
74 if err := PutBlock(testBlock, testHash); err != nil {
75 t.Fatalf("Error during PutBlock: %s", err)
78 // Check that PutBlock succeeds again even after CompareAndTouch
79 if err := PutBlock(testBlock, testHash); err != nil {
80 t.Fatalf("Error during PutBlock: %s", err)
83 // Check that PutBlock stored the data as expected
84 buf, err := GetBlock(testHash)
86 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
87 } else if bytes.Compare(buf, testBlock) != 0 {
88 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)
92 // Put a bad block using PutRaw, overwrite it using PutBlock and get it.
93 func testPutBlockCorrupt(t *testing.T, factory TestableVolumeManagerFactory,
94 testHash string, testBlock []byte, badData []byte) {
95 testableVolumes := factory(t)
96 defer testableVolumes[0].Teardown()
97 defer testableVolumes[1].Teardown()
100 // Put bad data for testHash in both volumes
101 testableVolumes[0].PutRaw(testHash, badData)
102 testableVolumes[1].PutRaw(testHash, badData)
104 // Check that PutBlock with good data succeeds
105 if err := PutBlock(testBlock, testHash); err != nil {
106 t.Fatalf("Error during PutBlock for %q: %s", testHash, err)
109 // Put succeeded and overwrote the badData in one volume,
110 // and Get should return the testBlock now, ignoring the bad data.
111 buf, err := GetBlock(testHash)
113 t.Fatalf("Error during GetBlock for %q: %s", testHash, err)
114 } else if bytes.Compare(buf, testBlock) != 0 {
115 t.Errorf("Get response incorrect. Expected %q; found %q", testBlock, buf)