mirror of
https://github.com/BaaRai/ARTEX.git
synced 2026-11-13 11:40:53 +08:00
feat: each test package runs on its own database
agent, db, server and evidence serialized on one shared test database via an advisory lock, while evidence, llmrec and traffic-style packages could still run against it in parallel; under full-suite load that window produced a real SQLSTATE 40P01 deadlock in the blackboard direct-source test. TestMain in every PG-using package now rewrites ARTEX_PG_DSN to a per-package database (created automatically by ensureDatabase), so packages neither contend nor need to serialize; the advisory lock stays as an in-package safety net. llmrec gains the TestMain it lacked, which also gives its requires-isolated-DSN tests a truly isolated database inside ./... runs.
This commit is contained in:
@@ -13,6 +13,10 @@ import (
|
||||
// agent test suite so cross-package DELETE cleanup races with db/server
|
||||
// packages are avoided when running `go test ./...`.
|
||||
func TestMain(m *testing.M) {
|
||||
// Own database per package (#80): with separate databases, packages stop
|
||||
// contending on shared tables and the advisory lock below stops
|
||||
// serializing go test ./... across packages.
|
||||
db.SuffixTestDatabase("agent")
|
||||
dsn, _, err := db.DSN()
|
||||
if err != nil {
|
||||
os.Exit(m.Run())
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -96,6 +97,26 @@ func DSN() (dsn, source string, err error) {
|
||||
return config.PostgresDSN()
|
||||
}
|
||||
|
||||
// SuffixTestDatabase rewrites the ARTEX_PG_DSN environment variable so its
|
||||
// database name carries the given suffix (artex -> artex_agent). Called from
|
||||
// package TestMain functions so every go test package runs against its own
|
||||
// database: parallel package processes then cannot contend on the same tables
|
||||
// (the under-load deadlock family, #80). No-op when ARTEX_PG_DSN is unset —
|
||||
// config-file and production paths are untouched. Open creates the suffixed
|
||||
// database automatically (ensureDatabase).
|
||||
func SuffixTestDatabase(suffix string) {
|
||||
v := strings.TrimSpace(os.Getenv("ARTEX_PG_DSN"))
|
||||
if v == "" {
|
||||
return
|
||||
}
|
||||
u, err := url.Parse(v)
|
||||
if err != nil || u.Path == "" || u.Path == "/" {
|
||||
return
|
||||
}
|
||||
u.Path = "/" + strings.TrimPrefix(u.Path, "/") + "_" + suffix
|
||||
_ = os.Setenv("ARTEX_PG_DSN", u.String())
|
||||
}
|
||||
|
||||
// DB wraps the shared *sql.DB. PG handles its own connection pool + concurrency
|
||||
// (MVCC), so unlike the old SQLite store there is no process-wide write mutex.
|
||||
type DB struct{ *sql.DB }
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
// avoid cross-package cleanup races (e.g. DELETE FROM assets WHERE id > X
|
||||
// from one package deleting assets created by another).
|
||||
func TestMain(m *testing.M) {
|
||||
// Own database per package (#80): with separate databases, packages stop
|
||||
// contending on shared tables and the advisory lock below stops
|
||||
// serializing go test ./... across packages.
|
||||
SuffixTestDatabase("db")
|
||||
dsn, _, err := DSN()
|
||||
if err != nil {
|
||||
// No DB configured — tests that need PG will skip themselves.
|
||||
|
||||
@@ -11,6 +11,9 @@ import (
|
||||
// Initialize an explicitly configured fresh database before taking the same
|
||||
// suite lock as db, agent and server. Hold it on one pinned connection.
|
||||
func TestMain(m *testing.M) {
|
||||
// Own database per package (#80): stop contending on the shared tables of
|
||||
// a single test database during parallel ./... runs.
|
||||
db.SuffixTestDatabase("evidence")
|
||||
if os.Getenv("ARTEX_PG_DSN") == "" {
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package llmrec
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Autumn-27/artex/db"
|
||||
)
|
||||
|
||||
// Run against this package's own database (db.SuffixTestDatabase, #80): the
|
||||
// recorder tests require an isolated ARTEX_PG_DSN, and the suffix gives them
|
||||
// one even inside a full parallel ./... run.
|
||||
func TestMain(m *testing.M) {
|
||||
db.SuffixTestDatabase("llmrec")
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -13,6 +13,10 @@ import (
|
||||
// server test suite so cross-package DELETE cleanup races with db/agent
|
||||
// packages are avoided when running `go test ./...`.
|
||||
func TestMain(m *testing.M) {
|
||||
// Own database per package (#80): with separate databases, packages stop
|
||||
// contending on shared tables and the advisory lock below stops
|
||||
// serializing go test ./... across packages.
|
||||
db.SuffixTestDatabase("server")
|
||||
dsn, _, err := db.DSN()
|
||||
if err != nil {
|
||||
os.Exit(m.Run())
|
||||
|
||||
Reference in New Issue
Block a user