aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db_test.go259
1 files changed, 131 insertions, 128 deletions
diff --git a/db_test.go b/db_test.go
index 2063249..b38be93 100644
--- a/db_test.go
+++ b/db_test.go
@@ -28,13 +28,13 @@ func TestOpen_BadPath(t *testing.T) {
// Ensure that a database can be opened without error.
func TestOpen(t *testing.T) {
- withTempPath(func(path string) {
- db, err := Open(path, 0666, nil)
- assert.NotNil(t, db)
- assert.NoError(t, err)
- assert.Equal(t, db.Path(), path)
- assert.NoError(t, db.Close())
- })
+ path := tempfile()
+ defer os.Remove(path)
+ db, err := Open(path, 0666, nil)
+ assert.NotNil(t, db)
+ assert.NoError(t, err)
+ assert.Equal(t, db.Path(), path)
+ assert.NoError(t, db.Close())
}
// Ensure that opening an already open database file will timeout.
@@ -42,21 +42,23 @@ func TestOpen_Timeout(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("timeout not supported on windows")
}
- withTempPath(func(path string) {
- // Open a data file.
- db0, err := Open(path, 0666, nil)
- assert.NotNil(t, db0)
- assert.NoError(t, err)
- // Attempt to open the database again.
- start := time.Now()
- db1, err := Open(path, 0666, &Options{Timeout: 100 * time.Millisecond})
- assert.Nil(t, db1)
- assert.Equal(t, ErrTimeout, err)
- assert.True(t, time.Since(start) > 100*time.Millisecond)
+ path := tempfile()
+ defer os.Remove(path)
- db0.Close()
- })
+ // Open a data file.
+ db0, err := Open(path, 0666, nil)
+ assert.NotNil(t, db0)
+ assert.NoError(t, err)
+
+ // Attempt to open the database again.
+ start := time.Now()
+ db1, err := Open(path, 0666, &Options{Timeout: 100 * time.Millisecond})
+ assert.Nil(t, db1)
+ assert.Equal(t, ErrTimeout, err)
+ assert.True(t, time.Since(start) > 100*time.Millisecond)
+
+ db0.Close()
}
// Ensure that opening an already open database file will wait until its closed.
@@ -64,48 +66,52 @@ func TestOpen_Wait(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("timeout not supported on windows")
}
- withTempPath(func(path string) {
- // Open a data file.
- db0, err := Open(path, 0666, nil)
- assert.NotNil(t, db0)
- assert.NoError(t, err)
- // Close it in just a bit.
- time.AfterFunc(100*time.Millisecond, func() { db0.Close() })
+ path := tempfile()
+ defer os.Remove(path)
- // Attempt to open the database again.
- start := time.Now()
- db1, err := Open(path, 0666, &Options{Timeout: 200 * time.Millisecond})
- assert.NotNil(t, db1)
- assert.NoError(t, err)
- assert.True(t, time.Since(start) > 100*time.Millisecond)
- })
+ // Open a data file.
+ db0, err := Open(path, 0666, nil)
+ assert.NotNil(t, db0)
+ assert.NoError(t, err)
+
+ // Close it in just a bit.
+ time.AfterFunc(100*time.Millisecond, func() { db0.Close() })
+
+ // Attempt to open the database again.
+ start := time.Now()
+ db1, err := Open(path, 0666, &Options{Timeout: 200 * time.Millisecond})
+ assert.NotNil(t, db1)
+ assert.NoError(t, err)
+ assert.True(t, time.Since(start) > 100*time.Millisecond)
}
// Ensure that a re-opened database is consistent.
func TestOpen_Check(t *testing.T) {
- withTempPath(func(path string) {
- db, err := Open(path, 0666, nil)
- assert.NoError(t, err)
- assert.NoError(t, db.View(func(tx *Tx) error { return <-tx.Check() }))
- db.Close()
+ path := tempfile()
+ defer os.Remove(path)
- db, err = Open(path, 0666, nil)
- assert.NoError(t, err)
- assert.NoError(t, db.View(func(tx *Tx) error { return <-tx.Check() }))
- db.Close()
- })
+ db, err := Open(path, 0666, nil)
+ assert.NoError(t, err)
+ assert.NoError(t, db.View(func(tx *Tx) error { return <-tx.Check() }))
+ db.Close()
+
+ db, err = Open(path, 0666, nil)
+ assert.NoError(t, err)
+ assert.NoError(t, db.View(func(tx *Tx) error { return <-tx.Check() }))
+ db.Close()
}
// Ensure that the database returns an error if the file handle cannot be open.
func TestDB_Open_FileError(t *testing.T) {
- withTempPath(func(path string) {
- _, err := Open(path+"/youre-not-my-real-parent", 0666, nil)
- if err, _ := err.(*os.PathError); assert.Error(t, err) {
- assert.Equal(t, path+"/youre-not-my-real-parent", err.Path)
- assert.Equal(t, "open", err.Op)
- }
- })
+ path := tempfile()
+ defer os.Remove(path)
+
+ _, err := Open(path+"/youre-not-my-real-parent", 0666, nil)
+ if err, _ := err.(*os.PathError); assert.Error(t, err) {
+ assert.Equal(t, path+"/youre-not-my-real-parent", err.Path)
+ assert.Equal(t, "open", err.Op)
+ }
}
// Ensure that write errors to the meta file handler during initialization are returned.
@@ -115,75 +121,78 @@ func TestDB_Open_MetaInitWriteError(t *testing.T) {
// Ensure that a database that is too small returns an error.
func TestDB_Open_FileTooSmall(t *testing.T) {
- withTempPath(func(path string) {
- db, err := Open(path, 0666, nil)
- assert.NoError(t, err)
- db.Close()
+ path := tempfile()
+ defer os.Remove(path)
- // corrupt the database
- assert.NoError(t, os.Truncate(path, int64(os.Getpagesize())))
+ db, err := Open(path, 0666, nil)
+ assert.NoError(t, err)
+ db.Close()
- db, err = Open(path, 0666, nil)
- assert.Equal(t, errors.New("file size too small"), err)
- })
+ // corrupt the database
+ assert.NoError(t, os.Truncate(path, int64(os.Getpagesize())))
+
+ db, err = Open(path, 0666, nil)
+ assert.Equal(t, errors.New("file size too small"), err)
}
// Ensure that corrupt meta0 page errors get returned.
func TestDB_Open_CorruptMeta0(t *testing.T) {
- withTempPath(func(path string) {
- var m meta
- m.magic = magic
- m.version = version
- m.pageSize = 0x8000
-
- // Create a file with bad magic.
- b := make([]byte, 0x10000)
- p0, p1 := (*page)(unsafe.Pointer(&b[0x0000])), (*page)(unsafe.Pointer(&b[0x8000]))
- p0.meta().magic = 0
- p0.meta().version = version
- p1.meta().magic = magic
- p1.meta().version = version
- err := ioutil.WriteFile(path, b, 0666)
- assert.NoError(t, err)
+ var m meta
+ m.magic = magic
+ m.version = version
+ m.pageSize = 0x8000
- // Open the database.
- _, err = Open(path, 0666, nil)
- assert.Equal(t, err, errors.New("meta0 error: invalid database"))
- })
+ path := tempfile()
+ defer os.Remove(path)
+
+ // Create a file with bad magic.
+ b := make([]byte, 0x10000)
+ p0, p1 := (*page)(unsafe.Pointer(&b[0x0000])), (*page)(unsafe.Pointer(&b[0x8000]))
+ p0.meta().magic = 0
+ p0.meta().version = version
+ p1.meta().magic = magic
+ p1.meta().version = version
+ err := ioutil.WriteFile(path, b, 0666)
+ assert.NoError(t, err)
+
+ // Open the database.
+ _, err = Open(path, 0666, nil)
+ assert.Equal(t, err, errors.New("meta0 error: invalid database"))
}
// Ensure that a corrupt meta page checksum causes the open to fail.
func TestDB_Open_MetaChecksumError(t *testing.T) {
for i := 0; i < 2; i++ {
- withTempPath(func(path string) {
- db, err := Open(path, 0600, nil)
- pageSize := db.pageSize
- db.Update(func(tx *Tx) error {
- _, err := tx.CreateBucket([]byte("widgets"))
- return err
- })
- db.Update(func(tx *Tx) error {
- _, err := tx.CreateBucket([]byte("woojits"))
- return err
- })
- db.Close()
-
- // Change a single byte in the meta page.
- f, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600)
- f.WriteAt([]byte{1}, int64((i*pageSize)+(pageHeaderSize+12)))
- f.Sync()
- f.Close()
-
- // Reopen the database.
- _, err = Open(path, 0600, nil)
- if assert.Error(t, err) {
- if i == 0 {
- assert.Equal(t, "meta0 error: checksum error", err.Error())
- } else {
- assert.Equal(t, "meta1 error: checksum error", err.Error())
- }
- }
+ path := tempfile()
+ defer os.Remove(path)
+
+ db, err := Open(path, 0600, nil)
+ pageSize := db.pageSize
+ db.Update(func(tx *Tx) error {
+ _, err := tx.CreateBucket([]byte("widgets"))
+ return err
+ })
+ db.Update(func(tx *Tx) error {
+ _, err := tx.CreateBucket([]byte("woojits"))
+ return err
})
+ db.Close()
+
+ // Change a single byte in the meta page.
+ f, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600)
+ f.WriteAt([]byte{1}, int64((i*pageSize)+(pageHeaderSize+12)))
+ f.Sync()
+ f.Close()
+
+ // Reopen the database.
+ _, err = Open(path, 0600, nil)
+ if assert.Error(t, err) {
+ if i == 0 {
+ assert.Equal(t, "meta0 error: checksum error", err.Error())
+ } else {
+ assert.Equal(t, "meta1 error: checksum error", err.Error())
+ }
+ }
}
}
@@ -579,31 +588,25 @@ func tempfile() string {
return f.Name()
}
-// withTempPath executes a function with a database reference.
-func withTempPath(fn func(string)) {
- path := tempfile()
- defer os.RemoveAll(path)
- fn(path)
-}
-
// withOpenDB executes a function with an already opened database.
func withOpenDB(fn func(*DB, string)) {
- withTempPath(func(path string) {
- db, err := Open(path, 0666, nil)
- if err != nil {
- panic("cannot open db: " + err.Error())
- }
- defer db.Close()
- fn(db, path)
+ path := tempfile()
+ defer os.Remove(path)
- // Log statistics.
- if *statsFlag {
- logStats(db)
- }
+ db, err := Open(path, 0666, nil)
+ if err != nil {
+ panic("cannot open db: " + err.Error())
+ }
+ defer db.Close()
+ fn(db, path)
- // Check database consistency after every test.
- mustCheck(db)
- })
+ // Log statistics.
+ if *statsFlag {
+ logStats(db)
+ }
+
+ // Check database consistency after every test.
+ mustCheck(db)
}
// mustCheck runs a consistency check on the database and panics if any errors are found.