diff options
-rw-r--r-- | .gitignore | 10 | ||||
-rw-r--r-- | Makefile | 116 | ||||
-rw-r--r-- | deps.mk | 57 | ||||
-rw-r--r-- | go.mod | 8 | ||||
-rw-r--r-- | go.sum | 2 | ||||
-rwxr-xr-x | mkdeps.sh | 25 | ||||
-rw-r--r-- | src/papod.go | 308 | ||||
l--------- | tests/benchmarks/join-leave/main.go | 1 | ||||
-rw-r--r-- | tests/benchmarks/join-leave/papod.go | 23 | ||||
l--------- | tests/functional/multiple-channels-and-users/main.go | 1 | ||||
-rw-r--r-- | tests/functional/multiple-channels-and-users/papod.go | 12 | ||||
l--------- | tests/fuzz/api-check/main.go | 1 | ||||
-rw-r--r-- | tests/fuzz/api-check/papod.go | 34 | ||||
-rw-r--r-- | tests/papod.go | 124 | ||||
-rw-r--r-- | tests/queries.sql | 0 |
15 files changed, 579 insertions, 143 deletions
@@ -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/ @@ -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: @@ -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 @@ -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 @@ -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= @@ -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 |