mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Tests.
This commit is contained in:
330
util/vfsutil/wrap_test.go
Normal file
330
util/vfsutil/wrap_test.go
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
// Package vfsutil implements virtual filesystem utilities.
|
||||||
|
package vfsutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ncruces/go-sqlite3/vfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWrapOpen(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapOpen(mockVFS{open: func(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
called++
|
||||||
|
return nil, flags, nil
|
||||||
|
}}, "", 0)
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("open not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
WrapOpenFilename(mockVFS{open: func(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
called++
|
||||||
|
return nil, flags, nil
|
||||||
|
}}, nil, 0)
|
||||||
|
|
||||||
|
if called != 2 {
|
||||||
|
t.Error("open not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapOpenFilename(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapOpen(mockVFSFilename{openFilename: func(name *vfs.Filename, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
called++
|
||||||
|
return nil, flags, nil
|
||||||
|
}}, "", 0)
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("openFilename not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
WrapOpenFilename(mockVFSFilename{openFilename: func(name *vfs.Filename, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
called++
|
||||||
|
return nil, flags, nil
|
||||||
|
}}, nil, 0)
|
||||||
|
|
||||||
|
if called != 2 {
|
||||||
|
t.Error("openFilename not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapLockState(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapLockState(mockFile{lockState: func() vfs.LockLevel {
|
||||||
|
called++
|
||||||
|
return 0
|
||||||
|
}})
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("lockState not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapPersistWAL(t *testing.T) {
|
||||||
|
persist := false
|
||||||
|
WrapSetPersistWAL(mockFile{setPersistWAL: func(b bool) { persist = b }}, true)
|
||||||
|
if !persist {
|
||||||
|
t.Error("setPersistWAL not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
called := 0
|
||||||
|
WrapPersistWAL(mockFile{persistWAL: func() bool { called++; return persist }})
|
||||||
|
if !persist {
|
||||||
|
t.Error("persistWAL not called")
|
||||||
|
}
|
||||||
|
if called != 1 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapPowersafeOverwrite(t *testing.T) {
|
||||||
|
persist := false
|
||||||
|
WrapSetPowersafeOverwrite(mockFile{setPowersafeOverwrite: func(b bool) { persist = b }}, true)
|
||||||
|
if !persist {
|
||||||
|
t.Error("setPowersafeOverwrite not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
called := 0
|
||||||
|
WrapPowersafeOverwrite(mockFile{powersafeOverwrite: func() bool { called++; return persist }})
|
||||||
|
if !persist {
|
||||||
|
t.Error("powersafeOverwrite not called")
|
||||||
|
}
|
||||||
|
if called != 1 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapChunkSize(t *testing.T) {
|
||||||
|
var chunk int
|
||||||
|
|
||||||
|
WrapChunkSize(mockFile{chunkSize: func(size int) {
|
||||||
|
chunk = size
|
||||||
|
}}, 5)
|
||||||
|
|
||||||
|
if chunk != 5 {
|
||||||
|
t.Error("chunkSize not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapSizeHint(t *testing.T) {
|
||||||
|
var hint int64
|
||||||
|
|
||||||
|
WrapSizeHint(mockFile{sizeHint: func(size int64) error {
|
||||||
|
hint = size
|
||||||
|
return nil
|
||||||
|
}}, 5)
|
||||||
|
|
||||||
|
if hint != 5 {
|
||||||
|
t.Error("sizeHint not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapHasMoved(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapHasMoved(mockFile{hasMoved: func() (bool, error) {
|
||||||
|
called++
|
||||||
|
return false, nil
|
||||||
|
}})
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("hasMoved not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapOverwrite(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapOverwrite(mockFile{overwrite: func() error {
|
||||||
|
called++
|
||||||
|
return nil
|
||||||
|
}})
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("overwrite not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapSyncSuper(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapSyncSuper(mockFile{syncSuper: func(super string) error {
|
||||||
|
called++
|
||||||
|
return nil
|
||||||
|
}}, "")
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("syncSuper not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapCommitPhaseTwo(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapCommitPhaseTwo(mockFile{commitPhaseTwo: func() error {
|
||||||
|
called++
|
||||||
|
return nil
|
||||||
|
}})
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("commitPhaseTwo not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapBatchAtomicWrite(t *testing.T) {
|
||||||
|
calledBegin := 0
|
||||||
|
calledCommit := 0
|
||||||
|
calledRollback := 0
|
||||||
|
|
||||||
|
f := mockFile{
|
||||||
|
begin: func() error { calledBegin++; return nil },
|
||||||
|
commit: func() error { calledCommit++; return nil },
|
||||||
|
rollback: func() error { calledRollback++; return nil },
|
||||||
|
}
|
||||||
|
WrapBeginAtomicWrite(f)
|
||||||
|
WrapCommitAtomicWrite(f)
|
||||||
|
WrapRollbackAtomicWrite(f)
|
||||||
|
|
||||||
|
if calledBegin != 1 {
|
||||||
|
t.Error("beginAtomicWrite not called")
|
||||||
|
}
|
||||||
|
if calledCommit != 1 {
|
||||||
|
t.Error("commitAtomicWrite not called")
|
||||||
|
}
|
||||||
|
if calledRollback != 1 {
|
||||||
|
t.Error("rollbackAtomicWrite not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapCheckpoint(t *testing.T) {
|
||||||
|
calledStart := 0
|
||||||
|
calledDone := 0
|
||||||
|
|
||||||
|
f := mockFile{
|
||||||
|
ckptStart: func() { calledStart++ },
|
||||||
|
ckptDone: func() { calledDone++ },
|
||||||
|
}
|
||||||
|
WrapCheckpointStart(f)
|
||||||
|
WrapCheckpointDone(f)
|
||||||
|
|
||||||
|
if calledStart != 1 {
|
||||||
|
t.Error("checkpointStart not called")
|
||||||
|
}
|
||||||
|
if calledDone != 1 {
|
||||||
|
t.Error("checkpointDone not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapPragma(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
val, err := WrapPragma(mockFile{
|
||||||
|
pragma: func(name, value string) (string, error) {
|
||||||
|
called++
|
||||||
|
if name != "foo" || value != "bar" {
|
||||||
|
t.Error("wrong pragma arguments")
|
||||||
|
}
|
||||||
|
return "baz", nil
|
||||||
|
},
|
||||||
|
}, "foo", "bar")
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("pragma not called")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if val != "baz" {
|
||||||
|
t.Error("unexpected pragma return value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWrapBusyHandler(t *testing.T) {
|
||||||
|
called := 0
|
||||||
|
|
||||||
|
WrapBusyHandler(mockFile{
|
||||||
|
busyHandler: func(handler func() bool) {
|
||||||
|
handler()
|
||||||
|
called++
|
||||||
|
},
|
||||||
|
}, func() bool { return true })
|
||||||
|
|
||||||
|
if called != 1 {
|
||||||
|
t.Error("busyHandler not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockVFS struct {
|
||||||
|
open func(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
return m.open(name, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockVFS) Delete(name string, syncDir bool) error { panic("unimplemented") }
|
||||||
|
func (m mockVFS) FullPathname(name string) (string, error) { panic("unimplemented") }
|
||||||
|
func (m mockVFS) Access(name string, flags vfs.AccessFlag) (bool, error) { panic("unimplemented") }
|
||||||
|
|
||||||
|
type mockVFSFilename struct {
|
||||||
|
mockVFS
|
||||||
|
openFilename func(name *vfs.Filename, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockVFSFilename) OpenFilename(name *vfs.Filename, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
|
return m.openFilename(name, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockFile struct {
|
||||||
|
lockState func() vfs.LockLevel
|
||||||
|
persistWAL func() bool
|
||||||
|
setPersistWAL func(bool)
|
||||||
|
powersafeOverwrite func() bool
|
||||||
|
setPowersafeOverwrite func(bool)
|
||||||
|
chunkSize func(int)
|
||||||
|
sizeHint func(int64) error
|
||||||
|
hasMoved func() (bool, error)
|
||||||
|
overwrite func() error
|
||||||
|
syncSuper func(super string) error
|
||||||
|
commitPhaseTwo func() error
|
||||||
|
begin func() error
|
||||||
|
commit func() error
|
||||||
|
rollback func() error
|
||||||
|
ckptStart func()
|
||||||
|
ckptDone func()
|
||||||
|
busyHandler func(func() bool)
|
||||||
|
pragma func(name, value string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockFile) LockState() vfs.LockLevel { return m.lockState() }
|
||||||
|
func (m mockFile) PersistWAL() bool { return m.persistWAL() }
|
||||||
|
func (m mockFile) SetPersistWAL(v bool) { m.setPersistWAL(v) }
|
||||||
|
func (m mockFile) PowersafeOverwrite() bool { return m.powersafeOverwrite() }
|
||||||
|
func (m mockFile) SetPowersafeOverwrite(v bool) { m.setPowersafeOverwrite(v) }
|
||||||
|
func (m mockFile) ChunkSize(s int) { m.chunkSize(s) }
|
||||||
|
func (m mockFile) SizeHint(s int64) error { return m.sizeHint(s) }
|
||||||
|
func (m mockFile) HasMoved() (bool, error) { return m.hasMoved() }
|
||||||
|
func (m mockFile) Overwrite() error { return m.overwrite() }
|
||||||
|
func (m mockFile) SyncSuper(s string) error { return m.syncSuper(s) }
|
||||||
|
func (m mockFile) CommitPhaseTwo() error { return m.commitPhaseTwo() }
|
||||||
|
func (m mockFile) BeginAtomicWrite() error { return m.begin() }
|
||||||
|
func (m mockFile) CommitAtomicWrite() error { return m.commit() }
|
||||||
|
func (m mockFile) RollbackAtomicWrite() error { return m.rollback() }
|
||||||
|
func (m mockFile) CheckpointStart() { m.ckptStart() }
|
||||||
|
func (m mockFile) CheckpointDone() { m.ckptDone() }
|
||||||
|
func (m mockFile) BusyHandler(f func() bool) { m.busyHandler(f) }
|
||||||
|
func (m mockFile) Pragma(n, v string) (string, error) { return m.pragma(n, v) }
|
||||||
|
|
||||||
|
func (m mockFile) Close() error { panic("unimplemented") }
|
||||||
|
func (m mockFile) ReadAt(p []byte, off int64) (n int, err error) { panic("unimplemented") }
|
||||||
|
func (m mockFile) WriteAt(p []byte, off int64) (n int, err error) { panic("unimplemented") }
|
||||||
|
func (m mockFile) Truncate(size int64) error { panic("unimplemented") }
|
||||||
|
func (m mockFile) Sync(flags vfs.SyncFlag) error { panic("unimplemented") }
|
||||||
|
func (m mockFile) Size() (int64, error) { panic("unimplemented") }
|
||||||
|
func (m mockFile) Lock(lock vfs.LockLevel) error { panic("unimplemented") }
|
||||||
|
func (m mockFile) Unlock(lock vfs.LockLevel) error { panic("unimplemented") }
|
||||||
|
func (m mockFile) CheckReservedLock() (bool, error) { panic("unimplemented") }
|
||||||
|
func (m mockFile) SectorSize() int { panic("unimplemented") }
|
||||||
|
func (m mockFile) DeviceCharacteristics() vfs.DeviceCharacteristic { panic("unimplemented") }
|
||||||
@@ -20,7 +20,10 @@ type hbshVFS struct {
|
|||||||
|
|
||||||
func (h *hbshVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
func (h *hbshVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
// notest // OpenFilename is called instead
|
// notest // OpenFilename is called instead
|
||||||
return nil, 0, sqlite3.CANTOPEN
|
if name == "" {
|
||||||
|
return h.OpenFilename(nil, flags)
|
||||||
|
}
|
||||||
|
return nil, flags, sqlite3.CANTOPEN
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hbshVFS) OpenFilename(name *vfs.Filename, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) {
|
func (h *hbshVFS) OpenFilename(name *vfs.Filename, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) {
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ func (vfsOS) Access(name string, flags AccessFlag) (bool, error) {
|
|||||||
|
|
||||||
func (vfsOS) Open(name string, flags OpenFlag) (File, OpenFlag, error) {
|
func (vfsOS) Open(name string, flags OpenFlag) (File, OpenFlag, error) {
|
||||||
// notest // OpenFilename is called instead
|
// notest // OpenFilename is called instead
|
||||||
|
if name == "" {
|
||||||
|
return vfsOS{}.OpenFilename(nil, flags)
|
||||||
|
}
|
||||||
return nil, 0, _CANTOPEN
|
return nil, 0, _CANTOPEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ type xtsVFS struct {
|
|||||||
|
|
||||||
func (x *xtsVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
func (x *xtsVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
|
||||||
// notest // OpenFilename is called instead
|
// notest // OpenFilename is called instead
|
||||||
return nil, 0, sqlite3.CANTOPEN
|
if name == "" {
|
||||||
|
return x.OpenFilename(nil, flags)
|
||||||
|
}
|
||||||
|
return nil, flags, sqlite3.CANTOPEN
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *xtsVFS) OpenFilename(name *vfs.Filename, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) {
|
func (x *xtsVFS) OpenFilename(name *vfs.Filename, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user