Use memdb for tests. (#131)

This commit is contained in:
Nuno Cruces
2024-08-05 21:25:47 +01:00
committed by GitHub
parent 40db26c1dd
commit 8f835eda79
21 changed files with 154 additions and 70 deletions

View File

@@ -7,7 +7,6 @@ import (
"errors"
"math"
"net/url"
"path/filepath"
"testing"
"time"
@@ -15,7 +14,7 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/internal/util"
"github.com/ncruces/go-sqlite3/vfs"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Test_Open_dir(t *testing.T) {
@@ -38,8 +37,11 @@ func Test_Open_dir(t *testing.T) {
func Test_Open_pragma(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_pragma": {"busy_timeout(1000)"},
})
db, err := sql.Open("sqlite3", "file::memory:?_pragma=busy_timeout(1000)")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -57,8 +59,11 @@ func Test_Open_pragma(t *testing.T) {
func Test_Open_pragma_invalid(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_pragma": {"busy_timeout 1000"},
})
db, err := sql.Open("sqlite3", "file::memory:?_pragma=busy_timeout+1000")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -81,14 +86,13 @@ func Test_Open_pragma_invalid(t *testing.T) {
}
func Test_Open_txLock(t *testing.T) {
if !vfs.SupportsFileLocking {
t.Skip("skipping without locks")
}
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_txlock": {"exclusive"},
"_pragma": {"busy_timeout(1000)"},
})
db, err := sql.Open("sqlite3", "file:"+
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))+
"?_txlock=exclusive&_pragma=busy_timeout(0)")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -119,8 +123,11 @@ func Test_Open_txLock(t *testing.T) {
func Test_Open_txLock_invalid(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_txlock": {"xclusive"},
})
_, err := sql.Open("sqlite3", "file::memory:?_txlock=xclusive")
_, err := sql.Open("sqlite3", tmp+"_txlock=xclusive")
if err == nil {
t.Fatal("want error")
}
@@ -130,17 +137,16 @@ func Test_Open_txLock_invalid(t *testing.T) {
}
func Test_BeginTx(t *testing.T) {
if !vfs.SupportsFileLocking {
t.Skip("skipping without locks")
}
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_txlock": {"exclusive"},
"_pragma": {"busy_timeout(0)"},
})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := sql.Open("sqlite3", "file:"+
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))+
"?_txlock=exclusive&_pragma=busy_timeout(0)")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -182,8 +188,9 @@ func Test_BeginTx(t *testing.T) {
func Test_Prepare(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := sql.Open("sqlite3", ":memory:")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -222,11 +229,12 @@ func Test_Prepare(t *testing.T) {
func Test_QueryRow_named(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := sql.Open("sqlite3", ":memory:")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -274,8 +282,9 @@ func Test_QueryRow_named(t *testing.T) {
func Test_QueryRow_blob_null(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := sql.Open("sqlite3", ":memory:")
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}
@@ -310,7 +319,11 @@ func Test_time(t *testing.T) {
for _, fmt := range []string{"auto", "sqlite", "rfc3339", time.ANSIC} {
t.Run(fmt, func(t *testing.T) {
db, err := sql.Open("sqlite3", "file::memory:?_timefmt="+url.QueryEscape(fmt))
tmp := memdb.TestDB(t, url.Values{
"_timefmt": {fmt},
})
db, err := sql.Open("sqlite3", tmp)
if err != nil {
t.Fatal(err)
}

View File

@@ -12,10 +12,11 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/ncruces/go-sqlite3/ext/array"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Example_driver() {
db, err := driver.Open(":memory:", array.Register)
db, err := driver.Open("file:/test.db?vfs=memdb", array.Register)
if err != nil {
log.Fatal(err)
}
@@ -87,8 +88,9 @@ func Example() {
func Test_cursor_Column(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", array.Register)
db, err := driver.Open(tmp, array.Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -12,12 +12,14 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/ncruces/go-sqlite3/ext/fileio"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Test_lsmode(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", fileio.Register)
db, err := driver.Open(tmp, fileio.Register)
if err != nil {
t.Fatal(err)
}
@@ -51,7 +53,9 @@ func Test_readfile(t *testing.T) {
for _, fsys := range []fs.FS{nil, os.DirFS(".")} {
t.Run("", func(t *testing.T) {
db, err := driver.Open(":memory:", func(c *sqlite3.Conn) error {
tmp := memdb.TestDB(t)
db, err := driver.Open(tmp, func(c *sqlite3.Conn) error {
fileio.RegisterFS(c, fsys)
return nil
})

View File

@@ -13,6 +13,7 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/ncruces/go-sqlite3/ext/fileio"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Test_fsdir(t *testing.T) {
@@ -20,7 +21,9 @@ func Test_fsdir(t *testing.T) {
for _, fsys := range []fs.FS{nil, os.DirFS(".")} {
t.Run("", func(t *testing.T) {
db, err := driver.Open(":memory:", func(c *sqlite3.Conn) error {
tmp := memdb.TestDB(t)
db, err := driver.Open(tmp, func(c *sqlite3.Conn) error {
fileio.RegisterFS(c, fsys)
return nil
})

View File

@@ -10,12 +10,14 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Test_writefile(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
_ "golang.org/x/crypto/blake2b"
_ "golang.org/x/crypto/blake2s"
_ "golang.org/x/crypto/md4"
@@ -19,6 +20,7 @@ import (
func TestRegister(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
tests := []struct {
name string
@@ -52,7 +54,7 @@ func TestRegister(t *testing.T) {
{"blake2b('', 256)", "0E5751C026E543B2E8AB2EB06099DAA1D1E5DF47778F7787FAAB45CDF12FE3A8"},
}
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -15,10 +15,11 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/ncruces/go-sqlite3/ext/lines"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Example() {
db, err := driver.Open(":memory:", lines.Register)
db, err := driver.Open("file:/test.db?vfs=memdb", lines.Register)
if err != nil {
log.Fatal(err)
}
@@ -66,8 +67,9 @@ func Example() {
func Test_lines(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", lines.Register)
db, err := driver.Open(tmp, lines.Register)
if err != nil {
log.Fatal(err)
}
@@ -96,8 +98,9 @@ func Test_lines(t *testing.T) {
func Test_lines_error(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", lines.Register)
db, err := driver.Open(tmp, lines.Register)
if err != nil {
log.Fatal(err)
}
@@ -120,8 +123,9 @@ func Test_lines_error(t *testing.T) {
func Test_lines_read(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", lines.Register)
db, err := driver.Open(tmp, lines.Register)
if err != nil {
log.Fatal(err)
}
@@ -151,8 +155,9 @@ func Test_lines_read(t *testing.T) {
func Test_lines_test(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", lines.Register)
db, err := driver.Open(tmp, lines.Register)
if err != nil {
log.Fatal(err)
}

View File

@@ -6,12 +6,14 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestRegister(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}
@@ -45,8 +47,9 @@ func TestRegister(t *testing.T) {
func TestRegister_errors(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -7,12 +7,14 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Test_generate(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}
@@ -130,8 +132,9 @@ func Test_generate(t *testing.T) {
func Test_convert(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", Register)
db, err := driver.Open(tmp, Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -9,12 +9,14 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/ncruces/go-sqlite3/ext/zorder"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestRegister_zorder(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", zorder.Register)
db, err := driver.Open(tmp, zorder.Register)
if err != nil {
t.Fatal(err)
}
@@ -57,8 +59,9 @@ func TestRegister_zorder(t *testing.T) {
func TestRegister_unzorder(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", zorder.Register)
db, err := driver.Open(tmp, zorder.Register)
if err != nil {
t.Fatal(err)
}
@@ -84,8 +87,9 @@ func TestRegister_unzorder(t *testing.T) {
func TestRegister_error(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db, err := driver.Open(":memory:", zorder.Register)
db, err := driver.Open(tmp, zorder.Register)
if err != nil {
t.Fatal(err)
}

View File

@@ -10,14 +10,14 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestDialector(t *testing.T) {
// This is the DSN of the in-memory SQLite database for these tests.
const InMemoryDSN = "file:testdatabase?mode=memory&cache=shared"
tmp := memdb.TestDB(t)
// Custom connection with a custom function called "my_custom_function".
db, err := driver.Open(InMemoryDSN, func(conn *sqlite3.Conn) error {
db, err := driver.Open(tmp, func(conn *sqlite3.Conn) error {
return conn.CreateFunction("my_custom_function", 0, sqlite3.DETERMINISTIC,
func(ctx sqlite3.Context, arg ...sqlite3.Value) {
ctx.ResultText("my-result")
@@ -36,14 +36,14 @@ func TestDialector(t *testing.T) {
}{
{
description: "Default driver",
dialector: Open(InMemoryDSN),
dialector: Open(tmp),
openSuccess: true,
query: "SELECT 1",
querySuccess: true,
},
{
description: "Custom function",
dialector: Open(InMemoryDSN),
dialector: Open(tmp),
openSuccess: true,
query: "SELECT my_custom_function()",
querySuccess: false,

View File

@@ -6,11 +6,10 @@ import (
"github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/vfs/memdb"
)
func Example_json() {
db, err := sqlite3.Open("file:/test.db?vfs=memdb")
db, err := sqlite3.Open(":memory:")
if err != nil {
log.Fatal(err)
}

View File

@@ -45,7 +45,7 @@ func (t params) mustExec(sql string, args ...interface{}) sql.Result {
func (sqliteDB) RunTest(t *testing.T, fn func(params)) {
db, err := sql.Open("sqlite3", "file:"+
filepath.Join(t.TempDir(), "foo.db")+
filepath.ToSlash(filepath.Join(t.TempDir(), "foo.db"))+
"?_pragma=busy_timeout(10000)&_pragma=synchronous(off)")
if err != nil {
t.Fatalf("foo.db open fail: %v", err)

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"math"
"net/url"
"os"
"path/filepath"
"strings"
@@ -13,6 +14,7 @@ import (
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs"
"github.com/ncruces/go-sqlite3/vfs/memdb"
_ "github.com/ncruces/go-sqlite3/vfs/memdb"
)
@@ -727,8 +729,11 @@ func TestConn_DBName(t *testing.T) {
func TestConn_AutoVacuumPages(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t, url.Values{
"_pragma": {"auto_vacuum(full)"},
})
db, err := sqlite3.Open("file:test.db?vfs=memdb&_pragma=auto_vacuum(full)")
db, err := sqlite3.Open(tmp)
if err != nil {
t.Fatal(err)
}

View File

@@ -12,6 +12,7 @@ import (
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs"
_ "github.com/ncruces/go-sqlite3/vfs/adiantum"
"github.com/ncruces/go-sqlite3/vfs/memdb"
_ "github.com/ncruces/go-sqlite3/vfs/memdb"
)
@@ -65,7 +66,7 @@ func TestDB_utf16(t *testing.T) {
func TestDB_memdb(t *testing.T) {
t.Parallel()
testDB(t, "file:test.db?vfs=memdb")
testDB(t, memdb.TestDB(t))
}
func TestDB_adiantum(t *testing.T) {

View File

@@ -8,15 +8,17 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestDriver(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:", nil, func(c *sqlite3.Conn) error {
db, err := driver.Open(tmp, nil, func(c *sqlite3.Conn) error {
return c.Exec(`PRAGMA optimize`)
})
if err != nil {

View File

@@ -11,16 +11,18 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
"github.com/ncruces/julianday"
)
func TestJSON(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:")
db, err := driver.Open(tmp)
if err != nil {
t.Fatal(err)
}

View File

@@ -2,6 +2,7 @@ package tests
import (
"io"
"net/url"
"os"
"os/exec"
"path/filepath"
@@ -31,7 +32,7 @@ func Test_parallel(t *testing.T) {
}
name := "file:" +
filepath.Join(t.TempDir(), "test.db") +
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db")) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(truncate)" +
"&_pragma=synchronous(off)"
@@ -45,7 +46,7 @@ func Test_wal(t *testing.T) {
}
name := "file:" +
filepath.Join(t.TempDir(), "test.db") +
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db")) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(wal)" +
"&_pragma=synchronous(off)"
@@ -61,8 +62,9 @@ func Test_memdb(t *testing.T) {
iter = 5000
}
memdb.Create("test.db", nil)
name := "file:/test.db?vfs=memdb"
name := memdb.TestDB(t, url.Values{
"_pragma": {"busy_timeout(10000)"},
})
testParallel(t, name, iter)
testIntegrity(t, name)
}
@@ -82,7 +84,10 @@ func Test_adiantum(t *testing.T) {
name := "file:" +
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db")) +
"?vfs=adiantum" +
"&_pragma=hexkey(e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)"
"&_pragma=hexkey(e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)" +
"&_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(truncate)" +
"&_pragma=synchronous(off)"
testParallel(t, name, iter)
testIntegrity(t, name)
}
@@ -98,7 +103,7 @@ func TestMultiProcess(t *testing.T) {
file := filepath.Join(t.TempDir(), "test.db")
t.Setenv("TestMultiProcess_dbfile", file)
name := "file:" + file +
name := "file:" + filepath.ToSlash(file) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(truncate)" +
"&_pragma=synchronous(off)"
@@ -133,7 +138,7 @@ func TestChildProcess(t *testing.T) {
t.SkipNow()
}
name := "file:" + file +
name := "file:" + filepath.ToSlash(file) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(truncate)" +
"&_pragma=synchronous(off)"
@@ -177,8 +182,9 @@ func Benchmark_memdb(b *testing.B) {
sqlite3.Initialize()
b.ResetTimer()
memdb.Create("test.db", nil)
name := "file:/test.db?vfs=memdb"
name := memdb.TestDB(b, url.Values{
"_pragma": {"busy_timeout(10000)"},
})
testParallel(b, name, b.N)
}
@@ -218,11 +224,6 @@ func testParallel(t testing.TB, name string, n int) {
}
defer db.Close()
err = db.BusyTimeout(10 * time.Second)
if err != nil {
return err
}
stmt, _, err := db.Prepare(`SELECT id, name FROM users`)
if err != nil {
return err

View File

@@ -11,6 +11,7 @@ import (
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestTimeFormat_Encode(t *testing.T) {
@@ -132,11 +133,12 @@ func TestTimeFormat_Decode(t *testing.T) {
func TestTimeFormat_Scanner(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:")
db, err := driver.Open(tmp)
if err != nil {
t.Fatal(err)
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
_ "github.com/ncruces/go-sqlite3/vfs/memdb"
"github.com/ncruces/go-sqlite3/vfs/memdb"
)
func TestConn_Transaction_exec(t *testing.T) {
@@ -254,14 +254,15 @@ func TestConn_Transaction_interrupted(t *testing.T) {
func TestConn_Transaction_busy(t *testing.T) {
t.Parallel()
tmp := memdb.TestDB(t)
db1, err := sqlite3.Open("file:/test.db?vfs=memdb")
db1, err := sqlite3.Open(tmp)
if err != nil {
t.Fatal(err)
}
defer db1.Close()
db2, err := sqlite3.Open("file:/test.db?vfs=memdb&_pragma=busy_timeout(10000)")
db2, err := sqlite3.Open(tmp + "&_pragma=busy_timeout(10000)")
if err != nil {
t.Fatal(err)
}

View File

@@ -10,7 +10,10 @@
package memdb
import (
"fmt"
"net/url"
"sync"
"testing"
"github.com/ncruces/go-sqlite3/vfs"
)
@@ -66,3 +69,30 @@ func Delete(name string) {
defer memoryMtx.Unlock()
delete(memoryDBs, name)
}
// TestDB creates an empty shared memory database for the test to use.
// The database is automatically deleted when the test and all its subtests complete.
// Each subsequent call to TestDB returns a unique database.
func TestDB(tb testing.TB, params ...url.Values) string {
tb.Helper()
name := fmt.Sprintf("%s_%p", tb.Name(), tb)
tb.Cleanup(func() { Delete(name) })
Create(name, nil)
p := url.Values{"vfs": {"memdb"}}
for _, v := range params {
for k, v := range v {
for _, v := range v {
p.Add(k, v)
}
}
}
return (&url.URL{
Scheme: "file",
OmitHost: true,
Path: "/" + name,
RawQuery: p.Encode(),
}).String()
}