From ce6d0627b22e65d40cdc762c60573154255514b3 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 27 Feb 2023 12:07:48 +0000 Subject: [PATCH] Tests. --- driver/driver_test.go | 24 +++- driver/example_test.go | 1 - error_test.go | 10 ++ example_test.go | 3 +- tests/blob_test.go | 228 ++++++++++++++++++++++++++++++++ tests/conn_test.go | 2 + tests/db_test.go | 2 +- tests/driver_test.go | 2 +- tests/parallel/parallel_test.go | 2 +- tests/stmt_test.go | 2 +- tests/tx_test.go | 34 +++-- 11 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 tests/blob_test.go diff --git a/driver/driver_test.go b/driver/driver_test.go index 2b68dff..514b70c 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -15,6 +15,8 @@ import ( ) func Test_Open_dir(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", ".") if err != nil { t.Fatal(err) @@ -31,6 +33,8 @@ func Test_Open_dir(t *testing.T) { } func Test_Open_pragma(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", "file::memory:?_pragma=busy_timeout(1000)") if err != nil { t.Fatal(err) @@ -48,6 +52,8 @@ func Test_Open_pragma(t *testing.T) { } func Test_Open_pragma_invalid(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", "file::memory:?_pragma=busy_timeout+1000") if err != nil { t.Fatal(err) @@ -71,8 +77,10 @@ func Test_Open_pragma_invalid(t *testing.T) { } func Test_Open_txLock(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", "file:"+ - filepath.Join(t.TempDir(), "test.db")+ + filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))+ "?_txlock=exclusive&_pragma=busy_timeout(0)") if err != nil { t.Fatal(err) @@ -103,6 +111,8 @@ func Test_Open_txLock(t *testing.T) { } func Test_Open_txLock_invalid(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", "file::memory:?_txlock=xclusive") if err != nil { t.Fatal(err) @@ -119,6 +129,8 @@ func Test_Open_txLock_invalid(t *testing.T) { } func Test_BeginTx(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -163,6 +175,8 @@ func Test_BeginTx(t *testing.T) { } func Test_Prepare(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) @@ -211,6 +225,8 @@ func Test_Prepare(t *testing.T) { } func Test_QueryRow_named(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -261,6 +277,8 @@ func Test_QueryRow_named(t *testing.T) { } func Test_QueryRow_blob_null(t *testing.T) { + t.Parallel() + db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) @@ -291,6 +309,8 @@ func Test_QueryRow_blob_null(t *testing.T) { } func Test_ZeroBlob(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -311,7 +331,7 @@ func Test_ZeroBlob(t *testing.T) { t.Fatal(err) } - _, err = conn.ExecContext(ctx, `INSERT INTO test(col) VALUES(?)`, sqlite3.ZeroBlob(4)) + _, err = conn.ExecContext(ctx, `INSERT INTO test VALUES (?)`, sqlite3.ZeroBlob(4)) if err != nil { t.Fatal(err) } diff --git a/driver/example_test.go b/driver/example_test.go index 9c7842b..029fd12 100644 --- a/driver/example_test.go +++ b/driver/example_test.go @@ -59,7 +59,6 @@ func Example() { log.Fatal(err) } fmt.Printf("ID of added album: %v\n", albID) - // Output: // Albums found: [{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99}] // Album found: {2 Giant Steps John Coltrane 63.99} diff --git a/error_test.go b/error_test.go index 72daf63..17eb612 100644 --- a/error_test.go +++ b/error_test.go @@ -15,6 +15,8 @@ func Test_assertErr(t *testing.T) { } func TestError(t *testing.T) { + t.Parallel() + err := Error{code: 0x8080} if rc := err.Code(); rc != 0x80 { t.Errorf("got %#x, want 0x80", rc) @@ -37,6 +39,8 @@ func TestError(t *testing.T) { } func TestError_Temporary(t *testing.T) { + t.Parallel() + tests := []struct { name string code uint64 @@ -73,6 +77,8 @@ func TestError_Temporary(t *testing.T) { } func TestError_Timeout(t *testing.T) { + t.Parallel() + tests := []struct { name string code uint64 @@ -103,6 +109,8 @@ func TestError_Timeout(t *testing.T) { } func Test_ErrorCode_Error(t *testing.T) { + t.Parallel() + db, err := Open(":memory:") if err != nil { t.Fatal(err) @@ -125,6 +133,8 @@ func Test_ErrorCode_Error(t *testing.T) { } func Test_ExtendedErrorCode_Error(t *testing.T) { + t.Parallel() + db, err := Open(":memory:") if err != nil { t.Fatal(err) diff --git a/example_test.go b/example_test.go index 69c461f..6101fcf 100644 --- a/example_test.go +++ b/example_test.go @@ -21,7 +21,7 @@ func Example() { log.Fatal(err) } - err = db.Exec(`INSERT INTO users(id, name) VALUES(0, 'go'), (1, 'zig'), (2, 'whatever')`) + err = db.Exec(`INSERT INTO users (id, name) VALUES (0, 'go'), (1, 'zig'), (2, 'whatever')`) if err != nil { log.Fatal(err) } @@ -47,7 +47,6 @@ func Example() { if err != nil { log.Fatal(err) } - // Output: // 0 go // 1 zig diff --git a/tests/blob_test.go b/tests/blob_test.go new file mode 100644 index 0000000..3554bf8 --- /dev/null +++ b/tests/blob_test.go @@ -0,0 +1,228 @@ +package tests + +import ( + "bytes" + "crypto/rand" + "errors" + "io" + "testing" + + "github.com/ncruces/go-sqlite3" + _ "github.com/ncruces/go-sqlite3/embed" +) + +func TestBlob(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO test VALUES (zeroblob(1024))`) + if err != nil { + t.Fatal(err) + } + + blob, err := db.OpenBlob("main", "test", "col", db.LastInsertRowID(), true) + if err != nil { + t.Fatal(err) + } + defer blob.Close() + + size := blob.Size() + if size != 1024 { + t.Errorf("got %d, want 1024", size) + } + + var data [1280]byte + _, err = rand.Read(data[:]) + if err != nil { + t.Fatal(err) + } + + _, err = io.Copy(blob, bytes.NewReader(data[:size/2])) + if err != nil { + t.Fatal(err) + } + + _, err = io.Copy(blob, bytes.NewReader(data[:])) + if !errors.Is(err, sqlite3.ERROR) { + t.Fatal("want error") + } + + _, err = io.Copy(blob, bytes.NewReader(data[size/2:size])) + if err != nil { + t.Fatal(err) + } + + _, err = blob.Seek(size/4, io.SeekStart) + if err != nil { + t.Fatal(err) + } + + if got, err := io.ReadAll(blob); err != nil { + t.Fatal(err) + } else if !bytes.Equal(got, data[size/4:size]) { + t.Errorf("got %q, want %q", got, data[size/4:size]) + } + + if n, err := blob.Read(make([]byte, 1)); n != 0 || err != io.EOF { + t.Errorf("got (%d, %v), want (0, EOF)", n, err) + } + + if err := blob.Close(); err != nil { + t.Fatal(err) + } + + if err := db.Close(); err != nil { + t.Fatal(err) + } +} + +func TestBlob_invalid(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO test VALUES (zeroblob(1024))`) + if err != nil { + t.Fatal(err) + } + + _, err = db.OpenBlob("", "test", "col", db.LastInsertRowID(), false) + if !errors.Is(err, sqlite3.ERROR) { + t.Fatal("want error") + } +} + +func TestBlob_readonly(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO test VALUES (zeroblob(1024))`) + if err != nil { + t.Fatal(err) + } + + blob, err := db.OpenBlob("main", "test", "col", db.LastInsertRowID(), false) + if err != nil { + t.Fatal(err) + } + defer blob.Close() + + _, err = blob.Write([]byte("data")) + if !errors.Is(err, sqlite3.READONLY) { + t.Fatal("want error") + } +} + +func TestBlob_expired(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO test VALUES (zeroblob(1024))`) + if err != nil { + t.Fatal(err) + } + + blob, err := db.OpenBlob("main", "test", "col", db.LastInsertRowID(), false) + if err != nil { + t.Fatal(err) + } + defer blob.Close() + + err = db.Exec(`DELETE FROM test`) + if err != nil { + t.Fatal(err) + } + + _, err = io.ReadAll(blob) + if !errors.Is(err, sqlite3.ABORT) { + t.Fatal("want error", err) + } +} + +func TestBlob_Seek(t *testing.T) { + t.Parallel() + + db, err := sqlite3.Open(":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`) + if err != nil { + t.Fatal(err) + } + + err = db.Exec(`INSERT INTO test VALUES (zeroblob(1024))`) + if err != nil { + t.Fatal(err) + } + + blob, err := db.OpenBlob("main", "test", "col", db.LastInsertRowID(), true) + if err != nil { + t.Fatal(err) + } + defer blob.Close() + + _, err = blob.Seek(0, 10) + if err == nil { + t.Fatal("want error") + } + + _, err = blob.Seek(-1, io.SeekCurrent) + if err == nil { + t.Fatal("want error") + } + + n, err := blob.Seek(1, io.SeekEnd) + if err != nil { + t.Fatal(err) + } + if n != blob.Size()+1 { + t.Errorf("got %d, want %d", n, blob.Size()) + } + + _, err = blob.Write([]byte("data")) + if !errors.Is(err, sqlite3.ERROR) { + t.Fatal("want error") + } +} diff --git a/tests/conn_test.go b/tests/conn_test.go index 5ea5b81..8d88d52 100644 --- a/tests/conn_test.go +++ b/tests/conn_test.go @@ -59,6 +59,8 @@ func TestConn_Close_BUSY(t *testing.T) { } func TestConn_SetInterrupt(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) diff --git a/tests/db_test.go b/tests/db_test.go index 47d8988..1e8c22d 100644 --- a/tests/db_test.go +++ b/tests/db_test.go @@ -30,7 +30,7 @@ func testDB(t *testing.T, name string) { t.Fatal(err) } - err = db.Exec(`INSERT INTO users(id, name) VALUES(0, 'go'), (1, 'zig'), (2, 'whatever')`) + err = db.Exec(`INSERT INTO users (id, name) VALUES (0, 'go'), (1, 'zig'), (2, 'whatever')`) if err != nil { t.Fatal(err) } diff --git a/tests/driver_test.go b/tests/driver_test.go index ebf851d..732dc17 100644 --- a/tests/driver_test.go +++ b/tests/driver_test.go @@ -34,7 +34,7 @@ func TestDriver(t *testing.T) { } res, err := conn.ExecContext(ctx, - `INSERT INTO users(id, name) VALUES(0, 'go'), (1, 'zig'), (2, 'whatever')`) + `INSERT INTO users (id, name) VALUES (0, 'go'), (1, 'zig'), (2, 'whatever')`) if err != nil { t.Fatal(err) } diff --git a/tests/parallel/parallel_test.go b/tests/parallel/parallel_test.go index 7821b51..24a102f 100644 --- a/tests/parallel/parallel_test.go +++ b/tests/parallel/parallel_test.go @@ -81,7 +81,7 @@ func testParallel(t *testing.T, name string, n int) { return err } - err = db.Exec(`INSERT INTO users(id, name) VALUES(0, 'go'), (1, 'zig'), (2, 'whatever')`) + err = db.Exec(`INSERT INTO users (id, name) VALUES (0, 'go'), (1, 'zig'), (2, 'whatever')`) if err != nil { return err } diff --git a/tests/stmt_test.go b/tests/stmt_test.go index 1dfa117..3c2cb65 100644 --- a/tests/stmt_test.go +++ b/tests/stmt_test.go @@ -22,7 +22,7 @@ func TestStmt(t *testing.T) { t.Fatal(err) } - stmt, _, err := db.Prepare(`INSERT INTO test(col) VALUES(?)`) + stmt, _, err := db.Prepare(`INSERT INTO test VALUES (?)`) if err != nil { t.Fatal(err) } diff --git a/tests/tx_test.go b/tests/tx_test.go index fed6970..9caf241 100644 --- a/tests/tx_test.go +++ b/tests/tx_test.go @@ -9,6 +9,8 @@ import ( ) func TestConn_Transaction_exec(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -75,6 +77,8 @@ func TestConn_Transaction_exec(t *testing.T) { } func TestConn_Transaction_panic(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -130,6 +134,8 @@ func TestConn_Transaction_panic(t *testing.T) { } func TestConn_Transaction_interrupt(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -145,7 +151,7 @@ func TestConn_Transaction_interrupt(t *testing.T) { if err != nil { t.Fatal(err) } - err = db.Exec(`INSERT INTO test(col) VALUES(1)`) + err = db.Exec(`INSERT INTO test VALUES (1)`) if err != nil { t.Fatal(err) } @@ -161,7 +167,7 @@ func TestConn_Transaction_interrupt(t *testing.T) { if err != nil { t.Fatal(err) } - err = db.Exec(`INSERT INTO test(col) VALUES(2)`) + err = db.Exec(`INSERT INTO test VALUES (2)`) if err != nil { t.Fatal(err) } @@ -172,7 +178,7 @@ func TestConn_Transaction_interrupt(t *testing.T) { t.Errorf("got %v, want sqlite3.INTERRUPT", err) } - err = db.Exec(`INSERT INTO test(col) VALUES(3)`) + err = db.Exec(`INSERT INTO test VALUES (3)`) if !errors.Is(err, sqlite3.INTERRUPT) { t.Errorf("got %v, want sqlite3.INTERRUPT", err) } @@ -203,6 +209,8 @@ func TestConn_Transaction_interrupt(t *testing.T) { } func TestConn_Transaction_rollback(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -215,7 +223,7 @@ func TestConn_Transaction_rollback(t *testing.T) { } tx := db.Begin() - err = db.Exec(`INSERT INTO test(col) VALUES(1)`) + err = db.Exec(`INSERT INTO test VALUES (1)`) if err != nil { t.Fatal(err) } @@ -247,6 +255,8 @@ func TestConn_Transaction_rollback(t *testing.T) { } func TestConn_Savepoint_exec(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -312,6 +322,8 @@ func TestConn_Savepoint_exec(t *testing.T) { } func TestConn_Savepoint_panic(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -366,6 +378,8 @@ func TestConn_Savepoint_panic(t *testing.T) { } func TestConn_Savepoint_interrupt(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -378,7 +392,7 @@ func TestConn_Savepoint_interrupt(t *testing.T) { } release := db.Savepoint() - err = db.Exec(`INSERT INTO test(col) VALUES(1)`) + err = db.Exec(`INSERT INTO test VALUES (1)`) if err != nil { t.Fatal(err) } @@ -391,12 +405,12 @@ func TestConn_Savepoint_interrupt(t *testing.T) { db.SetInterrupt(ctx) release1 := db.Savepoint() - err = db.Exec(`INSERT INTO test(col) VALUES(2)`) + err = db.Exec(`INSERT INTO test VALUES (2)`) if err != nil { t.Fatal(err) } release2 := db.Savepoint() - err = db.Exec(`INSERT INTO test(col) VALUES(3)`) + err = db.Exec(`INSERT INTO test VALUES (3)`) if err != nil { t.Fatal(err) } @@ -407,7 +421,7 @@ func TestConn_Savepoint_interrupt(t *testing.T) { t.Errorf("got %v, want sqlite3.INTERRUPT", err) } - err = db.Exec(`INSERT INTO test(col) VALUES(4)`) + err = db.Exec(`INSERT INTO test VALUES (4)`) if !errors.Is(err, sqlite3.INTERRUPT) { t.Errorf("got %v, want sqlite3.INTERRUPT", err) } @@ -444,6 +458,8 @@ func TestConn_Savepoint_interrupt(t *testing.T) { } func TestConn_Savepoint_rollback(t *testing.T) { + t.Parallel() + db, err := sqlite3.Open(":memory:") if err != nil { t.Fatal(err) @@ -456,7 +472,7 @@ func TestConn_Savepoint_rollback(t *testing.T) { } release := db.Savepoint() - err = db.Exec(`INSERT INTO test(col) VALUES(1)`) + err = db.Exec(`INSERT INTO test VALUES (1)`) if err != nil { t.Fatal(err) }