12 func TempUnixVolume(t *testing.T, queue chan *IORequest) UnixVolume {
13 d, err := ioutil.TempDir("", "volume_test")
17 return MakeUnixVolume(d, queue)
20 func _teardown(v UnixVolume) {
27 // store writes a Keep block directly into a UnixVolume, for testing
28 // UnixVolume methods.
30 func _store(t *testing.T, vol UnixVolume, filename string, block []byte) {
31 blockdir := fmt.Sprintf("%s/%s", vol.root, filename[:3])
32 if err := os.MkdirAll(blockdir, 0755); err != nil {
36 blockpath := fmt.Sprintf("%s/%s", blockdir, filename)
37 if f, err := os.Create(blockpath); err == nil {
45 func TestGet(t *testing.T) {
46 v := TempUnixVolume(t, nil)
48 _store(t, v, TEST_HASH, TEST_BLOCK)
50 buf, err := v.Get(TEST_HASH)
54 if bytes.Compare(buf, TEST_BLOCK) != 0 {
55 t.Errorf("expected %s, got %s", string(TEST_BLOCK), string(buf))
59 func TestGetNotFound(t *testing.T) {
60 v := TempUnixVolume(t, nil)
62 _store(t, v, TEST_HASH, TEST_BLOCK)
64 buf, err := v.Get(TEST_HASH_2)
66 case os.IsNotExist(err):
69 t.Errorf("Read should have failed, returned %s", string(buf))
71 t.Errorf("Read expected ErrNotExist, got: %s", err)
75 func TestPut(t *testing.T) {
76 v := TempUnixVolume(t, nil)
79 err := v.Put(TEST_HASH, TEST_BLOCK)
83 p := fmt.Sprintf("%s/%s/%s", v.root, TEST_HASH[:3], TEST_HASH)
84 if buf, err := ioutil.ReadFile(p); err != nil {
86 } else if bytes.Compare(buf, TEST_BLOCK) != 0 {
87 t.Errorf("Write should have stored %s, did store %s",
88 string(TEST_BLOCK), string(buf))
92 func TestPutBadVolume(t *testing.T) {
93 v := TempUnixVolume(t, nil)
97 err := v.Put(TEST_HASH, TEST_BLOCK)
99 t.Error("Write should have failed")
103 // Serialization tests.
105 // TODO(twp): a proper test of I/O serialization requires that
106 // a second request start while the first one is still executing.
107 // Doing this correctly requires some tricky synchronization.
108 // For now we'll just launch a bunch of requests in goroutines
109 // and demonstrate that they return accurate results.
111 func TestGetSerialized(t *testing.T) {
112 v := TempUnixVolume(t, make(chan *IORequest))
115 _store(t, v, TEST_HASH, TEST_BLOCK)
116 _store(t, v, TEST_HASH_2, TEST_BLOCK_2)
117 _store(t, v, TEST_HASH_3, TEST_BLOCK_3)
119 sem := make(chan int)
120 go func(sem chan int) {
121 buf, err := v.Get(TEST_HASH)
123 t.Errorf("err1: %v", err)
125 if bytes.Compare(buf, TEST_BLOCK) != 0 {
126 t.Errorf("buf should be %s, is %s", string(TEST_BLOCK), string(buf))
131 go func(sem chan int) {
132 buf, err := v.Get(TEST_HASH_2)
134 t.Errorf("err2: %v", err)
136 if bytes.Compare(buf, TEST_BLOCK_2) != 0 {
137 t.Errorf("buf should be %s, is %s", string(TEST_BLOCK_2), string(buf))
142 go func(sem chan int) {
143 buf, err := v.Get(TEST_HASH_3)
145 t.Errorf("err3: %v", err)
147 if bytes.Compare(buf, TEST_BLOCK_3) != 0 {
148 t.Errorf("buf should be %s, is %s", string(TEST_BLOCK_3), string(buf))
153 // Wait for all goroutines to finish
154 for done := 0; done < 2; {
159 func TestPutSerialized(t *testing.T) {
160 v := TempUnixVolume(t, make(chan *IORequest))
163 sem := make(chan int)
164 go func(sem chan int) {
165 err := v.Put(TEST_HASH, TEST_BLOCK)
167 t.Errorf("err1: %v", err)
172 go func(sem chan int) {
173 err := v.Put(TEST_HASH_2, TEST_BLOCK_2)
175 t.Errorf("err2: %v", err)
180 go func(sem chan int) {
181 err := v.Put(TEST_HASH_3, TEST_BLOCK_3)
183 t.Errorf("err3: %v", err)
188 // Wait for all goroutines to finish
189 for done := 0; done < 2; {
193 // Double check that we actually wrote the blocks we expected to write.
194 buf, err := v.Get(TEST_HASH)
196 t.Errorf("Get #1: %v", err)
198 if bytes.Compare(buf, TEST_BLOCK) != 0 {
199 t.Errorf("Get #1: expected %s, got %s", string(TEST_BLOCK), string(buf))
202 buf, err = v.Get(TEST_HASH_2)
204 t.Errorf("Get #2: %v", err)
206 if bytes.Compare(buf, TEST_BLOCK_2) != 0 {
207 t.Errorf("Get #2: expected %s, got %s", string(TEST_BLOCK_2), string(buf))
210 buf, err = v.Get(TEST_HASH_3)
212 t.Errorf("Get #3: %v", err)
214 if bytes.Compare(buf, TEST_BLOCK_3) != 0 {
215 t.Errorf("Get #3: expected %s, got %s", string(TEST_BLOCK_3), string(buf))
219 func TestIsFull(t *testing.T) {
220 v := TempUnixVolume(t, nil)
223 full_path := v.root + "/full"
224 now := fmt.Sprintf("%d", time.Now().Unix())
225 os.Symlink(now, full_path)
227 t.Errorf("%s: claims not to be full", v)
231 // Test with an expired /full link.
232 expired := fmt.Sprintf("%d", time.Now().Unix()-3605)
233 os.Symlink(expired, full_path)
235 t.Errorf("%s: should no longer be full", v)