mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-04 23:42:40 +08:00
Add TestThread3 (does not yet pass). Updates #15.
modified: Makefile modified: all_test.go modified: generator.go modified: internal/bin/bin_linux_386.go modified: internal/bin/bin_linux_amd64.go new file: internal/threadtest3/threadtest3_linux_386.go new file: internal/threadtest3/threadtest3_linux_amd64.go
This commit is contained in:
2
Makefile
2
Makefile
@@ -20,7 +20,7 @@ all: editor
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
go clean
|
go clean
|
||||||
rm -f *~ *.test *.out test.db testdb-* tt4-test*.db*
|
rm -f *~ *.test *.out test.db* tt4-test*.db*
|
||||||
|
|
||||||
cover:
|
cover:
|
||||||
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
|
||||||
|
115
all_test.go
115
all_test.go
@@ -484,7 +484,7 @@ func TestThread2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThread4(t *testing.T) {
|
func TestThread3(t *testing.T) {
|
||||||
dir, err := ioutil.TempDir("", "sqlite-test-")
|
dir, err := ioutil.TempDir("", "sqlite-test-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -511,36 +511,107 @@ func TestThread4(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := []string{"build", "-o", "threadtest4"}
|
s := []string{"build", "-o", "threadtest3"}
|
||||||
if *memTrace {
|
if *memTrace {
|
||||||
s = append(s, "-tags", "memory.trace", "-race")
|
s = append(s, "-tags", "memory.trace", "-race")
|
||||||
}
|
}
|
||||||
if out, err := exec.Command("go", append(s, "github.com/cznic/sqlite/internal/threadtest4")...).CombinedOutput(); err != nil {
|
if out, err := exec.Command("go", append(s, "github.com/cznic/sqlite/internal/threadtest3")...).CombinedOutput(); err != nil {
|
||||||
t.Fatalf("go build mptest: %s\n%s", err, out)
|
t.Fatalf("go build mptest: %s\n%s", err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opts := range [][]string{
|
for _, opts := range [][]string{
|
||||||
{},
|
{"walthread1"},
|
||||||
{"-wal"},
|
{"walthread2"},
|
||||||
{"-serialized"},
|
{"walthread3"},
|
||||||
{"-serialized", "-wal"},
|
{"walthread4"},
|
||||||
{"--multithread"},
|
{"walthread5"},
|
||||||
{"--multithread", "-wal"},
|
{"cgt_pager_1"},
|
||||||
{"--multithread", "-serialized"},
|
{"dynamic_triggers"},
|
||||||
{"--multithread", "-serialized", "-wal"},
|
{"checkpoint_starvation_1"},
|
||||||
|
{"checkpoint_starvation_2"},
|
||||||
|
{"create_drop_index_1"},
|
||||||
|
{"lookaside1"},
|
||||||
|
{"vacuum1"},
|
||||||
|
{"stress1"},
|
||||||
|
{"stress2"},
|
||||||
} {
|
} {
|
||||||
for i := 2; i <= 10; i++ {
|
out, err := exec.Command("./threadtest3", opts...).CombinedOutput()
|
||||||
out, err := exec.Command("./threadtest4", append(opts, strconv.Itoa(i))...).CombinedOutput()
|
dbg("%v\n%s", opts, out)
|
||||||
t.Logf("%v: %v\n%s", i, opts, out)
|
t.Logf("%v\n%s", opts, out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Contains(out, []byte("fault address")) ||
|
if bytes.Contains(out, []byte("fault address")) ||
|
||||||
bytes.Contains(out, []byte("data race")) ||
|
bytes.Contains(out, []byte("data race")) ||
|
||||||
bytes.Contains(out, []byte("RACE")) {
|
bytes.Contains(out, []byte("RACE")) {
|
||||||
t.Fatal("fault")
|
t.Fatal("fault")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestThread4(t *testing.T) {
|
||||||
|
cases := 0
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
dir, err := ioutil.TempDir("", "sqlite-test-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := os.RemoveAll(dir); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := os.Chdir(wd); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := os.Chdir(dir); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := []string{"build", "-o", "threadtest4"}
|
||||||
|
if *memTrace {
|
||||||
|
s = append(s, "-tags", "memory.trace", "-race")
|
||||||
|
}
|
||||||
|
if out, err := exec.Command("go", append(s, "github.com/cznic/sqlite/internal/threadtest4")...).CombinedOutput(); err != nil {
|
||||||
|
t.Fatalf("go build mptest: %s\n%s", err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opts := range [][]string{
|
||||||
|
{},
|
||||||
|
{"-wal"},
|
||||||
|
{"-serialized"},
|
||||||
|
{"-serialized", "-wal"},
|
||||||
|
{"--multithread"},
|
||||||
|
{"--multithread", "-wal"},
|
||||||
|
{"--multithread", "-serialized"},
|
||||||
|
{"--multithread", "-serialized", "-wal"},
|
||||||
|
} {
|
||||||
|
for j := 2; j <= 20; j++ {
|
||||||
|
out, err := exec.Command("./threadtest4", append(opts, strconv.Itoa(j))...).CombinedOutput()
|
||||||
|
t.Logf("%v %v: %v\n%s", i, j, opts, out)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Contains(out, []byte("fault address")) ||
|
||||||
|
bytes.Contains(out, []byte("data race")) ||
|
||||||
|
bytes.Contains(out, []byte("RACE")) {
|
||||||
|
t.Fatalf("case %v: fault", cases)
|
||||||
|
}
|
||||||
|
cases++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Logf("cases: %v", cases)
|
||||||
|
}
|
||||||
|
55
generator.go
55
generator.go
@@ -76,6 +76,8 @@ func ftrace(s string, args ...interface{}) {
|
|||||||
fmt.Fprintf(os.Stderr, "# %%s:%%d: %%v\n", path.Base(fn), fl, fmt.Sprintf(s, args...))
|
fmt.Fprintf(os.Stderr, "# %%s:%%d: %%v\n", path.Base(fn), fl, fmt.Sprintf(s, args...))
|
||||||
os.Stderr.Sync()
|
os.Stderr.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Xsqlite3PendingByte() int32 { return _sqlite3PendingByte }
|
||||||
`
|
`
|
||||||
|
|
||||||
prologueTest = `// Code generated by ccgo. DO NOT EDIT.
|
prologueTest = `// Code generated by ccgo. DO NOT EDIT.
|
||||||
@@ -113,6 +115,9 @@ func main() {
|
|||||||
#define SQLITE_ENABLE_API_ARMOR 1
|
#define SQLITE_ENABLE_API_ARMOR 1
|
||||||
#define SQLITE_USE_URI 1
|
#define SQLITE_USE_URI 1
|
||||||
#define SQLITE_WITHOUT_MSIZE 1
|
#define SQLITE_WITHOUT_MSIZE 1
|
||||||
|
|
||||||
|
int sqlite3PendingByte;
|
||||||
|
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -536,6 +541,54 @@ func threadTest(n int) {
|
|||||||
unconvert(dst)
|
unconvert(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func threadTest3() {
|
||||||
|
n := 3
|
||||||
|
repo := findRepo(sqliteRepo)
|
||||||
|
if repo == "" {
|
||||||
|
log.Fatalf("repository not found: %v", sqliteRepo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlitePth := filepath.Join(repo, "sqlite-amalgamation-"+version)
|
||||||
|
pth := filepath.Join(repo, "sqlite-src-"+version, "test")
|
||||||
|
tag := fmt.Sprintf("threadtest%v", n)
|
||||||
|
test := filepath.Join(pth, tag+".c")
|
||||||
|
_, src := build(
|
||||||
|
defines,
|
||||||
|
[][]string{
|
||||||
|
{filepath.Join(sqlitePth, "sqlite3.c")},
|
||||||
|
{filepath.Join(repo, "sqlite-src-"+version, "src", "test_multiplex.c")},
|
||||||
|
{test},
|
||||||
|
},
|
||||||
|
[]string{"bin"},
|
||||||
|
cc.EnableAnonymousStructFields(),
|
||||||
|
cc.IncludePaths([]string{".", sqlitePth, filepath.Join(repo, "sqlite-src-"+version, "src")}),
|
||||||
|
)
|
||||||
|
|
||||||
|
var b bytes.Buffer
|
||||||
|
fmt.Fprintf(&b, prologueTest, tidyComments(header(test)))
|
||||||
|
b.Write(src)
|
||||||
|
b2, err := format.Source(b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
b2 = b.Bytes()
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join("internal", tag), 0775); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Join("testdata", tag), 0775); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst := fmt.Sprintf(filepath.Join("internal", tag, tag+"_%s_%s.go"), runtime.GOOS, runtime.GOARCH)
|
||||||
|
b2 = bytes.Replace(b2, []byte("Xsqlite3PendingByte"), []byte("bin.Xsqlite3PendingByte()"), -1)
|
||||||
|
if err := ioutil.WriteFile(dst, b2, 0664); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
unconvert(dst)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetFlags(log.Lshortfile | log.Lmicroseconds)
|
log.SetFlags(log.Lshortfile | log.Lmicroseconds)
|
||||||
var err error
|
var err error
|
||||||
@@ -549,6 +602,6 @@ func main() {
|
|||||||
mpTest()
|
mpTest()
|
||||||
threadTest(1)
|
threadTest(1)
|
||||||
threadTest(2)
|
threadTest(2)
|
||||||
// threadTest(3) depends on unexported function.
|
threadTest3()
|
||||||
threadTest(4)
|
threadTest(4)
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,8 @@ func ftrace(s string, args ...interface{}) {
|
|||||||
os.Stderr.Sync()
|
os.Stderr.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Xsqlite3PendingByte() int32 { return _sqlite3PendingByte }
|
||||||
|
|
||||||
const (
|
const (
|
||||||
XFTS5_TOKENIZE_AUX = 8
|
XFTS5_TOKENIZE_AUX = 8
|
||||||
XFTS5_TOKENIZE_DOCUMENT = 4
|
XFTS5_TOKENIZE_DOCUMENT = 4
|
||||||
|
@@ -70,6 +70,8 @@ func ftrace(s string, args ...interface{}) {
|
|||||||
os.Stderr.Sync()
|
os.Stderr.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Xsqlite3PendingByte() int32 { return _sqlite3PendingByte }
|
||||||
|
|
||||||
const (
|
const (
|
||||||
XFTS5_TOKENIZE_AUX = 8
|
XFTS5_TOKENIZE_AUX = 8
|
||||||
XFTS5_TOKENIZE_DOCUMENT = 4
|
XFTS5_TOKENIZE_DOCUMENT = 4
|
||||||
|
6687
internal/threadtest3/threadtest3_linux_386.go
Normal file
6687
internal/threadtest3/threadtest3_linux_386.go
Normal file
File diff suppressed because one or more lines are too long
6687
internal/threadtest3/threadtest3_linux_amd64.go
Normal file
6687
internal/threadtest3/threadtest3_linux_amd64.go
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user