diff options
author | Rodolfo Carvalho <rhcarvalho@gmail.com> | 2015-12-10 18:39:03 +0100 |
---|---|---|
committer | Rodolfo Carvalho <rhcarvalho@gmail.com> | 2015-12-10 18:39:03 +0100 |
commit | 058a7ab3475728df50656699387b985b3a2537ed (patch) | |
tree | 9ef288011fb89734bb8509012624eea5badea884 /db_test.go | |
parent | Merge pull request #467 from boltdb/readme-coalescer (diff) | |
download | dedo-058a7ab3475728df50656699387b985b3a2537ed.tar.gz dedo-058a7ab3475728df50656699387b985b3a2537ed.tar.xz |
Make bolt.Open return the documented errors
- ErrInvalid is returned when a data file is not a Bolt-formatted
database.
- ErrVersionMismatch is returned when the data file was created with a
different version of Bolt.
- ErrChecksum is returned when either meta page checksum does not match.
Also:
- Do not wrap errors from os.Stat, so that a caller could handle os.Stat
errors just like it can handle errors from os.Open that bolt.Open
might return.
- Name tests consistently, following the pattern "TestOpen_*".
- Remove deferred calls to `os.Remove(path)`.
The calls are not only unnecessary, but also in all cases `os.Remove`
returns an error that is ignored. All those calls are meant to remove
a file that was already removed by `tmpfile()`.
- Combine "bad path" tests and use filepath.Join to build the path.
Diffstat (limited to 'db_test.go')
-rw-r--r-- | db_test.go | 118 |
1 files changed, 94 insertions, 24 deletions
@@ -7,29 +7,48 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "regexp" "runtime" "sort" "strings" "testing" "time" + "unsafe" "github.com/boltdb/bolt" ) var statsFlag = flag.Bool("stats", false, "show performance stats") -// Ensure that opening a database with a bad path returns an error. -func TestOpen_BadPath(t *testing.T) { - db, err := bolt.Open("", 0666, nil) - assert(t, err != nil, "err: %s", err) - assert(t, db == nil, "") +// version is the data file format version. +const version = 2 + +// magic is the marker value to indicate that a file is a Bolt DB. +const magic uint32 = 0xED0CDAED + +// pageSize is the size of one page in the data file. +const pageSize = 4096 + +// pageHeaderSize is the size of a page header. +const pageHeaderSize = 16 + +// meta represents a simplified version of a database meta page for testing. +type meta struct { + magic uint32 + version uint32 + _ uint32 + _ uint32 + _ [16]byte + _ uint64 + _ uint64 + _ uint64 + checksum uint64 } // Ensure that a database can be opened without error. func TestOpen(t *testing.T) { path := tempfile() - defer os.Remove(path) db, err := bolt.Open(path, 0666, nil) assert(t, db != nil, "") ok(t, err) @@ -37,6 +56,73 @@ func TestOpen(t *testing.T) { ok(t, db.Close()) } +// Ensure that opening a database with a bad path returns an error. +func TestOpen_BadPath(t *testing.T) { + for _, path := range []string{ + "", + filepath.Join(tempfile(), "youre-not-my-real-parent"), + } { + t.Logf("path = %q", path) + db, err := bolt.Open(path, 0666, nil) + assert(t, err != nil, "err: %s", err) + equals(t, path, err.(*os.PathError).Path) + equals(t, "open", err.(*os.PathError).Op) + equals(t, (*bolt.DB)(nil), db) + } +} + +// Ensure that opening a file with wrong checksum returns ErrChecksum. +func TestOpen_ErrChecksum(t *testing.T) { + buf := make([]byte, pageSize) + meta := (*meta)(unsafe.Pointer(&buf[0])) + meta.magic = magic + meta.version = version + meta.checksum = 123 + + path := tempfile() + f, err := os.Create(path) + equals(t, nil, err) + f.WriteAt(buf, pageHeaderSize) + f.Close() + defer os.Remove(path) + + _, err = bolt.Open(path, 0666, nil) + equals(t, bolt.ErrChecksum, err) +} + +// Ensure that opening a file that is not a Bolt database returns ErrInvalid. +func TestOpen_ErrInvalid(t *testing.T) { + path := tempfile() + + f, err := os.Create(path) + equals(t, nil, err) + fmt.Fprintln(f, "this is not a bolt database") + f.Close() + defer os.Remove(path) + + _, err = bolt.Open(path, 0666, nil) + equals(t, bolt.ErrInvalid, err) +} + +// Ensure that opening a file created with a different version of Bolt returns +// ErrVersionMismatch. +func TestOpen_ErrVersionMismatch(t *testing.T) { + buf := make([]byte, pageSize) + meta := (*meta)(unsafe.Pointer(&buf[0])) + meta.magic = magic + meta.version = version + 100 + + path := tempfile() + f, err := os.Create(path) + equals(t, nil, err) + f.WriteAt(buf, pageHeaderSize) + f.Close() + defer os.Remove(path) + + _, err = bolt.Open(path, 0666, nil) + equals(t, bolt.ErrVersionMismatch, err) +} + // Ensure that opening an already open database file will timeout. func TestOpen_Timeout(t *testing.T) { if runtime.GOOS == "solaris" { @@ -44,7 +130,6 @@ func TestOpen_Timeout(t *testing.T) { } path := tempfile() - defer os.Remove(path) // Open a data file. db0, err := bolt.Open(path, 0666, nil) @@ -68,7 +153,6 @@ func TestOpen_Wait(t *testing.T) { } path := tempfile() - defer os.Remove(path) // Open a data file. db0, err := bolt.Open(path, 0666, nil) @@ -179,7 +263,6 @@ func TestOpen_Size_Large(t *testing.T) { // Ensure that a re-opened database is consistent. func TestOpen_Check(t *testing.T) { path := tempfile() - defer os.Remove(path) db, err := bolt.Open(path, 0666, nil) ok(t, err) @@ -192,26 +275,14 @@ func TestOpen_Check(t *testing.T) { db.Close() } -// Ensure that the database returns an error if the file handle cannot be open. -func TestDB_Open_FileError(t *testing.T) { - path := tempfile() - defer os.Remove(path) - - _, err := bolt.Open(path+"/youre-not-my-real-parent", 0666, nil) - assert(t, err.(*os.PathError) != nil, "") - equals(t, path+"/youre-not-my-real-parent", err.(*os.PathError).Path) - equals(t, "open", err.(*os.PathError).Op) -} - // Ensure that write errors to the meta file handler during initialization are returned. -func TestDB_Open_MetaInitWriteError(t *testing.T) { +func TestOpen_MetaInitWriteError(t *testing.T) { t.Skip("pending") } // Ensure that a database that is too small returns an error. -func TestDB_Open_FileTooSmall(t *testing.T) { +func TestOpen_FileTooSmall(t *testing.T) { path := tempfile() - defer os.Remove(path) db, err := bolt.Open(path, 0666, nil) ok(t, err) @@ -235,7 +306,6 @@ func TestOpen_ReadOnly(t *testing.T) { bucket, key, value := []byte(`bucket`), []byte(`key`), []byte(`value`) path := tempfile() - defer os.Remove(path) // Open in read-write mode. db, err := bolt.Open(path, 0666, nil) |