Keep each test database when the pool replaces its connection (closes #209)
check / check (push) Waiting to run

SQLite deletes a shared in-memory database when its last connection
closes. A query cancelled while it runs makes the pool close its
connection, so a test could lose all its tables and rows at random.

The new package internal/dbtest has NewURL. It returns the URL of a
new in-memory database with a random name and holds one connection to
it open until the test ends. The db, handlers, ircserver, server and
service tests take their database URL from it. The test-support lint
rule keeps the package out of the server binary.

A new test cancels a query on such a database, checks with a TEMP
table that the connection was replaced, and checks that a row is
still there.

Model: opus-5-5
This commit was merged in pull request #210.
This commit is contained in:
2026-10-27 12:26:48 +01:00
parent 53009cf9a0
commit d444831f41
10 changed files with 106 additions and 42 deletions
+39
View File
@@ -0,0 +1,39 @@
// Package dbtest gives each test a database of its own. Only tests
// may import it.
package dbtest
import (
"crypto/rand"
"database/sql"
"testing"
_ "modernc.org/sqlite" // registers the sqlite driver
)
// NewURL returns the URL of a new, empty in-memory database for one
// test. SQLite deletes an in-memory database when its last connection
// closes. A pool closes a connection when a query on it is cancelled
// while it runs. So this function holds a connection of its own open
// until the test ends.
func NewURL(tb testing.TB) string {
tb.Helper()
// A random name, so that no other test can share the database.
dbURL := "file:" + rand.Text() + "?mode=memory&cache=shared"
pool, err := sql.Open("sqlite", dbURL)
if err != nil {
tb.Fatalf("open test database: %v", err)
}
tb.Cleanup(func() { _ = pool.Close() })
conn, err := pool.Conn(tb.Context())
if err != nil {
tb.Fatalf("connect to test database: %v", err)
}
tb.Cleanup(func() { _ = conn.Close() })
return dbURL
}