Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb67f2b417 |
+5
-2
@@ -32,9 +32,12 @@ RUN go mod download
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css web/dist/app.js
|
RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css web/dist/app.js
|
||||||
# -p 4 because test runs on a shared build host cap their parallelism.
|
# -p 4 because test runs on a shared build host cap their parallelism.
|
||||||
RUN go test -p 4 -timeout 90s -race -cover ./... || \
|
# -race also turns on Go's unsafe-pointer checks (checkptr) in every
|
||||||
|
# package. In modernc.org, SQLite machine-translated from C, they doubled
|
||||||
|
# the test time, so they are off there and stay on everywhere else.
|
||||||
|
RUN go test -p 4 -timeout 90s -race -gcflags='modernc.org/...=-d=checkptr=0' -cover ./... || \
|
||||||
{ echo "--- Rerunning with -v for details ---"; \
|
{ echo "--- Rerunning with -v for details ---"; \
|
||||||
go test -p 4 -timeout 90s -race -v ./...; exit 1; }
|
go test -p 4 -timeout 90s -race -gcflags='modernc.org/...=-d=checkptr=0' -v ./...; exit 1; }
|
||||||
|
|
||||||
# Build stage. Nothing is wanted from either phase above; the copies
|
# Build stage. Nothing is wanted from either phase above; the copies
|
||||||
# are what make BuildKit build them first, so this stage cannot run
|
# are what make BuildKit build them first, so this stage cannot run
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ package handlers_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -25,7 +22,6 @@ import (
|
|||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"go.uber.org/fx/fxtest"
|
"go.uber.org/fx/fxtest"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"modernc.org/sqlite"
|
|
||||||
"sneak.berlin/go/neoirc/internal/broker"
|
"sneak.berlin/go/neoirc/internal/broker"
|
||||||
"sneak.berlin/go/neoirc/internal/config"
|
"sneak.berlin/go/neoirc/internal/config"
|
||||||
"sneak.berlin/go/neoirc/internal/db"
|
"sneak.berlin/go/neoirc/internal/db"
|
||||||
@@ -41,76 +37,9 @@ import (
|
|||||||
"sneak.berlin/go/neoirc/pkg/irc"
|
"sneak.berlin/go/neoirc/pkg/irc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// templateDBURL names the in-memory database TestMain migrates once
|
|
||||||
// and every test copies; it lasts while TestMain holds it open.
|
|
||||||
const templateDBURL = "file:template?mode=memory&cache=shared"
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
db.SetBcryptCost(bcrypt.MinCost)
|
db.SetBcryptCost(bcrypt.MinCost)
|
||||||
|
os.Exit(m.Run())
|
||||||
template, err := sql.Open("sqlite", templateDBURL)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.NewTestDatabaseFromConn(template).
|
|
||||||
RunMigrations(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
code := m.Run()
|
|
||||||
|
|
||||||
_ = template.Close()
|
|
||||||
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// copyTemplateDB creates the in-memory database dbURL as a copy of
|
|
||||||
// the migrated template, so a test does not migrate the schema
|
|
||||||
// again. The copy lasts until the test ends.
|
|
||||||
func copyTemplateDB(t *testing.T, dbURL string) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
database, err := sql.Open("sqlite", dbURL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("open test db: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Cleanup(func() { _ = database.Close() })
|
|
||||||
|
|
||||||
conn, err := database.Conn(t.Context())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("connect test db: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() { _ = conn.Close() }()
|
|
||||||
|
|
||||||
err = conn.Raw(func(driverConn any) error {
|
|
||||||
restorer, ok := driverConn.(interface {
|
|
||||||
NewRestore(srcURI string) (*sqlite.Backup, error)
|
|
||||||
})
|
|
||||||
if !ok {
|
|
||||||
return errors.ErrUnsupported
|
|
||||||
}
|
|
||||||
|
|
||||||
restore, restoreErr := restorer.NewRestore(templateDBURL)
|
|
||||||
if restoreErr != nil {
|
|
||||||
return fmt.Errorf("start restore: %w", restoreErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, restoreErr = restore.Step(-1)
|
|
||||||
if restoreErr != nil {
|
|
||||||
_ = restore.Finish()
|
|
||||||
|
|
||||||
return fmt.Errorf("restore: %w", restoreErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return restore.Finish()
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("copy template db: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -155,7 +84,6 @@ func newTestServerWith(
|
|||||||
"file:test_%p?mode=memory&cache=shared",
|
"file:test_%p?mode=memory&cache=shared",
|
||||||
t,
|
t,
|
||||||
)
|
)
|
||||||
copyTemplateDB(t, dbURL)
|
|
||||||
|
|
||||||
var srv *server.Server
|
var srv *server.Server
|
||||||
|
|
||||||
@@ -181,8 +109,6 @@ func newTestServerWith(
|
|||||||
|
|
||||||
cfg.DBURL = dbURL
|
cfg.DBURL = dbURL
|
||||||
cfg.Port = 0
|
cfg.Port = 0
|
||||||
// One line: each line is a database write per new session.
|
|
||||||
cfg.MOTD = "neoirc test server"
|
|
||||||
cfg.HashcashBits = hashcashBits
|
cfg.HashcashBits = hashcashBits
|
||||||
cfg.OperName = operName
|
cfg.OperName = operName
|
||||||
cfg.OperPassword = operPassword
|
cfg.OperPassword = operPassword
|
||||||
|
|||||||
Reference in New Issue
Block a user