veyron/services/mgmt/lib/fs/*: support empty simplestores
This change extends simplstore to support persisting an empty simplestore.
Change-Id: I2f36ac30e316cd868042854b7dd78f89680e5505
diff --git a/services/mgmt/lib/fs/simplestore.go b/services/mgmt/lib/fs/simplestore.go
index 9314cc0..4fdd45b 100644
--- a/services/mgmt/lib/fs/simplestore.go
+++ b/services/mgmt/lib/fs/simplestore.go
@@ -67,13 +67,22 @@
// The file doesn't exist. Attempt to create it instead.
file, cerr := os.Create(configuredPersistentFile)
if cerr != nil {
- return nil, fmt.Errorf("File (%q) could neither be opened (%v) or created (%v)", configuredPersistentFile, err, cerr)
+ return nil, fmt.Errorf("File (%q) could neither be opened (%v) nor created (%v)", configuredPersistentFile, err, cerr)
}
defer file.Close()
} else {
decoder := gob.NewDecoder(file)
- if err := decoder.Decode(&data); err != nil {
- return nil, fmt.Errorf("Decode() failed: %v", err)
+ if err := decoder.Decode(&data); err != nil {
+ // Two situations. One is not an error.
+ fi, err := os.Stat(configuredPersistentFile)
+ if err != nil {
+ // Someone probably deleted the file out from underneath us. Give up.
+ return nil, fmt.Errorf("Decode() failed, file went missing: %v", err)
+ }
+ if fi.Size() != 0 {
+ return nil, fmt.Errorf("Decode() failed, backing file truncated: %v", err)
+ }
+ // An empty backing file deserializes to an empty memstore.
}
}
return &Memstore{
diff --git a/services/mgmt/lib/fs/simplestore_test.go b/services/mgmt/lib/fs/simplestore_test.go
index 46f37c6..fc893d8 100644
--- a/services/mgmt/lib/fs/simplestore_test.go
+++ b/services/mgmt/lib/fs/simplestore_test.go
@@ -435,3 +435,22 @@
t.Fatalf("Remove() failed: got %v, expected %v", err, verror.Internalf("Remove() without a transactional binding"))
}
}
+
+func TestOpenEmptyMemstore(t *testing.T) {
+ path := filepath.Join(os.TempDir(), "namedms")
+ defer os.Remove(path)
+
+ // Create a brand new memstore persisted to namedms. This will
+ // have the side-effect of creating an empty backing file.
+ _, err := NewMemstore(path)
+ if err != nil {
+ t.Fatalf("NewMemstore() failed: %v", err)
+ }
+
+ // Create another memstore that will attempt to deserialize the empty
+ // backing file.
+ _, err = NewMemstore(path)
+ if err != nil {
+ t.Fatalf("NewMemstore() failed: %v", err)
+ }
+}