Merge branch 'master' into 2221-complete-docker
[arvados.git] / services / keep / keep_test.go
1 package main
2
3 import (
4         "fmt"
5         "io/ioutil"
6         "os"
7         "path"
8         "testing"
9 )
10
11 var TEST_BLOCK = []byte("The quick brown fox jumps over the lazy dog.")
12 var TEST_HASH = "e4d909c290d0fb1ca068ffaddf22cbd0"
13 var BAD_BLOCK = []byte("The magic words are squeamish ossifrage.")
14
15 // Test simple block reads.
16 func TestGetBlockOK(t *testing.T) {
17         defer teardown()
18
19         // Create two test Keep volumes and store a block in each of them.
20         setup(t, 2)
21         for _, vol := range KeepVolumes {
22                 store(t, vol, TEST_HASH, TEST_BLOCK)
23         }
24
25         // Check that GetBlock returns success.
26         result, err := GetBlock(TEST_HASH)
27         if err != nil {
28                 t.Errorf("GetBlock error: %s", err)
29         }
30         if fmt.Sprint(result) != fmt.Sprint(TEST_BLOCK) {
31                 t.Errorf("expected %s, got %s", TEST_BLOCK, result)
32         }
33 }
34
35 // Test block reads when one Keep volume is missing.
36 func TestGetBlockOneKeepOK(t *testing.T) {
37         defer teardown()
38
39         // Two test Keep volumes, only the second has a block.
40         setup(t, 2)
41         store(t, KeepVolumes[1], TEST_HASH, TEST_BLOCK)
42
43         // Check that GetBlock returns success.
44         result, err := GetBlock(TEST_HASH)
45         if err != nil {
46                 t.Errorf("GetBlock error: %s", err)
47         }
48         if fmt.Sprint(result) != fmt.Sprint(TEST_BLOCK) {
49                 t.Errorf("expected %s, got %s", TEST_BLOCK, result)
50         }
51 }
52
53 // Test block read failure.
54 func TestGetBlockFail(t *testing.T) {
55         defer teardown()
56
57         // Create two empty test Keep volumes.
58         setup(t, 2)
59
60         // Check that GetBlock returns failure.
61         result, err := GetBlock(TEST_HASH)
62         if err == nil {
63                 t.Errorf("GetBlock incorrectly returned success: ", result)
64         }
65 }
66
67 // Test reading a corrupt block.
68 func TestGetBlockCorrupt(t *testing.T) {
69         defer teardown()
70
71         // Create two test Keep volumes and store a block in each of them,
72         // but the hash of the block does not match the filename.
73         setup(t, 2)
74         for _, vol := range KeepVolumes {
75                 store(t, vol, TEST_HASH, BAD_BLOCK)
76         }
77
78         // Check that GetBlock returns failure.
79         result, err := GetBlock(TEST_HASH)
80         if err == nil {
81                 t.Errorf("GetBlock incorrectly returned success: %s", result)
82         }
83 }
84
85 // setup
86 //     Create KeepVolumes for testing.
87 //
88 func setup(t *testing.T, num_volumes int) {
89         KeepVolumes = make([]string, num_volumes)
90         for i := range KeepVolumes {
91                 if dir, err := ioutil.TempDir(os.TempDir(), "keeptest"); err == nil {
92                         KeepVolumes[i] = dir + "/keep"
93                 } else {
94                         t.Fatal(err)
95                 }
96         }
97 }
98
99 // teardown
100 //     Cleanup to perform after each test.
101 //
102 func teardown() {
103         for _, vol := range KeepVolumes {
104                 os.RemoveAll(path.Dir(vol))
105         }
106 }
107
108 // store
109 //
110 func store(t *testing.T, keepdir string, filename string, block []byte) error {
111         blockdir := fmt.Sprintf("%s/%s", keepdir, filename[:3])
112         if err := os.MkdirAll(blockdir, 0755); err != nil {
113                 t.Fatal(err)
114         }
115
116         blockpath := fmt.Sprintf("%s/%s", blockdir, filename)
117         if f, err := os.Create(blockpath); err == nil {
118                 f.Write(block)
119                 f.Close()
120         } else {
121                 t.Fatal(err)
122         }
123
124         return nil
125 }