From 8f298826716f7934a481d342acf7879f6b4cbf06 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Tue, 7 Mar 2023 03:51:07 +0000 Subject: [PATCH] Pass mptest crash. --- module.go | 19 +++--- tests/mptest/mptest_test.go | 35 ++++++++--- tests/mptest/testdata/.gitattributes | 2 +- tests/mptest/testdata/build.sh | 1 + tests/mptest/testdata/mptest.wasm | 4 +- vfs.go | 16 +++-- vfs_files.go | 92 +++++++++++++++------------- vfs_lock.go | 27 ++++---- vfs_lock_test.go | 33 +++++----- vfs_test.go | 54 +++++++++------- 10 files changed, 164 insertions(+), 119 deletions(-) diff --git a/module.go b/module.go index 9d8f845..ad24477 100644 --- a/module.go +++ b/module.go @@ -4,6 +4,7 @@ package sqlite3 import ( "context" "crypto/rand" + "io" "math" "os" "runtime" @@ -80,12 +81,13 @@ type module struct { ctx context.Context mem memory api sqliteAPI + vfs io.Closer } func newModule(mod api.Module) (m *module, err error) { m = &module{} m.mem = memory{mod} - m.ctx = context.Background() + m.ctx, m.vfs = vfsContext(context.Background()) getFun := func(name string) api.Function { f := mod.ExportedFunction(name) @@ -156,13 +158,15 @@ func newModule(mod api.Module) (m *module, err error) { interrupt: getVal("sqlite3_interrupt_offset"), } if err != nil { - m = nil + return nil, err } - return + return m, nil } func (m *module) close() error { - return m.mem.mod.Close(m.ctx) + err := m.mem.mod.Close(m.ctx) + m.vfs.Close() + return err } func (m *module) error(rc uint64, handle uint32, sql ...string) error { @@ -178,18 +182,18 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error { var r []uint64 - r, _ = m.api.errstr.Call(m.ctx, rc) + r = m.call(m.api.errstr, rc) if r != nil { err.str = m.mem.readString(uint32(r[0]), _MAX_STRING) } - r, _ = m.api.errmsg.Call(m.ctx, uint64(handle)) + r = m.call(m.api.errmsg, uint64(handle)) if r != nil { err.msg = m.mem.readString(uint32(r[0]), _MAX_STRING) } if sql != nil { - r, _ = m.api.erroff.Call(m.ctx, uint64(handle)) + r = m.call(m.api.erroff, uint64(handle)) if r != nil && r[0] != math.MaxUint32 { err.sql = sql[0][r[0]:] } @@ -205,6 +209,7 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error { func (m *module) call(fn api.Function, params ...uint64) []uint64 { r, err := fn.Call(m.ctx, params...) if err != nil { + m.vfs.Close() panic(err) } return r diff --git a/tests/mptest/mptest_test.go b/tests/mptest/mptest_test.go index 8745c76..5eff633 100644 --- a/tests/mptest/mptest_test.go +++ b/tests/mptest/mptest_test.go @@ -7,6 +7,7 @@ import ( "embed" "io" "io/fs" + "os" "path/filepath" "runtime" "strconv" @@ -33,6 +34,9 @@ var scripts embed.FS //go:linkname vfsNewEnvModuleBuilder github.com/ncruces/go-sqlite3.vfsNewEnvModuleBuilder func vfsNewEnvModuleBuilder(r wazero.Runtime) wazero.HostModuleBuilder +//go:linkname vfsContext github.com/ncruces/go-sqlite3.vfsContext +func vfsContext(ctx context.Context) (context.Context, io.Closer) + var ( rt wazero.Runtime module wazero.CompiledModule @@ -83,40 +87,56 @@ func system(ctx context.Context, mod api.Module, ptr uint32) uint32 { args = args[:len(args)-1] cfg := config(ctx).WithArgs(args...) - go rt.InstantiateModule(ctx, module, cfg) + go func() { + ctx, vfs := vfsContext(ctx) + rt.InstantiateModule(ctx, module, cfg) + vfs.Close() + }() return 0 } func Test_config01(t *testing.T) { - ctx := newContext(t) + ctx, vfs := vfsContext(newContext(t)) name := filepath.Join(t.TempDir(), "test.db") cfg := config(ctx).WithArgs("mptest", name, "config01.test") _, err := rt.InstantiateModule(ctx, module, cfg) if err != nil { t.Error(err) } + vfs.Close() } func Test_config02(t *testing.T) { - t.Skip() // TODO: remove - ctx := newContext(t) + if testing.Short() { + t.Skip("skipping in short mode") + } + if os.Getenv("CI") != "" { + t.Skip("skipping in CI") + } + + ctx, vfs := vfsContext(newContext(t)) name := filepath.Join(t.TempDir(), "test.db") cfg := config(ctx).WithArgs("mptest", name, "config02.test") _, err := rt.InstantiateModule(ctx, module, cfg) if err != nil { t.Error(err) } + vfs.Close() } func Test_crash01(t *testing.T) { - t.Skip() // TODO: remove - ctx := newContext(t) + if testing.Short() { + t.Skip("skipping in short mode") + } + + ctx, vfs := vfsContext(newContext(t)) name := filepath.Join(t.TempDir(), "test.db") cfg := config(ctx).WithArgs("mptest", name, "crash01.test") _, err := rt.InstantiateModule(ctx, module, cfg) if err != nil { t.Error(err) } + vfs.Close() } func Test_multiwrite01(t *testing.T) { @@ -124,13 +144,14 @@ func Test_multiwrite01(t *testing.T) { t.Skip("skipping in short mode") } - ctx := newContext(t) + ctx, vfs := vfsContext(newContext(t)) name := filepath.Join(t.TempDir(), "test.db") cfg := config(ctx).WithArgs("mptest", name, "multiwrite01.test") _, err := rt.InstantiateModule(ctx, module, cfg) if err != nil { t.Error(err) } + vfs.Close() } func newContext(t *testing.T) context.Context { diff --git a/tests/mptest/testdata/.gitattributes b/tests/mptest/testdata/.gitattributes index 6432e8f..86eff9f 100644 --- a/tests/mptest/testdata/.gitattributes +++ b/tests/mptest/testdata/.gitattributes @@ -1,2 +1,2 @@ mptest.wasm filter=lfs diff=lfs merge=lfs -text -*.test* -crlf \ No newline at end of file +*.*test -crlf \ No newline at end of file diff --git a/tests/mptest/testdata/build.sh b/tests/mptest/testdata/build.sh index 7cd5a8d..e221442 100755 --- a/tests/mptest/testdata/build.sh +++ b/tests/mptest/testdata/build.sh @@ -19,6 +19,7 @@ zig cc --target=wasm32-wasi -flto -g0 -Os \ -mbulk-memory -mreference-types \ -mnontrapping-fptoint -msign-ext \ -D_HAVE_SQLITE_CONFIG_H \ + -DSQLITE_DEFAULT_SYNCHRONOUS=0 \ -DSQLITE_DEFAULT_LOCKING_MODE=0 \ -DHAVE_USLEEP -DSQLITE_NO_SYNC \ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ diff --git a/tests/mptest/testdata/mptest.wasm b/tests/mptest/testdata/mptest.wasm index 0395be1..97b7a68 100755 --- a/tests/mptest/testdata/mptest.wasm +++ b/tests/mptest/testdata/mptest.wasm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e155ad9a9723b2eb2c0d187cbd079f4111931064a62ba0cb30ff4e4242bf5efd -size 1077263 +oid sha256:3960b873a7dab969a66f7859d491cec0dd4e6c0c9f83eab449fb15ec5ebdfd8f +size 1077281 diff --git a/vfs.go b/vfs.go index af16d0b..ad5de95 100644 --- a/vfs.go +++ b/vfs.go @@ -232,8 +232,7 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile uint32, fla vfsOS.DeleteOnClose(file) } - id := vfsGetFileID(file) - vfsFilePtr{mod, pFile}.SetID(id).SetLock(_NO_LOCK) + vfsFileOpen(ctx, mod, pFile, file) if pOutFlags != 0 { memory{mod}.writeUint32(pOutFlags, uint32(flags)) @@ -242,8 +241,7 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile uint32, fla } func vfsClose(ctx context.Context, mod api.Module, pFile uint32) uint32 { - id := vfsFilePtr{mod, pFile}.ID() - err := vfsCloseFile(id) + err := vfsFileClose(ctx, mod, pFile) if err != nil { return uint32(IOERR_CLOSE) } @@ -253,7 +251,7 @@ func vfsClose(ctx context.Context, mod api.Module, pFile uint32) uint32 { func vfsRead(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOfst uint64) uint32 { buf := memory{mod}.view(zBuf, uint64(iAmt)) - file := vfsFilePtr{mod, pFile}.OSFile() + file := vfsFileGet(ctx, mod, pFile) n, err := file.ReadAt(buf, int64(iOfst)) if n == int(iAmt) { return _OK @@ -270,7 +268,7 @@ func vfsRead(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOfs func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOfst uint64) uint32 { buf := memory{mod}.view(zBuf, uint64(iAmt)) - file := vfsFilePtr{mod, pFile}.OSFile() + file := vfsFileGet(ctx, mod, pFile) _, err := file.WriteAt(buf, int64(iOfst)) if err != nil { return uint32(IOERR_WRITE) @@ -279,7 +277,7 @@ func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOf } func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64) uint32 { - file := vfsFilePtr{mod, pFile}.OSFile() + file := vfsFileGet(ctx, mod, pFile) err := file.Truncate(int64(nByte)) if err != nil { return uint32(IOERR_TRUNCATE) @@ -288,7 +286,7 @@ func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64 } func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 { - file := vfsFilePtr{mod, pFile}.OSFile() + file := vfsFileGet(ctx, mod, pFile) err := file.Sync() if err != nil { return uint32(IOERR_FSYNC) @@ -300,7 +298,7 @@ func vfsFileSize(ctx context.Context, mod api.Module, pFile, pSize uint32) uint3 // This uses [os.File.Seek] because we don't care about the offset for reading/writing. // But consider using [os.File.Stat] instead (as other VFSes do). - file := vfsFilePtr{mod, pFile}.OSFile() + file := vfsFileGet(ctx, mod, pFile) off, err := file.Seek(0, io.SeekEnd) if err != nil { return uint32(IOERR_SEEK) diff --git a/vfs_files.go b/vfs_files.go index 8d53969..f5b6d27 100644 --- a/vfs_files.go +++ b/vfs_files.go @@ -1,69 +1,79 @@ package sqlite3 import ( + "context" + "io" "os" - "sync" "github.com/tetratelabs/wazero/api" ) -var ( - vfsOpenFiles []*os.File - vfsOpenFilesMtx sync.Mutex -) +type vfsKey struct{} -func vfsGetFileID(file *os.File) uint32 { - vfsOpenFilesMtx.Lock() - defer vfsOpenFilesMtx.Unlock() +type vfsState struct { + files []*os.File +} + +func (vfs *vfsState) Close() error { + for _, f := range vfs.files { + if f != nil { + f.Close() + } + } + vfs.files = nil + return nil +} + +func vfsContext(ctx context.Context) (context.Context, io.Closer) { + vfs := &vfsState{} + return context.WithValue(ctx, vfsKey{}, vfs), vfs +} + +func vfsFileNewID(ctx context.Context, file *os.File) uint32 { + vfs := ctx.Value(vfsKey{}).(*vfsState) // Find an empty slot. - for id, ptr := range vfsOpenFiles { + for id, ptr := range vfs.files { if ptr == nil { - vfsOpenFiles[id] = file + vfs.files[id] = file return uint32(id) } } // Add a new slot. - vfsOpenFiles = append(vfsOpenFiles, file) - return uint32(len(vfsOpenFiles) - 1) + vfs.files = append(vfs.files, file) + return uint32(len(vfs.files) - 1) } -func vfsCloseFile(id uint32) error { - vfsOpenFilesMtx.Lock() - defer vfsOpenFilesMtx.Unlock() +func vfsFileOpen(ctx context.Context, mod api.Module, pFile uint32, file *os.File) { + mem := memory{mod} + id := vfsFileNewID(ctx, file) + mem.writeUint32(pFile+ptrlen, id) + mem.writeUint32(pFile+2*ptrlen, _NO_LOCK) +} - file := vfsOpenFiles[id] - vfsOpenFiles[id] = nil +func vfsFileClose(ctx context.Context, mod api.Module, pFile uint32) error { + mem := memory{mod} + id := mem.readUint32(pFile + ptrlen) + vfs := ctx.Value(vfsKey{}).(*vfsState) + file := vfs.files[id] + vfs.files[id] = nil return file.Close() } -type vfsFilePtr struct { - api.Module - ptr uint32 +func vfsFileGet(ctx context.Context, mod api.Module, pFile uint32) *os.File { + mem := memory{mod} + id := mem.readUint32(pFile + ptrlen) + vfs := ctx.Value(vfsKey{}).(*vfsState) + return vfs.files[id] } -func (p vfsFilePtr) OSFile() *os.File { - id := p.ID() - vfsOpenFilesMtx.Lock() - defer vfsOpenFilesMtx.Unlock() - return vfsOpenFiles[id] +func vfsFileLockState(ctx context.Context, mod api.Module, pFile uint32) vfsLockState { + mem := memory{mod} + return vfsLockState(mem.readUint32(pFile + 2*ptrlen)) } -func (p vfsFilePtr) ID() uint32 { - return memory{p}.readUint32(p.ptr + ptrlen) -} - -func (p vfsFilePtr) Lock() vfsLockState { - return vfsLockState(memory{p}.readUint32(p.ptr + 2*ptrlen)) -} - -func (p vfsFilePtr) SetID(id uint32) vfsFilePtr { - memory{p}.writeUint32(p.ptr+ptrlen, id) - return p -} - -func (p vfsFilePtr) SetLock(lock vfsLockState) vfsFilePtr { - memory{p}.writeUint32(p.ptr+2*ptrlen, uint32(lock)) - return p +func vfsFileSetLockState(ctx context.Context, mod api.Module, pFile uint32, lock vfsLockState) { + mem := memory{mod} + mem.writeUint32(pFile+2*ptrlen, uint32(lock)) } diff --git a/vfs_lock.go b/vfs_lock.go index f307f2d..69d2cfe 100644 --- a/vfs_lock.go +++ b/vfs_lock.go @@ -61,9 +61,8 @@ func vfsLock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockSta panic(assertErr()) } - ptr := vfsFilePtr{mod, pFile} - file := ptr.OSFile() - cLock := ptr.Lock() + file := vfsFileGet(ctx, mod, pFile) + cLock := vfsFileLockState(ctx, mod, pFile) switch { case cLock < _NO_LOCK || cLock > _EXCLUSIVE_LOCK: @@ -95,7 +94,7 @@ func vfsLock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockSta if rc := vfsOS.GetSharedLock(file); rc != _OK { return uint32(rc) } - ptr.SetLock(_SHARED_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _SHARED_LOCK) return _OK case _RESERVED_LOCK: @@ -106,7 +105,7 @@ func vfsLock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockSta if rc := vfsOS.GetReservedLock(file); rc != _OK { return uint32(rc) } - ptr.SetLock(_RESERVED_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _RESERVED_LOCK) return _OK case _EXCLUSIVE_LOCK: @@ -119,12 +118,12 @@ func vfsLock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockSta if rc := vfsOS.GetPendingLock(file); rc != _OK { return uint32(rc) } - ptr.SetLock(_PENDING_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _PENDING_LOCK) } if rc := vfsOS.GetExclusiveLock(file); rc != _OK { return uint32(rc) } - ptr.SetLock(_EXCLUSIVE_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _EXCLUSIVE_LOCK) return _OK default: @@ -138,9 +137,8 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockS panic(assertErr()) } - ptr := vfsFilePtr{mod, pFile} - file := ptr.OSFile() - cLock := ptr.Lock() + file := vfsFileGet(ctx, mod, pFile) + cLock := vfsFileLockState(ctx, mod, pFile) // Connection state check. if cLock < _NO_LOCK || cLock > _EXCLUSIVE_LOCK { @@ -157,12 +155,12 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockS if rc := vfsOS.DowngradeLock(file, cLock); rc != _OK { return uint32(rc) } - ptr.SetLock(_SHARED_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _SHARED_LOCK) return _OK case _NO_LOCK: rc := vfsOS.ReleaseLock(file, cLock) - ptr.SetLock(_NO_LOCK) + vfsFileSetLockState(ctx, mod, pFile, _NO_LOCK) return uint32(rc) default: @@ -171,14 +169,13 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockS } func vfsCheckReservedLock(ctx context.Context, mod api.Module, pFile, pResOut uint32) uint32 { - ptr := vfsFilePtr{mod, pFile} - cLock := ptr.Lock() + cLock := vfsFileLockState(ctx, mod, pFile) if cLock > _SHARED_LOCK { panic(assertErr()) } - file := ptr.OSFile() + file := vfsFileGet(ctx, mod, pFile) locked, rc := vfsOS.CheckReservedLock(file) var res uint32 diff --git a/vfs_lock_test.go b/vfs_lock_test.go index 631d62d..7914991 100644 --- a/vfs_lock_test.go +++ b/vfs_lock_test.go @@ -38,10 +38,13 @@ func Test_vfsLock(t *testing.T) { pOutput = 32 ) mem := newMemory(128) - vfsFilePtr{mem.mod, pFile1}.SetID(vfsGetFileID(file1)).SetLock(_NO_LOCK) - vfsFilePtr{mem.mod, pFile2}.SetID(vfsGetFileID(file2)).SetLock(_NO_LOCK) + ctx, vfs := vfsContext(context.TODO()) + defer vfs.Close() - rc := vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + vfsFileOpen(ctx, mem.mod, pFile1, file1) + vfsFileOpen(ctx, mem.mod, pFile2, file2) + + rc := vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -49,12 +52,12 @@ func Test_vfsLock(t *testing.T) { t.Error("file was locked") } - rc = vfsLock(context.TODO(), mem.mod, pFile2, _SHARED_LOCK) + rc = vfsLock(ctx, mem.mod, pFile2, _SHARED_LOCK) if rc != _OK { t.Fatal("returned", rc) } - rc = vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + rc = vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -62,16 +65,16 @@ func Test_vfsLock(t *testing.T) { t.Error("file was locked") } - rc = vfsLock(context.TODO(), mem.mod, pFile2, _RESERVED_LOCK) + rc = vfsLock(ctx, mem.mod, pFile2, _RESERVED_LOCK) if rc != _OK { t.Fatal("returned", rc) } - rc = vfsLock(context.TODO(), mem.mod, pFile2, _SHARED_LOCK) + rc = vfsLock(ctx, mem.mod, pFile2, _SHARED_LOCK) if rc != _OK { t.Fatal("returned", rc) } - rc = vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + rc = vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -79,12 +82,12 @@ func Test_vfsLock(t *testing.T) { t.Error("file wasn't locked") } - rc = vfsLock(context.TODO(), mem.mod, pFile2, _EXCLUSIVE_LOCK) + rc = vfsLock(ctx, mem.mod, pFile2, _EXCLUSIVE_LOCK) if rc != _OK { t.Fatal("returned", rc) } - rc = vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + rc = vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -92,12 +95,12 @@ func Test_vfsLock(t *testing.T) { t.Error("file wasn't locked") } - rc = vfsLock(context.TODO(), mem.mod, pFile1, _SHARED_LOCK) + rc = vfsLock(ctx, mem.mod, pFile1, _SHARED_LOCK) if rc == _OK { t.Fatal("returned", rc) } - rc = vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + rc = vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -105,12 +108,12 @@ func Test_vfsLock(t *testing.T) { t.Error("file wasn't locked") } - rc = vfsUnlock(context.TODO(), mem.mod, pFile2, _SHARED_LOCK) + rc = vfsUnlock(ctx, mem.mod, pFile2, _SHARED_LOCK) if rc != _OK { t.Fatal("returned", rc) } - rc = vfsCheckReservedLock(context.TODO(), mem.mod, pFile1, pOutput) + rc = vfsCheckReservedLock(ctx, mem.mod, pFile1, pOutput) if rc != _OK { t.Fatal("returned", rc) } @@ -118,7 +121,7 @@ func Test_vfsLock(t *testing.T) { t.Error("file was locked") } - rc = vfsLock(context.TODO(), mem.mod, pFile1, _SHARED_LOCK) + rc = vfsLock(ctx, mem.mod, pFile1, _SHARED_LOCK) if rc != _OK { t.Fatal("returned", rc) } diff --git a/vfs_test.go b/vfs_test.go index 6b9aadc..f3e7208 100644 --- a/vfs_test.go +++ b/vfs_test.go @@ -16,15 +16,17 @@ import ( func Test_vfsExit(t *testing.T) { mem := newMemory(128) + ctx := context.TODO() defer func() { _ = recover() }() - vfsExit(context.TODO(), mem.mod, 1) + vfsExit(ctx, mem.mod, 1) t.Error("want panic") } func Test_vfsLocaltime(t *testing.T) { mem := newMemory(128) + ctx := context.TODO() - rc := vfsLocaltime(context.TODO(), mem.mod, 0, 4) + rc := vfsLocaltime(ctx, mem.mod, 0, 4) if rc != 0 { t.Fatal("returned", rc) } @@ -71,24 +73,26 @@ func Test_vfsRandomness(t *testing.T) { } func Test_vfsSleep(t *testing.T) { - start := time.Now() + ctx := context.TODO() - rc := vfsSleep(context.TODO(), 0, 123456) + now := time.Now() + rc := vfsSleep(ctx, 0, 123456) if rc != 0 { t.Fatal("returned", rc) } want := 123456 * time.Microsecond - if got := time.Since(start); got < want { + if got := time.Since(now); got < want { t.Errorf("got %v, want %v", got, want) } } func Test_vfsCurrentTime(t *testing.T) { mem := newMemory(128) + ctx := context.TODO() now := time.Now() - rc := vfsCurrentTime(context.TODO(), mem.mod, 0, 4) + rc := vfsCurrentTime(ctx, mem.mod, 0, 4) if rc != 0 { t.Fatal("returned", rc) } @@ -101,10 +105,11 @@ func Test_vfsCurrentTime(t *testing.T) { func Test_vfsCurrentTime64(t *testing.T) { mem := newMemory(128) + ctx := context.TODO() now := time.Now() time.Sleep(time.Millisecond) - rc := vfsCurrentTime64(context.TODO(), mem.mod, 0, 4) + rc := vfsCurrentTime64(ctx, mem.mod, 0, 4) if rc != 0 { t.Fatal("returned", rc) } @@ -119,13 +124,14 @@ func Test_vfsCurrentTime64(t *testing.T) { func Test_vfsFullPathname(t *testing.T) { mem := newMemory(128 + _MAX_PATHNAME) mem.writeString(4, ".") + ctx := context.TODO() - rc := vfsFullPathname(context.TODO(), mem.mod, 0, 4, 0, 8) + rc := vfsFullPathname(ctx, mem.mod, 0, 4, 0, 8) if rc != uint32(CANTOPEN_FULLPATH) { t.Errorf("returned %d, want %d", rc, CANTOPEN_FULLPATH) } - rc = vfsFullPathname(context.TODO(), mem.mod, 0, 4, _MAX_PATHNAME, 8) + rc = vfsFullPathname(ctx, mem.mod, 0, 4, _MAX_PATHNAME, 8) if rc != _OK { t.Fatal("returned", rc) } @@ -147,8 +153,9 @@ func Test_vfsDelete(t *testing.T) { mem := newMemory(128 + _MAX_PATHNAME) mem.writeString(4, name) + ctx := context.TODO() - rc := vfsDelete(context.TODO(), mem.mod, 0, 4, 1) + rc := vfsDelete(ctx, mem.mod, 0, 4, 1) if rc != _OK { t.Fatal("returned", rc) } @@ -157,7 +164,7 @@ func Test_vfsDelete(t *testing.T) { t.Fatal("did not delete the file") } - rc = vfsDelete(context.TODO(), mem.mod, 0, 4, 1) + rc = vfsDelete(ctx, mem.mod, 0, 4, 1) if rc != _OK { t.Fatal("returned", rc) } @@ -177,8 +184,9 @@ func Test_vfsAccess(t *testing.T) { mem := newMemory(128 + _MAX_PATHNAME) mem.writeString(8, dir) + ctx := context.TODO() - rc := vfsAccess(context.TODO(), mem.mod, 0, 8, _ACCESS_EXISTS, 4) + rc := vfsAccess(ctx, mem.mod, 0, 8, _ACCESS_EXISTS, 4) if rc != _OK { t.Fatal("returned", rc) } @@ -186,7 +194,7 @@ func Test_vfsAccess(t *testing.T) { t.Error("directory did not exist") } - rc = vfsAccess(context.TODO(), mem.mod, 0, 8, _ACCESS_READWRITE, 4) + rc = vfsAccess(ctx, mem.mod, 0, 8, _ACCESS_READWRITE, 4) if rc != _OK { t.Fatal("returned", rc) } @@ -195,7 +203,7 @@ func Test_vfsAccess(t *testing.T) { } mem.writeString(8, file) - rc = vfsAccess(context.TODO(), mem.mod, 0, 8, _ACCESS_READWRITE, 4) + rc = vfsAccess(ctx, mem.mod, 0, 8, _ACCESS_READWRITE, 4) if rc != _OK { t.Fatal("returned", rc) } @@ -206,9 +214,11 @@ func Test_vfsAccess(t *testing.T) { func Test_vfsFile(t *testing.T) { mem := newMemory(128) + ctx, vfs := vfsContext(context.TODO()) + defer vfs.Close() // Open a temporary file. - rc := vfsOpen(context.TODO(), mem.mod, 0, 0, 4, OPEN_CREATE|OPEN_EXCLUSIVE|OPEN_READWRITE|OPEN_DELETEONCLOSE, 0) + rc := vfsOpen(ctx, mem.mod, 0, 0, 4, OPEN_CREATE|OPEN_EXCLUSIVE|OPEN_READWRITE|OPEN_DELETEONCLOSE, 0) if rc != _OK { t.Fatal("returned", rc) } @@ -216,13 +226,13 @@ func Test_vfsFile(t *testing.T) { // Write stuff. text := "Hello world!" mem.writeString(16, text) - rc = vfsWrite(context.TODO(), mem.mod, 4, 16, uint32(len(text)), 0) + rc = vfsWrite(ctx, mem.mod, 4, 16, uint32(len(text)), 0) if rc != _OK { t.Fatal("returned", rc) } // Check file size. - rc = vfsFileSize(context.TODO(), mem.mod, 4, 16) + rc = vfsFileSize(ctx, mem.mod, 4, 16) if rc != _OK { t.Fatal("returned", rc) } @@ -231,7 +241,7 @@ func Test_vfsFile(t *testing.T) { } // Partial read at offset. - rc = vfsRead(context.TODO(), mem.mod, 4, 16, uint32(len(text)), 4) + rc = vfsRead(ctx, mem.mod, 4, 16, uint32(len(text)), 4) if rc != uint32(IOERR_SHORT_READ) { t.Fatal("returned", rc) } @@ -240,13 +250,13 @@ func Test_vfsFile(t *testing.T) { } // Truncate the file. - rc = vfsTruncate(context.TODO(), mem.mod, 4, 4) + rc = vfsTruncate(ctx, mem.mod, 4, 4) if rc != _OK { t.Fatal("returned", rc) } // Check file size. - rc = vfsFileSize(context.TODO(), mem.mod, 4, 16) + rc = vfsFileSize(ctx, mem.mod, 4, 16) if rc != _OK { t.Fatal("returned", rc) } @@ -255,7 +265,7 @@ func Test_vfsFile(t *testing.T) { } // Read at offset. - rc = vfsRead(context.TODO(), mem.mod, 4, 32, 4, 0) + rc = vfsRead(ctx, mem.mod, 4, 32, 4, 0) if rc != _OK { t.Fatal("returned", rc) } @@ -264,7 +274,7 @@ func Test_vfsFile(t *testing.T) { } // Close the file. - rc = vfsClose(context.TODO(), mem.mod, 4) + rc = vfsClose(ctx, mem.mod, 4) if rc != _OK { t.Fatal("returned", rc) }