// TestErrDatabaseNotOpen tests that checkMetadata returns an error when called // on a BoltDatabase that is closed. func TestErrDatabaseNotOpen(t *testing.T) { if testing.Short() { t.SkipNow() } testDir := build.TempDir(persistDir, "TestErrDatabaseNotOpen") err := os.MkdirAll(testDir, 0700) if err != nil { t.Fatal(err) } dbFilepath := filepath.Join(testDir, "fake_filename") md := Metadata{"Fake Header", "Fake Version"} db, err := bolt.Open(dbFilepath, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { t.Fatal(err) } boltDB := &BoltDatabase{ Metadata: md, DB: db, } err = boltDB.Close() if err != nil { t.Fatal(err) } // Should return an error since boltDB is closed. err = boltDB.checkMetadata(md) if err != bolt.ErrDatabaseNotOpen { t.Errorf("expected database not open, got %v", err) } err = os.Remove(dbFilepath) if err != nil { t.Error(err) } }
// TestErrCheckMetadata tests that checkMetadata returns an error when called // on a BoltDatabase whose metadata has been changed. func TestErrCheckMetadata(t *testing.T) { if testing.Short() { t.SkipNow() } testDir := build.TempDir(persistDir, "TestErrCheckMetadata") err := os.MkdirAll(testDir, 0700) if err != nil { t.Fatal(err) } for i, in := range testInputs { dbFilename := testFilenames[i%len(testFilenames)] dbFilepath := filepath.Join(testDir, dbFilename) db, err := bolt.Open(dbFilepath, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { t.Fatal(err) } boltDB := &BoltDatabase{ Metadata: in.md, DB: db, } err = db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte("Metadata")) if err != nil { return err } err = bucket.Put([]byte("Header"), []byte(in.newMd.Header)) if err != nil { return err } err = bucket.Put([]byte("Version"), []byte(in.newMd.Version)) if err != nil { return err } return nil }) if err != nil { t.Errorf("Put method failed for input %v, filename %v with error %v", in, dbFilename, err) continue } // Should return an error because boltDB's metadata now differs from // its original metadata. err = (*boltDB).checkMetadata(in.md) if err != in.err { t.Errorf("expected %v, got %v for input %v -> %v", in.err, err, in.md, in.newMd) } err = boltDB.Close() if err != nil { t.Fatal(err) } err = os.Remove(dbFilepath) if err != nil { t.Fatal(err) } } }
// openDatabase opens a database filename and checks metadata func OpenDatabase(md Metadata, filename string) (*BoltDatabase, error) { // Open the database using a 1 second timeout (without the timeout, // database will potentially hang indefinitely. db, err := bolt.Open(filename, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { return nil, err } boltDB := &BoltDatabase{ Metadata: md, DB: db, } err = boltDB.checkMetadata(md) if err != nil { return nil, err } return boltDB, nil }
// OpenDatabase opens a database filename and checks metadata func OpenDatabase(md Metadata, filename string) (*BoltDatabase, error) { // Open the database using a 1 second timeout (without the timeout, // database will potentially hang indefinitely. db, err := bolt.Open(filename, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { return nil, err } // Check the metadata. boltDB := &BoltDatabase{ Metadata: md, DB: db, } err = boltDB.checkMetadata(md) if err != nil { // Database opening failed, and therefore needs to be closed. db.Close() return nil, err } return boltDB, nil }
// TestErrTxNotWritable checks that updateMetadata returns an error when called // from a read-only transaction. func TestErrTxNotWritable(t *testing.T) { if testing.Short() { t.SkipNow() } testDir := build.TempDir(persistDir, "TestErrTxNotWritable") err := os.MkdirAll(testDir, 0700) if err != nil { t.Fatal(err) } for i, in := range testInputs { dbFilename := testFilenames[i%len(testFilenames)] dbFilepath := filepath.Join(testDir, dbFilename) db, err := bolt.Open(dbFilepath, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { t.Fatal(err) } boltDB := &BoltDatabase{ Metadata: in.md, DB: db, } // Should return an error because updateMetadata is being called from // a read-only transaction. err = db.View(boltDB.updateMetadata) if err != bolt.ErrTxNotWritable { t.Errorf("updateMetadata returned wrong error for input %v, filename %v; expected tx not writable, got %v", in.md, dbFilename, err) } err = boltDB.Close() if err != nil { t.Fatal(err) } err = os.Remove(dbFilepath) if err != nil { t.Fatal(err) } } }