aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2014-01-12 15:30:09 -0700
committerBen Johnson <benbjohnson@yahoo.com>2014-01-12 15:30:09 -0700
commit28c1e86a27b2dc3ba59b8c4d69f15a8e54334a89 (patch)
tree0ceb5ed513345f4d52fe419cb635bd6b6aed31de
parentAdd mock OS. (diff)
downloaddedo-28c1e86a27b2dc3ba59b8c4d69f15a8e54334a89.tar.gz
dedo-28c1e86a27b2dc3ba59b8c4d69f15a8e54334a89.tar.xz
Mock OS and File.
-rw-r--r--db.go16
-rw-r--r--db_test.go41
-rw-r--r--file.go8
-rw-r--r--file_test.go29
-rw-r--r--os.go2
5 files changed, 87 insertions, 9 deletions
diff --git a/db.go b/db.go
index 8176dd6..d9a6274 100644
--- a/db.go
+++ b/db.go
@@ -1,7 +1,7 @@
package bolt
import (
- . "os"
+ "os"
"sync"
"syscall"
"unsafe"
@@ -26,9 +26,9 @@ type DB struct {
sync.Mutex
opened bool
- os OS
- file *File
- metafile *File
+ os _os
+ file file
+ metafile file
data []byte
buf []byte
meta0 *meta
@@ -56,14 +56,14 @@ type DB struct {
}
func NewDB() *DB {
- return &DB{os: &sysos{}}
+ return &DB{}
}
func (db *DB) Path() string {
return db.path
}
-func (db *DB) Open(path string, mode FileMode) error {
+func (db *DB) Open(path string, mode os.FileMode) error {
var err error
db.Lock()
defer db.Unlock()
@@ -79,11 +79,11 @@ func (db *DB) Open(path string, mode FileMode) error {
// Open data file and separate sync handler for metadata writes.
db.path = path
- if db.file, err = db.os.OpenFile(db.path, O_RDWR|O_CREATE, mode); err != nil {
+ if db.file, err = db.os.OpenFile(db.path, os.O_RDWR|os.O_CREATE, mode); err != nil {
db.close()
return err
}
- if db.metafile, err = db.os.OpenFile(db.path, O_RDWR|O_SYNC, mode); err != nil {
+ if db.metafile, err = db.os.OpenFile(db.path, os.O_RDWR|os.O_SYNC, mode); err != nil {
db.close()
return err
}
diff --git a/db_test.go b/db_test.go
index 534bc3c..9c6ad85 100644
--- a/db_test.go
+++ b/db_test.go
@@ -8,13 +8,46 @@ import (
"github.com/stretchr/testify/assert"
)
+// Ensure that a database can be opened without error.
func TestDBOpen(t *testing.T) {
withDB(func(db *DB, path string) {
err := db.Open(path, 0666)
assert.NoError(t, err)
+ assert.Equal(t, db.Path(), path)
})
}
+// Ensure that the database returns an error if already open.
+func TestDBReopen(t *testing.T) {
+ withDB(func(db *DB, path string) {
+ db.Open(path, 0666)
+ err := db.Open(path, 0666)
+ assert.Equal(t, err, DatabaseAlreadyOpenedError)
+ })
+}
+
+// Ensure that the database returns an error if the file handle cannot be open.
+func TestDBOpenFileError(t *testing.T) {
+ withMockDB(func(db *DB, mockos *mockos, path string) {
+ exp := &os.PathError{}
+ mockos.On("OpenFile", path, os.O_RDWR|os.O_CREATE, os.FileMode(0666)).Return((*os.File)(nil), exp)
+ err := db.Open(path, 0666)
+ assert.Equal(t, err, exp)
+ })
+}
+
+// Ensure that the database returns an error if the meta file handle cannot be open.
+func TestDBOpenMetaFileError(t *testing.T) {
+ withMockDB(func(db *DB, mockos *mockos, path string) {
+ exp := &os.PathError{}
+ mockos.On("OpenFile", path, os.O_RDWR|os.O_CREATE, os.FileMode(0666)).Return(&os.File{}, nil)
+ mockos.On("OpenFile", path, os.O_RDWR|os.O_SYNC, os.FileMode(0666)).Return((*os.File)(nil), exp)
+ err := db.Open(path, 0666)
+ assert.Equal(t, err, exp)
+ })
+}
+
+// withDB executes a function with a database reference.
func withDB(fn func(*DB, string)) {
f, _ := ioutil.TempFile("", "bolt-")
path := f.Name()
@@ -25,3 +58,11 @@ func withDB(fn func(*DB, string)) {
db := NewDB()
fn(db, path)
}
+
+// withMockDB executes a function with a database reference and a mock filesystem.
+func withMockDB(fn func(*DB, *mockos, string)) {
+ os := &mockos{}
+ db := NewDB()
+ db.os = os
+ fn(db, os, "/mock/db")
+}
diff --git a/file.go b/file.go
new file mode 100644
index 0000000..4beb722
--- /dev/null
+++ b/file.go
@@ -0,0 +1,8 @@
+package bolt
+
+type file interface {
+ Fd() uintptr
+ Name() string
+ ReadAt(b []byte, off int64) (n int, err error)
+ WriteAt(b []byte, off int64) (n int, err error)
+}
diff --git a/file_test.go b/file_test.go
new file mode 100644
index 0000000..3f33d14
--- /dev/null
+++ b/file_test.go
@@ -0,0 +1,29 @@
+package bolt
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockfile struct {
+ mock.Mock
+ fd uintptr
+ name string
+}
+
+func (m *mockfile) Fd() uintptr {
+ return m.fd
+}
+
+func (m *mockfile) Name() string {
+ return m.name
+}
+
+func (m *mockfile) ReadAt(b []byte, off int64) (n int, err error) {
+ args := m.Called(b, off)
+ return args.Int(0), args.Error(1)
+}
+
+func (m *mockfile) WriteAt(b []byte, off int64) (n int, err error) {
+ args := m.Called(b, off)
+ return args.Int(0), args.Error(1)
+}
diff --git a/os.go b/os.go
index f1de723..ab415a9 100644
--- a/os.go
+++ b/os.go
@@ -4,7 +4,7 @@ import (
"os"
)
-type OS interface {
+type _os interface {
OpenFile(name string, flag int, perm os.FileMode) (file *os.File, err error)
Stat(name string) (fi os.FileInfo, err error)
Getpagesize() int