summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore10
-rw-r--r--Makefile116
-rw-r--r--deps.mk57
-rw-r--r--go.mod8
-rw-r--r--go.sum2
-rwxr-xr-xmkdeps.sh25
-rw-r--r--src/papod.go308
l---------tests/benchmarks/join-leave/main.go1
-rw-r--r--tests/benchmarks/join-leave/papod.go23
l---------tests/functional/multiple-channels-and-users/main.go1
-rw-r--r--tests/functional/multiple-channels-and-users/papod.go12
l---------tests/fuzz/api-check/main.go1
-rw-r--r--tests/fuzz/api-check/papod.go34
-rw-r--r--tests/papod.go124
-rw-r--r--tests/queries.sql0
15 files changed, 579 insertions, 143 deletions
diff --git a/.gitignore b/.gitignore
index c096254..1b9f827 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,15 @@
/src/version.go
/*.bin
-/*.db
+/*.db*
/src/*.a
/src/*.bin
/tests/*.a
/tests/*.bin
+/tests/functional/*/*.a
+/tests/functional/*/*.bin
+/tests/fuzz/*/*.a
+/tests/fuzz/*/*.bin
+/tests/benchmarks/*/*.a
+/tests/benchmarks/*/*.bin
+/tests/benchmarks/*/*.txt
+/tests/fuzz/corpus/
diff --git a/Makefile b/Makefile
index cf73f0a..66066d2 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ MANDIR = $(SHAREDIR)/man
EXEC = ./
## Where to store the installation. Empty by default.
DESTDIR =
-LDLIBS = -lsqlite3
+LDLIBS = --static -lscrypt-kdf -lsqlite3 -lm
GOCFLAGS = -I $(GOLIBDIR)
GOLDFLAGS = -L $(GOLIBDIR)
@@ -26,17 +26,26 @@ GOLDFLAGS = -L $(GOLIBDIR)
.SUFFIXES:
.SUFFIXES: .go .a .bin .bin-check
+.go.a:
+ go tool compile $(GOCFLAGS) -I $(@D) -o $@ -p $(*F) \
+ `find $< $$(if [ $(*F) != main ]; then \
+ echo src/$(NAME).go src/version.go; fi) | uniq`
+
+.a.bin:
+ go tool link $(GOLDFLAGS) -L $(@D) -o $@ --extldflags '$(LDLIBS)' $<
+
all:
include deps.mk
-objects = \
- src/$(NAME).a \
- src/main.a \
- tests/$(NAME).a \
- tests/main.a \
+libs.a = $(libs.go:.go=.a)
+mains.a = $(mains.go:.go=.a)
+mains.bin = $(mains.go:.go=.bin)
+functional-tests/lib.a = $(functional-tests/lib.go:.go=.a)
+fuzz-targets/lib.a = $(fuzz-targets/lib.go:.go=.a)
+benchmarks/lib.a = $(benchmarks/lib.go:.go=.a)
sources = \
src/$(NAME).go \
@@ -46,17 +55,18 @@ sources = \
derived-assets = \
src/version.go \
- $(objects) \
- src/main.bin \
- tests/main.bin \
+ $(libs.a) \
+ $(mains.a) \
+ $(mains.bin) \
$(NAME).bin \
side-assets = \
- papod.db \
- papod.public.socket \
- papod.command.socket \
- wscat.socket \
- glaze.socket \
+ $(NAME).db* \
+ tests/functional/*/*.go.db* \
+ tests/fuzz/corpus/ \
+ tests/benchmarks/*/main.txt \
+ $(NAME).public.socket \
+ $(NAME).command.socket \
@@ -65,40 +75,35 @@ side-assets = \
all: $(derived-assets)
-$(objects): Makefile
-
-src/$(NAME).a: src/$(NAME).go src/version.go
- go tool compile $(GOCFLAGS) -o $@ -p $(*F) -I $(@D) $*.go src/version.go
+$(libs.a): Makefile deps.mk
+$(libs.a): src/$(NAME).go src/version.go
-src/main.a: src/main.go src/$(NAME).a
-tests/main.a: tests/main.go tests/$(NAME).a
-src/main.a tests/main.a:
- go tool compile $(GOCFLAGS) -o $@ -p $(*F) -I $(@D) $*.go
-tests/$(NAME).a: tests/$(NAME).go src/$(NAME).go src/version.go
- go tool compile $(GOCFLAGS) -o $@ -p $(*F) $*.go src/$(*F).go src/version.go
+$(fuzz-targets/lib.a):
+ go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \
+ $*.go src/$(NAME).go src/version.go
-src/main.bin: src/main.a
-tests/main.bin: tests/main.a
-src/main.bin tests/main.bin:
- go tool link $(GOLDFLAGS) -o $@ -L $(@D) --extldflags '$(LDLIBS)' $*.a
+src/version.go: Makefile
+ echo 'package $(NAME); const Version = "$(VERSION)"' > $@
$(NAME).bin: src/main.bin
ln -fs $? $@
-src/version.go: Makefile
- echo 'package $(NAME); const Version = "$(VERSION)"' > $@
+.PRECIOUS: tests/queries.sql
+tests/queries.sql: tests/main.bin ALWAYS
+ env TESTING_DUMP_SQL_QUERIES=1 $(EXEC)tests/main.bin | diff -U10 $@ -
tests.bin-check = \
- tests/main.bin-check \
+ tests/main.bin-check \
+ $(functional-tests/main.go:.go=.bin-check) \
-tests/main.bin-check: tests/main.bin
$(tests.bin-check):
$(EXEC)$*.bin
check-unit: $(tests.bin-check)
+check-unit: tests/queries.sql
integration-tests = \
@@ -111,6 +116,7 @@ $(integration-tests): ALWAYS
sh $@
check-integration: $(integration-tests)
+check-integration: fuzz
## Run all tests. Each test suite is isolated, so that a parallel
@@ -120,6 +126,26 @@ check: check-unit check-integration
+FUZZSEC=1
+fuzz-targets/main.bin-check = $(fuzz-targets/main.go:.go=.bin-check)
+$(fuzz-targets/main.bin-check):
+ $(EXEC)$*.bin --test.fuzztime=$(FUZZSEC)s \
+ --test.fuzz='.*' --test.fuzzcachedir=tests/fuzz/corpus
+
+fuzz: $(fuzz-targets/main.bin-check)
+
+
+
+benchmarks/main.bin-check = $(benchmarks/main.go:.go=.bin-check)
+$(benchmarks/main.bin-check):
+ printf '%s\n' '$(EXEC)$*.bin' > $*.txt
+ LANG=POSIX.UTF-8 time -p $(EXEC)$*.bin 2>> $*.txt
+ printf '%s\n' '$*.txt'
+
+bench: $(benchmarks/main.bin-check)
+
+
+
## Remove *all* derived artifacts produced during the build.
## A dedicated test asserts that this is always true.
clean:
@@ -148,30 +174,10 @@ uninstall:
'$(DESTDIR)$(SRCDIR)' \
-run-papod: $(NAME).bin
- rm -f papod.public.socket papod.command.socket
- ./$(NAME).bin
-
-run-wscat:
- rm -f wscat.socket
- wscat wscat.socket papod.public.socket
-
-run-glaze:
- rm -f glaze.socket
- glaze -P '/api/socket:wscat.socket' -P '*:src/static/' glaze.socket
-
-run-binder-web:
- binder localhost:4443 glaze.socket
-
-run-binder-ircd:
- binder localhost:6667 papod.public.socket
-
-## Run it locally, alongside its helper programs.
+## Run it locally.
run: all
- for c in wscat papod binder-web binder-ircd glaze; do \
- $(MAKE) run-$$c & \
- done; \
- wait
+ rm -f $(NAME).public.socket $(NAME).command.socket
+ ./$(NAME).bin
ALWAYS:
diff --git a/deps.mk b/deps.mk
index e69de29..432fe5b 100644
--- a/deps.mk
+++ b/deps.mk
@@ -0,0 +1,57 @@
+libs.go = \
+ src/papod.go \
+ tests/benchmarks/join-leave/papod.go \
+ tests/functional/multiple-channels-and-users/papod.go \
+ tests/fuzz/api-check/papod.go \
+ tests/papod.go \
+
+mains.go = \
+ src/main.go \
+ tests/benchmarks/join-leave/main.go \
+ tests/functional/multiple-channels-and-users/main.go \
+ tests/fuzz/api-check/main.go \
+ tests/main.go \
+
+functional-tests/libs.go = \
+ tests/functional/multiple-channels-and-users/papod.go \
+
+functional-tests/main.go = \
+ tests/functional/multiple-channels-and-users/main.go \
+
+fuzz-targets/lib.go = \
+ tests/fuzz/api-check/papod.go \
+
+fuzz-targets/main.go = \
+ tests/fuzz/api-check/main.go \
+
+benchmarks/lib.go = \
+ tests/benchmarks/join-leave/papod.go \
+
+benchmarks/main.go = \
+ tests/benchmarks/join-leave/main.go \
+
+src/main.a: src/main.go
+src/papod.a: src/papod.go
+tests/benchmarks/join-leave/main.a: tests/benchmarks/join-leave/main.go
+tests/benchmarks/join-leave/papod.a: tests/benchmarks/join-leave/papod.go
+tests/functional/multiple-channels-and-users/main.a: tests/functional/multiple-channels-and-users/main.go
+tests/functional/multiple-channels-and-users/papod.a: tests/functional/multiple-channels-and-users/papod.go
+tests/fuzz/api-check/main.a: tests/fuzz/api-check/main.go
+tests/fuzz/api-check/papod.a: tests/fuzz/api-check/papod.go
+tests/main.a: tests/main.go
+tests/papod.a: tests/papod.go
+src/main.bin: src/main.a
+tests/benchmarks/join-leave/main.bin: tests/benchmarks/join-leave/main.a
+tests/functional/multiple-channels-and-users/main.bin: tests/functional/multiple-channels-and-users/main.a
+tests/fuzz/api-check/main.bin: tests/fuzz/api-check/main.a
+tests/main.bin: tests/main.a
+src/main.bin-check: src/main.bin
+tests/benchmarks/join-leave/main.bin-check: tests/benchmarks/join-leave/main.bin
+tests/functional/multiple-channels-and-users/main.bin-check: tests/functional/multiple-channels-and-users/main.bin
+tests/fuzz/api-check/main.bin-check: tests/fuzz/api-check/main.bin
+tests/main.bin-check: tests/main.bin
+src/main.a: src/$(NAME).a
+tests/benchmarks/join-leave/main.a: tests/benchmarks/join-leave/$(NAME).a
+tests/functional/multiple-channels-and-users/main.a: tests/functional/multiple-channels-and-users/$(NAME).a
+tests/fuzz/api-check/main.a: tests/fuzz/api-check/$(NAME).a
+tests/main.a: tests/$(NAME).a
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 36de052..0000000
--- a/go.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-module euandre.org/papod
-
-go 1.21.5
-
-require github.com/mattn/go-sqlite3 v1.14.22
-
-require euandre.org/gobang v0.1.0
-replace euandre.org/gobang => ../gobang
diff --git a/go.sum b/go.sum
deleted file mode 100644
index e8d092a..0000000
--- a/go.sum
+++ /dev/null
@@ -1,2 +0,0 @@
-github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
-github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
diff --git a/mkdeps.sh b/mkdeps.sh
index e5606ff..b1c61b3 100755
--- a/mkdeps.sh
+++ b/mkdeps.sh
@@ -2,3 +2,28 @@
set -eu
export LANG=POSIX.UTF-8
+
+
+libs() {
+ find src tests -name '*.go' | grep -v '/main\.go$' |
+ grep -v '/version\.go$'
+}
+
+mains() {
+ find src tests -name '*.go' | grep '/main\.go$'
+}
+
+libs | varlist 'libs.go'
+mains | varlist 'mains.go'
+
+find tests/functional/*/*.go -not -name main.go | varlist 'functional-tests/libs.go'
+find tests/functional/*/main.go | varlist 'functional-tests/main.go'
+find tests/fuzz/*/*.go -not -name main.go | varlist 'fuzz-targets/lib.go'
+find tests/fuzz/*/main.go | varlist 'fuzz-targets/main.go'
+find tests/benchmarks/*/*.go -not -name main.go | varlist 'benchmarks/lib.go'
+find tests/benchmarks/*/main.go | varlist 'benchmarks/main.go'
+
+{ libs; mains; } | sort | sed 's/^\(.*\)\.go$/\1.a:\t\1.go/'
+mains | sort | sed 's/^\(.*\)\.go$/\1.bin:\t\1.a/'
+mains | sort | sed 's/^\(.*\)\.go$/\1.bin-check:\t\1.bin/'
+mains | sort | sed 's|^\(.*\)/main\.go$|\1/main.a:\t\1/$(NAME).a|'
diff --git a/src/papod.go b/src/papod.go
index 05b1d8e..220ef55 100644
--- a/src/papod.go
+++ b/src/papod.go
@@ -18,12 +18,308 @@ import (
"sync"
"time"
+ "gracha"
+ "q"
+ // "golite"
+ "guuid"
g "gobang"
- "golite"
)
+type tablesT struct{
+ servers string
+ users string
+ channels string
+ channelEvents string
+}
+
+type queriesT struct{
+ addChannel func(string) error
+ eventsAfter func([]byte, func(eventT) error) error
+ addEvent func(string, string) error
+ close func() error
+}
+
+type eventT struct{
+ id int64
+}
+
+type PapoD struct{
+ queries queriesT
+ auth gracha.IAuth
+ queue q.IQueue
+}
+
+type consumerT struct{
+ topic string
+ handlerFn func(PapoD) func(q.Message) error
+}
+
+
+
+const (
+ NEW_CHANNEL_EVENT = "new-channel-event"
+
+ defaultPrefix = "papod"
+)
+
+
+
+func tablesFrom(prefix string) (tablesT, error) {
+ err := g.ValidateSQLTablePrefix(prefix)
+ if err != nil {
+ return tablesT{}, err
+ }
+
+ servers := prefix + "-servers"
+ users := prefix + "-users"
+ channels := prefix + "-channels"
+ channelEvents := prefix + "-channel-events"
+ return tablesT{
+ servers: servers,
+ users: users,
+ channels: channels,
+ channelEvents: channelEvents,
+ }, nil
+}
+
+func createTables(db *sql.DB, tables tablesT) error {
+ const tmpl = `
+ BEGIN TRANSACTION;
+ CREATE TABLE IF NOT EXISTS "%s" (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL DEFAULT (%s),
+ uuid BLOB NOT NULL UNIQUE,
+ name TEXT NOT NULL,
+ description TEXT NOT NULL,
+ public BOOLEAN NOT NULL,
+ metadata TEXT
+ );
+ CREATE TABLE IF NOT EXISTS "%s" (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL DEFAULT (%s),
+ uuid BLOB NOT NULL UNIQUE,
+ server_id INTEGER NOT NULL REFERENCES "%s"(id),
+ authuser_uuid BLOB NOT NULL UNIQUE,
+ human BOOLEAN NOT NULL,
+ visible BOOLEAN NOT NULL,
+ enabled BOOLEAN NOT NULL,
+ metadata TEXT
+ );
+ CREATE TABLE IF NOT EXISTS "%s" (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL DEFAULT (%s),
+ uuid BLOB NOT NULL UNIQUE,
+ server_id INTEGER NOT NULL REFERENCES "%s"(id),
+ name TEXT,
+ description TEXT,
+ virtual BOOLEAN NOT NULL,
+ metadata TEXT
+ );
+ -- FIXME: group conversations?
+ CREATE TABLE IF NOT EXISTS "%s" (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL DEFAULT (%s),
+ uuid BLOB NOT NULL UNIQUE,
+ channel_id INTEGER NOT NULL REFERENCES "%s"(id),
+ connection_id INTEGER NOT NULL
+ -- payload FIXME: vary by type?
+ );
+
+
+ -- FIXME:indexes
+ COMMIT TRANSACTION;
+ `
+ sql := fmt.Sprintf(
+ tmpl,
+ tables.servers,
+ g.SQLiteNow,
+ tables.users,
+ g.SQLiteNow,
+ tables.servers,
+ tables.channels,
+ g.SQLiteNow,
+ tables.servers,
+ tables.channelEvents,
+ g.SQLiteNow,
+ tables.channels,
+ )
+ fmt.Println(sql) ///
+
+ _, err := db.Exec(sql)
+ return err
+}
+
+func addChannelQuery(
+ db *sql.DB,
+ tables tablesT,
+) (func (string) error, func() error, error) {
+ const tmpl = `
+ `
+ sql := fmt.Sprintf(tmpl)
+ /// fmt.Println(sql) ///
+
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ fn := func(name string) error {
+ _, err := stmt.Exec(name)
+ return err
+ }
+
+ return fn, nil, nil
+}
+
+func eventEach(
+ stmt *sql.Stmt,
+ uuid []byte,
+ callback func(eventT) error,
+) error {
+ rows, err := stmt.Query(uuid)
+ if err != nil {
+ return err
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var event eventT
+ err = rows.Scan(
+ &event.id,
+ )
+ if err != nil {
+ return err
+ }
+
+ err = callback(event)
+ if err != nil {
+ return err
+ }
+ }
+
+ return rows.Err()
+}
+
+func eventsAfterQuery(
+ db *sql.DB,
+ tables tablesT,
+) (func ([]byte, func(eventT) error) error, func() error, error) {
+ const tmpl = `
+ -- INSERT
+ `
+ sql := fmt.Sprintf(tmpl)
+ /// fmt.Println(sql) ///
+
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ fn := func(uuid []byte, callback func(eventT) error) error {
+ return eventEach(stmt, uuid, callback)
+ }
+
+ return fn, stmt.Close, nil
+}
+
+func addEventQuery(
+ db *sql.DB,
+ tables tablesT,
+) (func (string, string) error, func() error, error) {
+ const tmpl = `
+ `
+ sql := fmt.Sprintf(tmpl)
+ /// fmt.Println(sql) ///
+
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ fn := func(type_ string, payload string) error {
+ _, err := stmt.Exec(type_, payload)
+ return err
+ }
+
+ return fn, stmt.Close, nil
+}
+
+func initDB(db *sql.DB, tables tablesT) (queriesT, error) {
+ createTablesErr := createTables(db, tables)
+ addChannel, addChannelClose, addChannelErr := addChannelQuery(db, tables)
+ eventsAfter, eventsAfterClose, eventsAfterErr := eventsAfterQuery(db, tables)
+ addEvent, addEventClose, addEventErr := addEventQuery(db, tables)
+
+ err := g.SomeError(
+ createTablesErr,
+ addChannelErr,
+ eventsAfterErr,
+ addEventErr,
+ )
+ if err != nil {
+ return queriesT{}, err
+ }
+
+ close := func() error {
+ return g.SomeFnError(
+ addChannelClose,
+ eventsAfterClose,
+ addEventClose,
+ )
+ }
+
+ return queriesT{
+ addChannel: addChannel,
+ eventsAfter: eventsAfter,
+ addEvent: addEvent,
+ close: close,
+ }, nil
+}
+
+func (papod PapoD) Close() error {
+ return papod.queries.close()
+}
+
+var consumers = []consumerT{
+}
+func registerConsumers(papod PapoD, consumers []consumerT) {
+ for _, consumer := range consumers {
+ papod.queue.Subscribe(
+ consumer.topic,
+ defaultPrefix + "-" + consumer.topic,
+ consumer.handlerFn(papod),
+ )
+ }
+}
+
+func NewWithPrefix(db *sql.DB, queue q.IQueue, prefix string) (PapoD, error) {
+ tables, err := tablesFrom(prefix)
+ if err != nil {
+ return PapoD{}, err
+ }
+
+ queries, err := initDB(db, tables)
+ if err != nil {
+ return PapoD{}, err
+ }
+
+ return PapoD{
+ queries: queries,
+ queue: queue,
+ }, nil
+}
+
+func New(db *sql.DB, queue q.IQueue) (PapoD, error) {
+ return NewWithPrefix(db, queue, defaultPrefix)
+}
+
+
+
+
+
+
// Global variables
@@ -48,8 +344,6 @@ var EmitWriteToClientError = g.MakeCounter("write-to-client")
const pingFrequency = time.Duration(30) * time.Second
const pongMaxLatency = time.Duration(5) * time.Second
-// type UUID string
-
type Channel struct {
}
@@ -196,7 +490,7 @@ func HandlePRIVMSG(ctx *Context, msg Message) {
defer stmt.Close()
ret, err := stmt.Exec(
- g.NewUUID().String(),
+ guuid.New().String(),
"FIXME",
"FIXME",
time.Now(),
@@ -497,7 +791,7 @@ func RunMigrations(db *sql.DB) {
func InitDB(databasePath string) *sql.DB {
db, err := sql.Open("sqlite3", databasePath)
g.FatalIf(err)
- RunMigrations(db)
+ // RunMigrations(db)
return db
}
@@ -505,8 +799,8 @@ func Init() {
g.Init(slog.Group(
"versions",
"gobang", g.Version,
- "golite", golite.Version,
- "this", version,
+ // "golite", golite.Version,
+ "this", Version,
))
SetEnvironmentVariables()
}
diff --git a/tests/benchmarks/join-leave/main.go b/tests/benchmarks/join-leave/main.go
new file mode 120000
index 0000000..f67563d
--- /dev/null
+++ b/tests/benchmarks/join-leave/main.go
@@ -0,0 +1 @@
+../../main.go \ No newline at end of file
diff --git a/tests/benchmarks/join-leave/papod.go b/tests/benchmarks/join-leave/papod.go
new file mode 100644
index 0000000..7bb69cc
--- /dev/null
+++ b/tests/benchmarks/join-leave/papod.go
@@ -0,0 +1,23 @@
+package papod
+
+import (
+ "flag"
+ "time"
+)
+
+
+
+var nFlag = flag.Int(
+ "n",
+ 1_000,
+ "The number of iterations to execute",
+)
+
+func MainTest() {
+ flag.Parse()
+ n := *nFlag
+
+ for i := 0; i < n; i++ {
+ time.Sleep(time.Millisecond * 1)
+ }
+}
diff --git a/tests/functional/multiple-channels-and-users/main.go b/tests/functional/multiple-channels-and-users/main.go
new file mode 120000
index 0000000..f67563d
--- /dev/null
+++ b/tests/functional/multiple-channels-and-users/main.go
@@ -0,0 +1 @@
+../../main.go \ No newline at end of file
diff --git a/tests/functional/multiple-channels-and-users/papod.go b/tests/functional/multiple-channels-and-users/papod.go
new file mode 100644
index 0000000..6f6a67b
--- /dev/null
+++ b/tests/functional/multiple-channels-and-users/papod.go
@@ -0,0 +1,12 @@
+package papod
+
+import (
+ g "gobang"
+)
+
+
+
+func MainTest() {
+ g.Testing("multiple users can join a channel", func() {
+ })
+}
diff --git a/tests/fuzz/api-check/main.go b/tests/fuzz/api-check/main.go
new file mode 120000
index 0000000..f67563d
--- /dev/null
+++ b/tests/fuzz/api-check/main.go
@@ -0,0 +1 @@
+../../main.go \ No newline at end of file
diff --git a/tests/fuzz/api-check/papod.go b/tests/fuzz/api-check/papod.go
new file mode 100644
index 0000000..edab81c
--- /dev/null
+++ b/tests/fuzz/api-check/papod.go
@@ -0,0 +1,34 @@
+package papod
+
+import (
+ "os"
+ "testing"
+ "testing/internal/testdeps"
+)
+
+
+
+func api(f *testing.F) {
+ f.Fuzz(func(t *testing.T, n int) {
+ if n > 1 {
+ if n < 2 {
+ t.Errorf("Failed n: %v\n", n)
+ }
+ }
+ })
+}
+
+
+
+func MainTest() {
+ fuzzTargets := []testing.InternalFuzzTarget{
+ { "api", api },
+ }
+
+ deps := testdeps.TestDeps{}
+ tests := []testing.InternalTest {}
+ benchmarks := []testing.InternalBenchmark{}
+ examples := []testing.InternalExample {}
+ m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples)
+ os.Exit(m.Run())
+}
diff --git a/tests/papod.go b/tests/papod.go
index af2a5f7..2d908f5 100644
--- a/tests/papod.go
+++ b/tests/papod.go
@@ -4,46 +4,42 @@ import (
"bufio"
"database/sql"
"errors"
- "os"
- "reflect"
"strings"
- "testing"
- "testing/internal/testdeps"
+ // "q"
g "gobang"
)
-func errorIf(t *testing.T, err error) {
- if err != nil {
- t.Errorf("Unexpected error: %#v\n", err)
- }
-}
-func errorIfNotI(t *testing.T, i int, err error) {
- if err == nil {
- t.Errorf("Expected error, got nil (i = %d)\n", i)
+func test_initDB() {
+ g.TestStart("initDB()")
+
+ /*
+ q := new(liteq.Queue)
+ sql.Register("sqliteq", liteq.MakeDriver(q))
+
+ db, err := sql.Open("sqliteq", "file:papod-test.db?mode=memory&cache=shared")
+ if err != nil {
+ panic(err)
}
-}
+ // defer db.Close()
-func assertEqualI(t *testing.T, i int, given any, expected any) {
- if !reflect.DeepEqual(given, expected) {
- t.Errorf("given != expected (i = %d)\n", i)
- t.Errorf("given: %#v\n", given)
- t.Errorf("expected: %#v\n", expected)
+ *q, err = liteq.New(db)
+ if err != nil {
+ panic(err)
}
-}
+ // defer q.Close()
-func assertEqual(t *testing.T, given any, expected any) {
- if !reflect.DeepEqual(given, expected) {
- t.Errorf("given != expected")
- t.Errorf("given: %#v\n", given)
- t.Errorf("expected: %#v\n", expected)
+ // _, err = New(db, *q)
+ // _, err = initDB(db,
+ if err != nil {
+ panic(err)
}
+ */
}
-
-func TestSplitOnCRLF(t *testing.T) {
+func test_SplitOnCRLF() {
type tableT struct {
input string
expected []string
@@ -83,7 +79,7 @@ func TestSplitOnCRLF(t *testing.T) {
},
}
- for i, entry := range table {
+ for _, entry := range table {
var given []string
scanner := bufio.NewScanner(strings.NewReader(entry.input))
scanner.Split(SplitOnCRLF)
@@ -92,12 +88,12 @@ func TestSplitOnCRLF(t *testing.T) {
}
err := scanner.Err()
- errorIf(t, err)
- assertEqualI(t, i, given, entry.expected)
+ g.TErrorIf(err)
+ g.TAssertEqual(given, entry.expected)
}
}
-func TestSplitOnRawMessage(t *testing.T) {
+func test_SplitOnRawMessage() {
type tableT struct {
input string
expected []string
@@ -114,7 +110,7 @@ func TestSplitOnRawMessage(t *testing.T) {
}
- for i, entry := range table {
+ for _, entry := range table {
var given []string
scanner := bufio.NewScanner(strings.NewReader(entry.input))
scanner.Split(SplitOnRawMessage)
@@ -123,12 +119,12 @@ func TestSplitOnRawMessage(t *testing.T) {
}
err := scanner.Err()
- errorIf(t, err)
- assertEqualI(t, i, given, entry.expected)
+ g.TErrorIf(err)
+ g.TAssertEqual(given, entry.expected)
}
}
-func TestParseMessageParams(t *testing.T) {
+func test_ParseMessageParams() {
type tableT struct {
input string
expected MessageParams
@@ -311,13 +307,13 @@ func TestParseMessageParams(t *testing.T) {
},
}
- for i, entry := range table {
+ for _, entry := range table {
given := ParseMessageParams(entry.input)
- assertEqualI(t, i, given, entry.expected)
+ g.TAssertEqual(given, entry.expected)
}
}
-func TestParseMessage(t *testing.T) {
+func test_ParseMessage() {
type tableTOK struct {
input string
expected Message
@@ -442,16 +438,16 @@ func TestParseMessage(t *testing.T) {
},
}}
- for i, entry := range tableOK {
+ for _, entry := range tableOK {
given, err := ParseMessage(entry.input)
- errorIf(t, err)
- assertEqualI(t, i, given, entry.expected)
+ g.TErrorIf(err)
+ g.TAssertEqual(given, entry.expected)
}
type tableErrorT struct {
input string
- expected error
+ expected error
}
parseErr := errors.New("Can't parse message")
tableError := []tableErrorT {
@@ -469,31 +465,31 @@ func TestParseMessage(t *testing.T) {
},
}
- for i, entry := range tableError {
+ for _, entry := range tableError {
_, given := ParseMessage(entry.input)
- assertEqualI(t, i, given, entry.expected)
+ g.TAssertEqual(given, entry.expected)
}
}
-func TestInitMigrations(t *testing.T) {
+func test_InitMigrations() {
const query = `SELECT filename FROM migrations;`
db, err := sql.Open("sqlite3", ":memory:")
g.FatalIf(err)
_, err = db.Query(query)
- assertEqual(t, err.Error(), "no such table: migrations")
+ g.TAssertEqual(err.Error(), "no such table: migrations")
for i := 0; i < 5; i++ {
InitMigrations(db)
rows, err := db.Query(query)
g.FatalIf(err)
- assertEqual(t, rows.Next(), false)
+ g.TAssertEqual(rows.Next(), false)
g.FatalIf(rows.Err())
}
}
-func TestPendingMigrations(t *testing.T) {
+func test_PendingMigrations() {
db, err := sql.Open("sqlite3", ":memory:")
g.FatalIf(err)
@@ -501,10 +497,10 @@ func TestPendingMigrations(t *testing.T) {
pending1 := PendingMigrations(db)
pending2 := PendingMigrations(db)
- assertEqual(t, pending1, pending2)
+ g.TAssertEqual(pending1, pending2)
}
-func TestRunMigrations(t *testing.T) {
+func test_RunMigrations() {
db, err := sql.Open("sqlite3", ":memory:")
g.FatalIf(err)
@@ -516,25 +512,13 @@ func TestRunMigrations(t *testing.T) {
func MainTest() {
- tests := []testing.InternalTest {
- { "TestSplitOnCRLF", TestSplitOnCRLF },
- { "TestSplitOnRawMessage", TestSplitOnRawMessage },
- { "TestParseMessageParams", TestParseMessageParams },
- { "TestParseMessage", TestParseMessage },
- { "TestInitMigrations", TestInitMigrations },
- { "TestPendingMigrations", TestPendingMigrations },
- { "TestRunMigrations", TestRunMigrations },
- }
-
- benchmarks := []testing.InternalBenchmark {}
- fuzzTargets := []testing.InternalFuzzTarget {}
- examples := []testing.InternalExample {}
- m := testing.MainStart(
- testdeps.TestDeps {},
- tests,
- benchmarks,
- fuzzTargets,
- examples,
- )
- os.Exit(m.Run())
+ test_initDB()
+ test_SplitOnCRLF()
+ test_SplitOnRawMessage()
+ test_ParseMessageParams()
+ test_ParseMessage()
+
+ // { "TestInitMigrations", TestInitMigrations },
+ // { "TestPendingMigrations", TestPendingMigrations },
+ // { "TestRunMigrations", TestRunMigrations },
}
diff --git a/tests/queries.sql b/tests/queries.sql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/queries.sql