blob: 995712137648eaf4a3cd7c384af0dc857f57e9f9 [file] [log] [blame]
Robert Kroegerf903fe22014-10-20 14:37:28 -07001package fs_test
Robert Kroegerd9c34882014-08-22 11:16:38 -07002
3import (
4 "fmt"
Robin Thellend4081a302014-12-08 17:38:56 -08005 "io/ioutil"
Robert Kroegerd9c34882014-08-22 11:16:38 -07006 "os"
Robert Kroegerd9c34882014-08-22 11:16:38 -07007 "reflect"
8 "testing"
9
Robert Kroegerf903fe22014-10-20 14:37:28 -070010 "veyron.io/veyron/veyron/services/mgmt/lib/fs"
Jiri Simsa519c5072014-09-17 21:37:57 -070011 _ "veyron.io/veyron/veyron/services/mgmt/profile"
12 "veyron.io/veyron/veyron2/naming"
13 "veyron.io/veyron/veyron2/services/mgmt/application"
14 "veyron.io/veyron/veyron2/verror"
Robert Kroegerd9c34882014-08-22 11:16:38 -070015)
16
Robin Thellend4081a302014-12-08 17:38:56 -080017func tempFile(t *testing.T) string {
18 tmpfile, err := ioutil.TempFile("", "simplestore-test-")
19 if err != nil {
20 t.Fatalf("ioutil.TempFile() failed: %v", err)
21 }
22 defer tmpfile.Close()
23 return tmpfile.Name()
24}
25
Robert Kroegerd9c34882014-08-22 11:16:38 -070026func TestNewMemstore(t *testing.T) {
Robert Kroegerf903fe22014-10-20 14:37:28 -070027 memstore, err := fs.NewMemstore("")
Robert Kroegerd9c34882014-08-22 11:16:38 -070028
29 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -070030 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -070031 }
32
Robin Thellend4081a302014-12-08 17:38:56 -080033 if _, err = os.Stat(memstore.PersistedFile()); err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -070034 t.Fatalf("Stat(%v) failed: %v", memstore.PersistedFile(), err)
Robert Kroegerd9c34882014-08-22 11:16:38 -070035 }
Robin Thellend4081a302014-12-08 17:38:56 -080036 os.Remove(memstore.PersistedFile())
Robert Kroegerd9c34882014-08-22 11:16:38 -070037}
38
39func TestNewNamedMemstore(t *testing.T) {
Robin Thellend4081a302014-12-08 17:38:56 -080040 path := tempFile(t)
41 defer os.Remove(path)
Robert Kroegerf903fe22014-10-20 14:37:28 -070042 memstore, err := fs.NewMemstore(path)
Robert Kroegerd9c34882014-08-22 11:16:38 -070043 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -070044 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -070045 }
Robert Kroegerd9c34882014-08-22 11:16:38 -070046
Robin Thellend4081a302014-12-08 17:38:56 -080047 if _, err = os.Stat(memstore.PersistedFile()); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -070048 t.Fatalf("Stat(%v) failed: %v", path, err)
49 }
50}
51
52// Verify that all of the listed paths Exists().
53// Caller is responsible for setting up any transaction state necessary.
Robert Kroegerf903fe22014-10-20 14:37:28 -070054func allPathsExist(ts *fs.Memstore, paths []string) error {
Robert Kroegerd9c34882014-08-22 11:16:38 -070055 for _, p := range paths {
56 exists, err := ts.BindObject(p).Exists(nil)
57 if err != nil {
58 return fmt.Errorf("Exists(%s) expected to succeed but failed: %v", p, err)
59 }
60 if !exists {
61 return fmt.Errorf("Exists(%s) expected to be true but is false", p)
62 }
63 }
64 return nil
65}
66
67// Verify that all of the listed paths !Exists().
68// Caller is responsible for setting up any transaction state necessary.
Robert Kroegerf903fe22014-10-20 14:37:28 -070069func allPathsDontExist(ts *fs.Memstore, paths []string) error {
Robert Kroegerd9c34882014-08-22 11:16:38 -070070 for _, p := range paths {
71 exists, err := ts.BindObject(p).Exists(nil)
72 if err != nil {
73 return fmt.Errorf("Exists(%s) expected to succeed but failed: %v", p, err)
74 }
75 if exists {
76 return fmt.Errorf("Exists(%s) expected to be false but is true", p)
77 }
78 }
79 return nil
80}
81
82type PathValue struct {
83 Path string
84 Expected interface{}
85}
86
87// getEquals tests that every provided path is equal to the specified value.
Robert Kroegerf903fe22014-10-20 14:37:28 -070088func allPathsEqual(ts *fs.Memstore, pvs []PathValue) error {
Robert Kroegerd9c34882014-08-22 11:16:38 -070089 for _, p := range pvs {
90 v, err := ts.BindObject(p.Path).Get(nil)
91 if err != nil {
92 return fmt.Errorf("Get(%s) expected to succeed but failed", p, err)
93 }
94 if !reflect.DeepEqual(p.Expected, v.Value) {
95 return fmt.Errorf("Unexpected non-equality for %s: got %v, expected %v", p.Path, v.Value, p.Expected)
96 }
97 }
98 return nil
99}
100
Robert Kroegerd9c34882014-08-22 11:16:38 -0700101func TestSerializeDeserialize(t *testing.T) {
Robin Thellend4081a302014-12-08 17:38:56 -0800102 path := tempFile(t)
103 defer os.Remove(path)
Robert Kroegerf903fe22014-10-20 14:37:28 -0700104 memstoreOriginal, err := fs.NewMemstore(path)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700105 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700106 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700107 }
Robert Kroegerd9c34882014-08-22 11:16:38 -0700108
109 // Create example data.
110 envelope := application.Envelope{
111 Args: []string{"--help"},
112 Env: []string{"DEBUG=1"},
113 Binary: "/veyron/name/of/binary",
114 }
115 secondEnvelope := application.Envelope{
116 Args: []string{"--save"},
117 Env: []string{"VEYRON=42"},
118 Binary: "/veyron/name/of/binary/is/memstored",
119 }
120
121 // TRANSACTION BEGIN
Robert Kroegerf903fe22014-10-20 14:37:28 -0700122 // Insert a value into the fs.Memstore at /test/a
Robert Kroegerd9c34882014-08-22 11:16:38 -0700123 memstoreOriginal.Lock()
124 tname, err := memstoreOriginal.BindTransactionRoot("ignored").CreateTransaction(nil)
125 if err != nil {
126 t.Fatalf("CreateTransaction() failed: %v", err)
127 }
Robert Kroegerf903fe22014-10-20 14:37:28 -0700128 if _, err := memstoreOriginal.BindObject(fs.TP("/test/a")).Put(nil, envelope); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700129 t.Fatalf("Put() failed: %v", err)
130 }
131
Robert Kroegerf903fe22014-10-20 14:37:28 -0700132 if err := allPathsExist(memstoreOriginal, []string{fs.TP("/test/a"), fs.TP("/test")}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700133 t.Fatalf("%v", err)
134 }
Robert Kroegerf903fe22014-10-20 14:37:28 -0700135 if err := allPathsEqual(memstoreOriginal, []PathValue{{fs.TP("/test/a"), envelope}}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700136 t.Fatalf("%v", err)
137 }
138
139 if err := memstoreOriginal.BindTransaction(tname).Commit(nil); err != nil {
140 t.Fatalf("Commit() failed: %v", err)
141 }
142 memstoreOriginal.Unlock()
143 // TRANSACTION END
144
145 // Validate persisted state.
146 if err := allPathsExist(memstoreOriginal, []string{"/test/a", "/test"}); err != nil {
147 t.Fatalf("%v", err)
148 }
149 if err := allPathsEqual(memstoreOriginal, []PathValue{{"/test/a", envelope}}); err != nil {
150 t.Fatalf("%v", err)
151 }
152
153 // TRANSACTION BEGIN Write a value to /test/b as well.
154 memstoreOriginal.Lock()
155 tname, err = memstoreOriginal.BindTransactionRoot("also ignored").CreateTransaction(nil)
Robert Kroegerf903fe22014-10-20 14:37:28 -0700156 bindingTnameTestB := memstoreOriginal.BindObject(fs.TP("/test/b"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700157 if _, err := bindingTnameTestB.Put(nil, envelope); err != nil {
158 t.Fatalf("Put() failed: %v", err)
159 }
160
161 // Validate persisted state during transaction
162 if err := allPathsExist(memstoreOriginal, []string{"/test/a", "/test"}); err != nil {
163 t.Fatalf("%v", err)
164 }
165 if err := allPathsEqual(memstoreOriginal, []PathValue{{"/test/a", envelope}}); err != nil {
166 t.Fatalf("%v", err)
167 }
168 // Validate pending state during transaction
Robert Kroegerf903fe22014-10-20 14:37:28 -0700169 if err := allPathsExist(memstoreOriginal, []string{fs.TP("/test/a"), fs.TP("/test"), fs.TP("/test/b")}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700170 t.Fatalf("%v", err)
171 }
172 if err := allPathsEqual(memstoreOriginal, []PathValue{
Robert Kroegerf903fe22014-10-20 14:37:28 -0700173 {fs.TP("/test/a"), envelope},
174 {fs.TP("/test/b"), envelope}}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700175 t.Fatalf("%v", err)
176 }
177
178 // Commit the <tname>/test/b to /test/b
179 if err := memstoreOriginal.Commit(nil); err != nil {
180 t.Fatalf("Commit() failed: %v", err)
181 }
182 memstoreOriginal.Unlock()
183 // TODO(rjkroege): Consider ensuring that Get() on <tname>/test/b should now fail.
184 // TRANSACTION END
185
186 // Validate persisted state after transaction
187 if err := allPathsExist(memstoreOriginal, []string{"/test/a", "/test", "/test/b"}); err != nil {
188 t.Fatalf("%v", err)
189 }
190 if err := allPathsEqual(memstoreOriginal, []PathValue{
191 {"/test/a", envelope},
192 {"/test/b", envelope}}); err != nil {
193 t.Fatalf("%v", err)
194 }
195
196 // TRANSACTION BEGIN (to be abandonned)
197 memstoreOriginal.Lock()
198 tname, err = memstoreOriginal.BindTransactionRoot("").CreateTransaction(nil)
199
200 // Exists is true before doing anything.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700201 if err := allPathsExist(memstoreOriginal, []string{fs.TP("/test")}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700202 t.Fatalf("%v", err)
203 }
204
Robert Kroegerf903fe22014-10-20 14:37:28 -0700205 if _, err := memstoreOriginal.BindObject(fs.TP("/test/b")).Put(nil, secondEnvelope); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700206 t.Fatalf("Put() failed: %v", err)
207 }
208
209 // Validate persisted state during transaction
210 if err := allPathsExist(memstoreOriginal, []string{
211 "/test/a",
212 "/test/b",
213 "/test",
Robert Kroegerf903fe22014-10-20 14:37:28 -0700214 fs.TP("/test"),
215 fs.TP("/test/a"),
216 fs.TP("/test/b"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700217 }); err != nil {
218 t.Fatalf("%v", err)
219 }
220 if err := allPathsEqual(memstoreOriginal, []PathValue{
221 {"/test/a", envelope},
222 {"/test/b", envelope},
Robert Kroegerf903fe22014-10-20 14:37:28 -0700223 {fs.TP("/test/b"), secondEnvelope},
224 {fs.TP("/test/a"), envelope},
Robert Kroegerd9c34882014-08-22 11:16:38 -0700225 }); err != nil {
226 t.Fatalf("%v", err)
227 }
228
229 // Pending Remove() of /test
Robert Kroegerf903fe22014-10-20 14:37:28 -0700230 if err := memstoreOriginal.BindObject(fs.TP("/test")).Remove(nil); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700231 t.Fatalf("Remove() failed: %v", err)
232 }
233
234 // Verify that all paths are successfully removed from the in-progress transaction.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700235 if err := allPathsDontExist(memstoreOriginal, []string{fs.TP("/test/a"), fs.TP("/test"), fs.TP("/test/b")}); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700236 t.Fatalf("%v", err)
237 }
238 // But all paths remain in the persisted version.
239 if err := allPathsExist(memstoreOriginal, []string{"/test/a", "/test", "/test/b"}); err != nil {
240 t.Fatalf("%v", err)
241 }
242 if err := allPathsEqual(memstoreOriginal, []PathValue{
243 {"/test/a", envelope},
244 {"/test/b", envelope},
245 }); err != nil {
246 t.Fatalf("%v", err)
247 }
248
249 // At which point, Get() on the transaction won't find anything.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700250 if _, err := memstoreOriginal.BindObject(fs.TP("/test/a")).Get(nil); !verror.Is(err, verror.NoExist) {
Tilak Sharma492e8e92014-09-18 10:58:14 -0700251 t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/a"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700252 }
253
254 // Attempting to Remove() it over again will fail.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700255 if err := memstoreOriginal.BindObject(fs.TP("/test/a")).Remove(nil); !verror.Is(err, verror.NoExist) {
Tilak Sharma492e8e92014-09-18 10:58:14 -0700256 t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/a"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700257 }
258
259 // Attempting to Remove() a non-existing path will fail.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700260 if err := memstoreOriginal.BindObject(fs.TP("/foo")).Remove(nil); !verror.Is(err, verror.NoExist) {
Tilak Sharma492e8e92014-09-18 10:58:14 -0700261 t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/foo"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700262 }
263
264 // Exists() a non-existing path will fail.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700265 if present, _ := memstoreOriginal.BindObject(fs.TP("/foo")).Exists(nil); present {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700266 t.Fatalf("Exists() should have failed for non-existing path %s", tname+"/foo")
267 }
268
269 // Abort the transaction without committing it.
270 memstoreOriginal.Abort(nil)
271 memstoreOriginal.Unlock()
272 // TRANSACTION END (ABORTED)
273
274 // Validate that persisted state after abandonned transaction has not changed.
275 if err := allPathsExist(memstoreOriginal, []string{"/test/a", "/test", "/test/b"}); err != nil {
276 t.Fatalf("%v", err)
277 }
278 if err := allPathsEqual(memstoreOriginal, []PathValue{
279 {"/test/a", envelope},
280 {"/test/b", envelope}}); err != nil {
281 t.Fatalf("%v", err)
282 }
283
284 // Validate that Get will fail on a non-existent path.
Tilak Sharma492e8e92014-09-18 10:58:14 -0700285 if _, err := memstoreOriginal.BindObject("/test/c").Get(nil); !verror.Is(err, verror.NoExist) {
286 t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/c"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700287 }
288
289 // Verify that the previous Commit() operations have persisted to
290 // disk by creating a new Memstore from the contents on disk.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700291 memstoreCopy, err := fs.NewMemstore(path)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700292 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700293 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700294 }
295 // Verify that memstoreCopy is an exact copy of memstoreOriginal.
296 if err := allPathsExist(memstoreCopy, []string{"/test/a", "/test", "/test/b"}); err != nil {
297 t.Fatalf("%v", err)
298 }
299 if err := allPathsEqual(memstoreCopy, []PathValue{
300 {"/test/a", envelope},
301 {"/test/b", envelope}}); err != nil {
302 t.Fatalf("%v", err)
303 }
304
305 // TRANSACTION BEGIN
306 memstoreCopy.Lock()
307 tname, err = memstoreCopy.BindTransactionRoot("also ignored").CreateTransaction(nil)
308
309 // Add a pending object c to test that pending objects are deleted.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700310 if _, err := memstoreCopy.BindObject(fs.TP("/test/c")).Put(nil, secondEnvelope); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700311 t.Fatalf("Put() failed: %v", err)
312 }
313 if err := allPathsExist(memstoreCopy, []string{
Robert Kroegerf903fe22014-10-20 14:37:28 -0700314 fs.TP("/test/a"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700315 "/test/a",
Robert Kroegerf903fe22014-10-20 14:37:28 -0700316 fs.TP("/test"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700317 "/test",
Robert Kroegerf903fe22014-10-20 14:37:28 -0700318 fs.TP("/test/b"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700319 "/test/b",
Robert Kroegerf903fe22014-10-20 14:37:28 -0700320 fs.TP("/test/c"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700321 }); err != nil {
322 t.Fatalf("%v", err)
323 }
324 if err := allPathsEqual(memstoreCopy, []PathValue{
Robert Kroegerf903fe22014-10-20 14:37:28 -0700325 {fs.TP("/test/a"), envelope},
326 {fs.TP("/test/b"), envelope},
327 {fs.TP("/test/c"), secondEnvelope},
Robert Kroegerd9c34882014-08-22 11:16:38 -0700328 {"/test/a", envelope},
329 {"/test/b", envelope},
330 }); err != nil {
331 t.Fatalf("%v", err)
332 }
333
334 // Remove /test/a /test/b /test/c /test
Robert Kroegerf903fe22014-10-20 14:37:28 -0700335 if err := memstoreCopy.BindObject(fs.TP("/test")).Remove(nil); err != nil {
Robert Kroegerd9c34882014-08-22 11:16:38 -0700336 t.Fatalf("Remove() failed: %v", err)
337 }
338 // Verify that all paths are successfully removed from the in-progress transaction.
339 if err := allPathsDontExist(memstoreCopy, []string{
Robert Kroegerf903fe22014-10-20 14:37:28 -0700340 fs.TP("/test/a"),
341 fs.TP("/test"),
342 fs.TP("/test/b"),
343 fs.TP("/test/c"),
Robert Kroegerd9c34882014-08-22 11:16:38 -0700344 }); err != nil {
345 t.Fatalf("%v", err)
346 }
347 if err := allPathsExist(memstoreCopy, []string{
348 "/test/a",
349 "/test",
350 "/test/b",
351 }); err != nil {
352 t.Fatalf("%v", err)
353 }
354 // Commit the change.
355 if err = memstoreCopy.Commit(nil); err != nil {
356 t.Fatalf("Commit() failed: %v", err)
357 }
358 memstoreCopy.Unlock()
359 // TRANSACTION END
360
361 // Create a new Memstore from file to see if Remove operates are
362 // persisted.
Robert Kroegerf903fe22014-10-20 14:37:28 -0700363 memstoreRemovedCopy, err := fs.NewMemstore(path)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700364 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700365 t.Fatalf("fs.NewMemstore() failed for removed copy: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700366 }
367 if err := allPathsDontExist(memstoreRemovedCopy, []string{
368 "/test/a",
369 "/test",
370 "/test/b",
371 "/test/c",
372 }); err != nil {
373 t.Fatalf("%v", err)
374 }
375}
376
377func TestOperationsNeedValidBinding(t *testing.T) {
Robin Thellend4081a302014-12-08 17:38:56 -0800378 path := tempFile(t)
379 defer os.Remove(path)
Robert Kroegerf903fe22014-10-20 14:37:28 -0700380 memstoreOriginal, err := fs.NewMemstore(path)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700381 if err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700382 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroegerd9c34882014-08-22 11:16:38 -0700383 }
Robert Kroegerd9c34882014-08-22 11:16:38 -0700384
385 // Create example data.
386 envelope := application.Envelope{
387 Args: []string{"--help"},
388 Env: []string{"DEBUG=1"},
389 Binary: "/veyron/name/of/binary",
390 }
391
392 // TRANSACTION BEGIN
393 // Attempt inserting a value at /test/a.
394 memstoreOriginal.Lock()
395 tname, err := memstoreOriginal.BindTransactionRoot("").CreateTransaction(nil)
396 if err != nil {
397 t.Fatalf("CreateTransaction() failed: %v", err)
398 }
399
400 if err := memstoreOriginal.BindTransaction(tname).Commit(nil); err != nil {
401 t.Fatalf("Commit() failed: %v", err)
402 }
403 memstoreOriginal.Unlock()
404 // TRANSACTION END
405
406 // Put outside ot a transaction should fail.
407 bindingTnameTestA := memstoreOriginal.BindObject(naming.Join("fooey", "/test/a"))
408 if _, err := bindingTnameTestA.Put(nil, envelope); !verror.Is(err, verror.BadProtocol) {
409 t.Fatalf("Put() failed: got %v, expected %v", err, verror.BadProtocolf("Put() without a transactional binding"))
410 }
411
412 // Remove outside of a transaction should fail
413 if err := bindingTnameTestA.Remove(nil); !verror.Is(err, verror.BadProtocol) {
414 t.Fatalf("Put() failed: got %v, expected %v", err, verror.BadProtocolf("Remove() without a transactional binding"))
415 }
416
417 // Commit outside of a transaction should fail
418 if err := memstoreOriginal.BindTransaction(tname).Commit(nil); !verror.Is(err, verror.BadProtocol) {
419 t.Fatalf("Commit() failed: got %v, expected %v", err, verror.BadProtocolf("illegal attempt to commit previously committed or abandonned transaction"))
420 }
421
422 // Attempt inserting a value at /test/b
423 memstoreOriginal.Lock()
424 tname, err = memstoreOriginal.BindTransactionRoot("").CreateTransaction(nil)
425 if err != nil {
426 t.Fatalf("CreateTransaction() failed: %v", err)
427 }
428
Robert Kroegerf903fe22014-10-20 14:37:28 -0700429 bindingTnameTestB := memstoreOriginal.BindObject(fs.TP("/test/b"))
Robert Kroegerd9c34882014-08-22 11:16:38 -0700430 if _, err := bindingTnameTestB.Put(nil, envelope); err != nil {
431 t.Fatalf("Put() failed: %v", err)
432 }
433 // Abandon transaction.
434 memstoreOriginal.Unlock()
435
436 // Remove should definitely fail on an abndonned transaction.
437 if err := bindingTnameTestB.Remove(nil); !verror.Is(err, verror.BadProtocol) {
438 t.Fatalf("Remove() failed: got %v, expected %v", err, verror.Internalf("Remove() without a transactional binding"))
439 }
440}
Robert Kroeger5fec5cf2014-10-08 17:19:50 -0700441
442func TestOpenEmptyMemstore(t *testing.T) {
Robin Thellend4081a302014-12-08 17:38:56 -0800443 path := tempFile(t)
Robert Kroeger5fec5cf2014-10-08 17:19:50 -0700444 defer os.Remove(path)
445
446 // Create a brand new memstore persisted to namedms. This will
447 // have the side-effect of creating an empty backing file.
Robin Thellend4081a302014-12-08 17:38:56 -0800448 if _, err := fs.NewMemstore(path); err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700449 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroeger5fec5cf2014-10-08 17:19:50 -0700450 }
451
452 // Create another memstore that will attempt to deserialize the empty
Asim Shankarc920db32014-10-16 19:18:21 -0700453 // backing file.
Robin Thellend4081a302014-12-08 17:38:56 -0800454 if _, err := fs.NewMemstore(path); err != nil {
Robert Kroegerf903fe22014-10-20 14:37:28 -0700455 t.Fatalf("fs.NewMemstore() failed: %v", err)
Robert Kroeger5fec5cf2014-10-08 17:19:50 -0700456 }
457}
Robin Thellend0155a372014-11-11 17:30:11 -0800458
459func TestChildren(t *testing.T) {
460 memstore, err := fs.NewMemstore("")
461 if err != nil {
462 t.Fatalf("fs.NewMemstore() failed: %v", err)
463 }
464 defer os.Remove(memstore.PersistedFile())
465
466 // Create example data.
467 envelope := application.Envelope{
468 Args: []string{"--help"},
469 Env: []string{"DEBUG=1"},
470 Binary: "/veyron/name/of/binary",
471 }
472
473 // TRANSACTION BEGIN
474 memstore.Lock()
475 tname, err := memstore.BindTransactionRoot("ignored").CreateTransaction(nil)
476 if err != nil {
477 t.Fatalf("CreateTransaction() failed: %v", err)
478 }
479 // Insert a few values
480 names := []string{"/test/a", "/test/b", "/test/a/x", "/test/a/y", "/test/b/fooooo/bar"}
481 for _, n := range names {
482 if _, err := memstore.BindObject(fs.TP(n)).Put(nil, envelope); err != nil {
483 t.Fatalf("Put() failed: %v", err)
484 }
485 }
486 if err := memstore.BindTransaction(tname).Commit(nil); err != nil {
487 t.Fatalf("Commit() failed: %v", err)
488 }
489 memstore.Unlock()
490 // TRANSACTION END
491
492 memstore.Lock()
493 testcases := []struct {
494 name string
495 children []string
496 }{
497 {"/", []string{"test"}},
498 {"/test", []string{"a", "b"}},
499 {"/test/a", []string{"x", "y"}},
500 {"/test/b", []string{"fooooo"}},
501 {"/test/b/fooooo", []string{"bar"}},
502 {"/test/a/x", []string{}},
503 {"/test/a/y", []string{}},
504 }
505 for _, tc := range testcases {
506 children, err := memstore.BindObject(tc.name).Children()
507 if err != nil {
508 t.Errorf("unexpected error for %q: %v", tc.name, err)
509 continue
510 }
511 if !reflect.DeepEqual(children, tc.children) {
512 t.Errorf("unexpected result for %q: got %q, expected %q", tc.name, children, tc.children)
513 }
514 }
515
516 for _, notthere := range []string{"/doesnt-exist", "/tes"} {
517 if _, err := memstore.BindObject(notthere).Children(); err == nil {
518 t.Errorf("unexpected success for: %q", notthere)
519 }
520 }
521 memstore.Unlock()
522}