From e9b2cab0fa6fd0536cf472967cd82f418218c81c Mon Sep 17 00:00:00 2001 From: Tommi Virtanen Date: Sun, 23 Mar 2014 14:40:08 -0700 Subject: Re-add tests for write failures Commit d2173f5f0ecbf4ed93c768e975435b04df3186ec removed the complete os & syscall mocking layer as overly complex. This commit adds back the simplest possible thing: hooks to control the database file writes. Missing tests: TestDBOpenMetaFileError, TestDBMmapStatError. These are harder to test without more extensive mocking. Conflicts: db_test.go --- db_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'db_test.go') diff --git a/db_test.go b/db_test.go index 2882ba8..b363486 100644 --- a/db_test.go +++ b/db_test.go @@ -1,6 +1,7 @@ package bolt import ( + "io" "io/ioutil" "math/rand" "os" @@ -50,6 +51,67 @@ func TestDBReopen(t *testing.T) { }) } +// Ensure that the database returns an error if the file handle cannot be open. +func TestDBOpenFileError(t *testing.T) { + withDBFile(func(db *DB, path string) { + exp := &os.PathError{ + Op: "open", + Path: path + "/youre-not-my-real-parent", + Err: syscall.ENOTDIR, + } + err := db.Open(path+"/youre-not-my-real-parent", 0666) + assert.Equal(t, err, exp) + }) +} + +// Ensure that write errors to the meta file handler during initialization are returned. +func TestDBMetaInitWriteError(t *testing.T) { + withDB(func(db *DB, path string) { + // Mock the file system. + db.ops.metaWriteAt = func(p []byte, offset int64) (n int, err error) { return 0, io.ErrShortWrite } + + // Open the database. + err := db.Open(path, 0666) + assert.Equal(t, err, io.ErrShortWrite) + }) +} + +// Ensure that a database that is too small returns an error. +func TestDBFileTooSmall(t *testing.T) { + withDBFile(func(db *DB, path string) { + // corrupt the database + err := os.Truncate(path, int64(os.Getpagesize())) + assert.NoError(t, err) + + err = db.Open(path, 0666) + assert.Equal(t, err, &Error{"file size too small", nil}) + }) +} + +// Ensure that corrupt meta0 page errors get returned. +func TestDBCorruptMeta0(t *testing.T) { + withDB(func(db *DB, 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) + + // Open the database. + err = db.Open(path, 0666) + assert.Equal(t, err, &Error{"meta error", ErrInvalid}) + }) +} + // Ensure that a database cannot open a transaction when it's not open. func TestDBTxErrDatabaseNotOpen(t *testing.T) { withDB(func(db *DB, path string) { -- cgit v1.2.3