7329: since moved functional testing into generic testing, removing now redundant...
[arvados.git] / services / keepstore / volume_keepstore_generic_test.go
1 package main
2
3 import (
4         "bytes"
5         "testing"
6 )
7
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
12
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"))
25 }
26
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()
32         defer KeepVM.Close()
33
34         // Put testBlock in one volume
35         testableVolumes[1].PutRaw(testHash, testBlock)
36
37         // Get should pass
38         buf, err := GetBlock(testHash)
39         if err != nil {
40                 t.Fatalf("Error while getting block %s", err)
41         }
42         if bytes.Compare(buf, testBlock) != 0 {
43                 t.Errorf("Put succeeded but Get returned %+v, expected %+v", buf, testBlock)
44         }
45 }
46
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()
53         defer KeepVM.Close()
54
55         // Put bad data for testHash in both volumes
56         testableVolumes[0].PutRaw(testHash, badData)
57         testableVolumes[1].PutRaw(testHash, badData)
58
59         // Get should fail
60         _, err := GetBlock(testHash)
61         if err == nil {
62                 t.Fatalf("Expected error while getting corrupt block %v", testHash)
63         }
64 }
65
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()
71         defer KeepVM.Close()
72
73         // PutBlock
74         if err := PutBlock(testBlock, testHash); err != nil {
75                 t.Fatalf("Error during PutBlock: %s", err)
76         }
77
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)
81         }
82
83         // Check that PutBlock stored the data as expected
84         buf, err := GetBlock(testHash)
85         if err != nil {
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)
89         }
90 }
91
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()
98         defer KeepVM.Close()
99
100         // Put bad data for testHash in both volumes
101         testableVolumes[0].PutRaw(testHash, badData)
102         testableVolumes[1].PutRaw(testHash, badData)
103
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)
107         }
108
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)
112         if err != nil {
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)
116         }
117 }