Documentation
¶
Overview ¶
Package testdb is the single entry point for tests that touch the PostgreSQL test database.
Two layers protect the suite from itself:
- A per-package schema. Lock creates `test_<pkg>_<pid>`, opens every handle with `search_path=<schema>,public` (by overriding the DSN env for the whole test process), and drops the schema when the package finishes. Each package therefore migrates and writes its own relations — one package's schema DDL can no longer touch another package's tables or rows.
- A suite lock (PostgreSQL advisory lock), held for the whole package run. It serializes schema migrations across packages. It is kept as defense in depth: even a package that somehow skipped the lock only sees its own schema, so it cannot deadlock anyone else.
The lock matters because db.Open re-runs the whole schema migration on every call and that migration takes ACCESS EXCLUSIVE locks. Before isolation, a migration running outside the lock deadlocked against another package's asset DML (40P01), with the failure landing in whichever transaction lost the race.
Tests must take the lock in TestMain (testdb.Lock) and open handles through testdb.Open; Open refuses to run without the lock, which makes "open before lock" impossible to write by accident. The lock is per package rather than per test because production helpers opened inside tests (Manager, stores) call db.Open themselves, so a per-test lease could not cover them.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DSN ¶
func DSN() string
DSN returns the configured PostgreSQL DSN, or "" when none is configured. Once Lock has run it returns the schema-isolated DSN for this test process. It accepts ARTEX_REDTEAM_PG_DSN (legacy ARTEX_PG_DSN) and config.json, the same resolution production uses.
func Lock ¶
Lock runs m in a per-package schema with the shared suite lock held, then drops the schema. Call it from TestMain:
func TestMain(m *testing.M) { os.Exit(testdb.Lock(m)) }
Without a configured DSN it simply runs m; DB-backed tests skip themselves in Open, so a DB-less environment behaves as before.
func Open ¶
Open runs open(dsn) while the suite lock is held and registers cleanup to close the returned handle. T is any handle with Close() error (*db.DB, etc.).
open is expected to be db.Open (or a wrapper around it) so the idempotent schema migration happens here, in this package's schema, under the lock. Calling Open without testdb.Lock in TestMain fails the test.
Types ¶
This section is empty.