summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2024-10-26 15:47:57 -0300
committerEuAndreh <eu@euandre.org>2024-10-26 16:47:14 -0300
commitda12c61343f988a6f19f65bf7be331298bc1cca8 (patch)
treed62b50894858e7099a68bf5de362a2c267b47bb9
parentMakefile: "var version" -> "const Version" (diff)
downloadpapod-da12c61343f988a6f19f65bf7be331298bc1cca8.tar.gz
papod-da12c61343f988a6f19f65bf7be331298bc1cca8.tar.xz
Big bundle commit: adjust build project skeleton; include uncommitted code
There was some code that was being slowly tweaked as I'd work or related things on other repositories that wasn't committed step by step, and that now I'd rather include all as a single changeset, single there weren't really separated stages on how it was developed. Other than that, this commit includes adjustments on dependencies API usage, as they changed during my work on them, and adjustments on the build and test system, as I improved how they worked also during work on other projects. As of this commit, the code compiles and the tests pass. I can't recall if this was true before this commit, but it is true now.
-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