mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
More tests.
This commit is contained in:
20
.github/coverage.html
vendored
20
.github/coverage.html
vendored
@@ -65,7 +65,7 @@
|
||||
|
||||
<option value="file4">github.com/ncruces/go-sqlite3/stmt.go (27.2%)</option>
|
||||
|
||||
<option value="file5">github.com/ncruces/go-sqlite3/vfs.go (67.4%)</option>
|
||||
<option value="file5">github.com/ncruces/go-sqlite3/vfs.go (74.7%)</option>
|
||||
|
||||
<option value="file6">github.com/ncruces/go-sqlite3/vfs_files.go (70.6%)</option>
|
||||
|
||||
@@ -848,7 +848,7 @@ func vfsFullPathname(ctx context.Context, mod api.Module, pVfs, zRelative, nFull
|
||||
// This might be buggy on Windows (the Windows VFS doesn't try).
|
||||
|
||||
<span class="cov8" title="1">siz := uint32(len(abs) + 1)
|
||||
if siz > nFull </span><span class="cov0" title="0">{
|
||||
if siz > nFull </span><span class="cov8" title="1">{
|
||||
return uint32(CANTOPEN_FULLPATH)
|
||||
}</span>
|
||||
<span class="cov8" title="1">if zFull == 0 </span><span class="cov0" title="0">{
|
||||
@@ -873,13 +873,13 @@ func vfsDelete(ctx context.Context, mod api.Module, pVfs, zPath, syncDir uint32)
|
||||
<span class="cov8" title="1">if err != nil </span><span class="cov0" title="0">{
|
||||
return uint32(IOERR_DELETE)
|
||||
}</span>
|
||||
<span class="cov8" title="1">if syncDir != 0 </span><span class="cov0" title="0">{
|
||||
<span class="cov8" title="1">if syncDir != 0 </span><span class="cov8" title="1">{
|
||||
f, err := os.Open(filepath.Dir(path))
|
||||
if err == nil </span><span class="cov0" title="0">{
|
||||
if err == nil </span><span class="cov8" title="1">{
|
||||
err = f.Sync()
|
||||
f.Close()
|
||||
}</span>
|
||||
<span class="cov0" title="0">if err != nil </span><span class="cov0" title="0">{
|
||||
<span class="cov8" title="1">if err != nil </span><span class="cov0" title="0">{
|
||||
return uint32(IOERR_DELETE)
|
||||
}</span>
|
||||
}
|
||||
@@ -897,7 +897,7 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags Ac
|
||||
switch </span>{
|
||||
case flags == ACCESS_EXISTS:<span class="cov8" title="1">
|
||||
switch </span>{
|
||||
case err == nil:<span class="cov0" title="0">
|
||||
case err == nil:<span class="cov8" title="1">
|
||||
res = 1</span>
|
||||
case errors.Is(err, fs.ErrNotExist):<span class="cov8" title="1">
|
||||
res = 0</span>
|
||||
@@ -905,15 +905,15 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath uint32, flags Ac
|
||||
return uint32(IOERR_ACCESS)</span>
|
||||
}
|
||||
|
||||
case err == nil:<span class="cov0" title="0">
|
||||
case err == nil:<span class="cov8" title="1">
|
||||
var want fs.FileMode = syscall.S_IRUSR
|
||||
if flags == ACCESS_READWRITE </span><span class="cov0" title="0">{
|
||||
if flags == ACCESS_READWRITE </span><span class="cov8" title="1">{
|
||||
want |= syscall.S_IWUSR
|
||||
}</span>
|
||||
<span class="cov0" title="0">if fi.IsDir() </span><span class="cov0" title="0">{
|
||||
<span class="cov8" title="1">if fi.IsDir() </span><span class="cov8" title="1">{
|
||||
want |= syscall.S_IXUSR
|
||||
}</span>
|
||||
<span class="cov0" title="0">if fi.Mode()&want == want </span><span class="cov0" title="0">{
|
||||
<span class="cov8" title="1">if fi.Mode()&want == want </span><span class="cov8" title="1">{
|
||||
res = 1
|
||||
}</span> else<span class="cov0" title="0"> {
|
||||
res = 0
|
||||
|
||||
2
.github/coverage.svg
vendored
2
.github/coverage.svg
vendored
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="108" height="20" role="img" aria-label="coverage: 59.0%"><title>coverage: 59.0%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="108" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="47" height="20" fill="#fe7d37"/><rect width="108" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="835" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">59.0%</text><text x="835" y="140" transform="scale(.1)" fill="#fff" textLength="370">59.0%</text></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="108" height="20" role="img" aria-label="coverage: 61.1%"><title>coverage: 61.1%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="108" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="47" height="20" fill="#fe7d37"/><rect width="108" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="835" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">61.1%</text><text x="835" y="140" transform="scale(.1)" fill="#fff" textLength="370">61.1%</text></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
34
conn_test.go
34
conn_test.go
@@ -15,7 +15,7 @@ func TestConn_new(t *testing.T) {
|
||||
|
||||
defer func() { _ = recover() }()
|
||||
db.new(math.MaxUint32)
|
||||
t.Errorf("should have panicked")
|
||||
t.Error("should have panicked")
|
||||
}
|
||||
|
||||
func TestConn_newBytes(t *testing.T) {
|
||||
@@ -27,18 +27,18 @@ func TestConn_newBytes(t *testing.T) {
|
||||
|
||||
ptr := db.newBytes(nil)
|
||||
if ptr != 0 {
|
||||
t.Errorf("want nullptr got %x", ptr)
|
||||
t.Errorf("got %x, want nullptr", ptr)
|
||||
}
|
||||
|
||||
buf := []byte("sqlite3")
|
||||
ptr = db.newBytes(buf)
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Fatal("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
want := buf
|
||||
if got, ok := db.memory.Read(ptr, uint32(len(want))); !ok || !bytes.Equal(want, got) {
|
||||
t.Errorf("want %q got %q", want, got)
|
||||
if got, ok := db.memory.Read(ptr, uint32(len(want))); !ok || !bytes.Equal(got, want) {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,18 +51,18 @@ func TestConn_newString(t *testing.T) {
|
||||
|
||||
ptr := db.newString("")
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Error("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
str := "sqlite3\000sqlite3"
|
||||
ptr = db.newString(str)
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Fatal("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
want := str + "\000"
|
||||
if got, ok := db.memory.Read(ptr, uint32(len(want))); !ok || want != string(got) {
|
||||
t.Errorf("want %q got %q", want, got)
|
||||
if got, ok := db.memory.Read(ptr, uint32(len(want))); !ok || string(got) != want {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,33 +75,33 @@ func TestConn_getString(t *testing.T) {
|
||||
|
||||
ptr := db.newString("")
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Error("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
str := "sqlite3" + "\000 drop this"
|
||||
ptr = db.newString(str)
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Fatal("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
want := "sqlite3"
|
||||
if got := db.getString(ptr, math.MaxUint32); want != got {
|
||||
t.Errorf("want %q got %q", want, got)
|
||||
if got := db.getString(ptr, math.MaxUint32); got != want {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
if got := db.getString(ptr, 0); got != "" {
|
||||
t.Errorf("want empty got %q", got)
|
||||
t.Errorf("got %q, want empty", got)
|
||||
}
|
||||
|
||||
func() {
|
||||
defer func() { _ = recover() }()
|
||||
db.getString(ptr, uint32(len(want)/2))
|
||||
t.Errorf("should have panicked")
|
||||
t.Error("should have panicked")
|
||||
}()
|
||||
|
||||
func() {
|
||||
defer func() { _ = recover() }()
|
||||
db.getString(0, math.MaxUint32)
|
||||
t.Errorf("should have panicked")
|
||||
t.Error("should have panicked")
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func TestConn_free(t *testing.T) {
|
||||
|
||||
ptr := db.new(0)
|
||||
if ptr == 0 {
|
||||
t.Errorf("want a pointer got nullptr")
|
||||
t.Error("got nullptr, want a pointer")
|
||||
}
|
||||
|
||||
db.free(ptr)
|
||||
|
||||
@@ -34,10 +34,10 @@ func TestOpen_dir(t *testing.T) {
|
||||
t.Fatal("want sqlite3.Error")
|
||||
}
|
||||
if serr.Code != sqlite3.CANTOPEN {
|
||||
t.Fatal("want sqlite3.CANTOPEN")
|
||||
t.Error("want sqlite3.CANTOPEN")
|
||||
}
|
||||
if got := err.Error(); got != "sqlite3: unable to open database file" {
|
||||
t.Fatal("got message: ", got)
|
||||
t.Error("got message: ", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,17 +69,17 @@ func testOpen(t *testing.T, name string) {
|
||||
idx := 0
|
||||
for ; stmt.Step(); idx++ {
|
||||
if ids[idx] != stmt.ColumnInt(0) {
|
||||
t.Errorf("want %d got %d", ids[idx], stmt.ColumnInt(0))
|
||||
t.Errorf("got %d, want %d", stmt.ColumnInt(0), ids[idx])
|
||||
}
|
||||
if names[idx] != stmt.ColumnText(1) {
|
||||
t.Errorf("want %q got %q", names[idx], stmt.ColumnText(1))
|
||||
t.Errorf("got %q, want %q", stmt.ColumnText(1), names[idx])
|
||||
}
|
||||
}
|
||||
if err := stmt.Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if idx != 3 {
|
||||
t.Errorf("want %d rows got %d", len(ids), idx)
|
||||
t.Errorf("got %d rows, want %d", idx, len(ids))
|
||||
}
|
||||
|
||||
err = stmt.Close()
|
||||
|
||||
126
vfs_test.go
126
vfs_test.go
@@ -3,7 +3,11 @@ package sqlite3
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -14,40 +18,35 @@ func Test_vfsLocaltime(t *testing.T) {
|
||||
memory := make(MockMemory, 128)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
memory.Write(0, []byte("zero"))
|
||||
|
||||
rc := vfsLocaltime(context.TODO(), module, 0, 4)
|
||||
if rc != 0 {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
epoch := time.Unix(0, 0)
|
||||
if z, _ := memory.Read(0, 4); !bytes.Equal(z, []byte("zero")) {
|
||||
t.Fatal("overwrote zero address")
|
||||
}
|
||||
if s, _ := memory.ReadUint32Le(4 + 0*4); int(s) != epoch.Second() {
|
||||
t.Fatal("wrong second")
|
||||
t.Error("wrong second")
|
||||
}
|
||||
if m, _ := memory.ReadUint32Le(4 + 1*4); int(m) != epoch.Minute() {
|
||||
t.Fatal("wrong minute")
|
||||
t.Error("wrong minute")
|
||||
}
|
||||
if h, _ := memory.ReadUint32Le(4 + 2*4); int(h) != epoch.Hour() {
|
||||
t.Fatal("wrong hour")
|
||||
t.Error("wrong hour")
|
||||
}
|
||||
if d, _ := memory.ReadUint32Le(4 + 3*4); int(d) != epoch.Day() {
|
||||
t.Fatal("wrong day")
|
||||
t.Error("wrong day")
|
||||
}
|
||||
if m, _ := memory.ReadUint32Le(4 + 4*4); time.Month(1+m) != epoch.Month() {
|
||||
t.Fatal("wrong month")
|
||||
t.Error("wrong month")
|
||||
}
|
||||
if y, _ := memory.ReadUint32Le(4 + 5*4); 1900+int(y) != epoch.Year() {
|
||||
t.Fatal("wrong year")
|
||||
t.Error("wrong year")
|
||||
}
|
||||
if w, _ := memory.ReadUint32Le(4 + 6*4); time.Weekday(w) != epoch.Weekday() {
|
||||
t.Fatal("wrong weekday")
|
||||
t.Error("wrong weekday")
|
||||
}
|
||||
if d, _ := memory.ReadUint32Le(4 + 7*4); int(d) != epoch.YearDay()-1 {
|
||||
t.Fatal("wrong yearday")
|
||||
t.Error("wrong yearday")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,24 +54,18 @@ func Test_vfsRandomness(t *testing.T) {
|
||||
memory := make(MockMemory, 128)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
memory.Write(0, []byte("zero"))
|
||||
|
||||
rand.Seed(0)
|
||||
rc := vfsRandomness(context.TODO(), module, 0, 16, 4)
|
||||
if rc != 16 {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
if z, _ := memory.Read(0, 4); !bytes.Equal(z, []byte("zero")) {
|
||||
t.Fatal("overwrote zero address")
|
||||
}
|
||||
|
||||
var want [16]byte
|
||||
rand.Seed(0)
|
||||
rand.Read(want[:])
|
||||
|
||||
if got, _ := memory.Read(4, 16); !bytes.Equal(got, want[:]) {
|
||||
t.Fatalf("got %q, want %q", got, want)
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +79,7 @@ func Test_vfsSleep(t *testing.T) {
|
||||
|
||||
want := 123456 * time.Microsecond
|
||||
if got := time.Since(start); got < want {
|
||||
t.Fatalf("got %v, want %v", got, want)
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,20 +87,15 @@ func Test_vfsCurrentTime(t *testing.T) {
|
||||
memory := make(MockMemory, 128)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
memory.Write(0, []byte("zero"))
|
||||
|
||||
now := time.Now()
|
||||
rc := vfsCurrentTime(context.TODO(), module, 0, 4)
|
||||
if rc != 0 {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
if z, _ := memory.Read(0, 4); !bytes.Equal(z, []byte("zero")) {
|
||||
t.Fatal("overwrote zero address")
|
||||
}
|
||||
want := julianday.Float(now)
|
||||
if got, _ := memory.ReadFloat64Le(4); float32(got) != float32(want) {
|
||||
t.Fatalf("got %v, want %v", got, want)
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +103,6 @@ func Test_vfsCurrentTime64(t *testing.T) {
|
||||
memory := make(MockMemory, 128)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
memory.Write(0, []byte("zero"))
|
||||
|
||||
now := time.Now()
|
||||
time.Sleep(time.Millisecond)
|
||||
rc := vfsCurrentTime64(context.TODO(), module, 0, 4)
|
||||
@@ -124,12 +110,86 @@ func Test_vfsCurrentTime64(t *testing.T) {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
if z, _ := memory.Read(0, 4); !bytes.Equal(z, []byte("zero")) {
|
||||
t.Fatal("overwrote zero address")
|
||||
}
|
||||
day, nsec := julianday.Date(now)
|
||||
want := day*86_400_000 + nsec/1_000_000
|
||||
if got, _ := memory.ReadUint64Le(4); int64(got)-want > 100 {
|
||||
t.Fatalf("got %v, want %v", got, want)
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_vfsFullPathname(t *testing.T) {
|
||||
memory := make(MockMemory, 128+_MAX_PATHNAME)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
memory.Write(4, []byte{'.', 0})
|
||||
|
||||
rc := vfsFullPathname(context.TODO(), module, 0, 4, 0, 8)
|
||||
if rc != uint32(CANTOPEN_FULLPATH) {
|
||||
t.Errorf("returned %d, want %d", rc, CANTOPEN_FULLPATH)
|
||||
}
|
||||
|
||||
rc = vfsFullPathname(context.TODO(), module, 0, 4, _MAX_PATHNAME, 8)
|
||||
if rc != _OK {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
want, _ := filepath.Abs(".")
|
||||
if got := getString(&memory, 8, _MAX_PATHNAME); got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_vfsDelete(t *testing.T) {
|
||||
memory := make(MockMemory, 128+_MAX_PATHNAME)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
os.CreateTemp("", "sqlite3")
|
||||
file, err := os.CreateTemp("", "sqlite3-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
name := file.Name()
|
||||
defer os.RemoveAll(name)
|
||||
file.Close()
|
||||
|
||||
memory.Write(4, []byte(name))
|
||||
|
||||
rc := vfsDelete(context.TODO(), module, 0, 4, 1)
|
||||
if rc != _OK {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(name); !errors.Is(err, fs.ErrNotExist) {
|
||||
t.Error("did not delete the file")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_vfsAccess(t *testing.T) {
|
||||
memory := make(MockMemory, 128+_MAX_PATHNAME)
|
||||
module := &MockModule{&memory}
|
||||
|
||||
os.CreateTemp("", "sqlite3")
|
||||
dir, err := os.MkdirTemp("", "sqlite3-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
memory.Write(8, []byte(dir))
|
||||
|
||||
rc := vfsAccess(context.TODO(), module, 0, 8, ACCESS_EXISTS, 4)
|
||||
if rc != _OK {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
if got, ok := memory.ReadByte(4); !ok && got != 1 {
|
||||
t.Error("directory did not exist")
|
||||
}
|
||||
|
||||
rc = vfsAccess(context.TODO(), module, 0, 8, ACCESS_READWRITE, 4)
|
||||
if rc != _OK {
|
||||
t.Fatal("returned", rc)
|
||||
}
|
||||
if got, ok := memory.ReadByte(4); !ok && got != 1 {
|
||||
t.Error("can't access directory")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user