Main's #8605 took migrations 0072 and 0073 for the user deletion target, so the invitation migration moves to 0074_invite_revocation.sql. Upgrade fixtures now start from main's schema through 0073, the migrator test expects 74 contiguous migrations with the invitation assertions at index 73, and both TESTING.md files name 0074. Co-authored-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Luke Tornquist <tornquist@squareup.com>
3.6 KiB
PostgreSQL-backed tests in buzz-db
The dedicated PostgreSQL CI lane discovers tests and Cargo packages by structure rather than by exact lists. Follow this checklist so a new database test is run automatically and remains safe under parallel execution.
Adding a test
- Put the test in a module whose name ends in
postgres_tests. - Mark it
#[ignore = "requires Postgres"]so infrastructure-free unit-test jobs stay fast. - Connect through
crate::test_support::database_url(). The CI wrapper sets this helper's environment to a unique database for each test process; never hard-code the shared development database. - Keep tests that need infrastructure beyond PostgreSQL and Redis in an
external_infra*_testsmodule. The PostgreSQL lane excludes those tests. - Run
scripts/test-postgres-test-discovery.shafter adding or moving the test. The same guard runs in CI immediately after changed-path detection.
The wrapper isolates destructive tests by dropping the entire per-test
database after the process exits. It does not DELETE rows or TRUNCATE
shared tables, so tests may run concurrently without coordinating cleanup.
Choose the schema intentionally
Most tests use the committed desired-state schema from schema/schema.sql,
a manifest that includes one schema/tables/public/<table>.sql per table plus
its types, functions, partitions, triggers, and seed rows.
That is the default and is appropriate for data-access behavior.
Tests in migration::postgres_tests receive an empty database and own the
embedded migration lifecycle. A test outside that module that intentionally
depends on migration-created triggers or seed rows must prefix its function
name with migration_schema_; it also receives an empty database with
BUZZ_TEST_SCHEMA_MODE=migration.
Helpers that normally run migrations honor BUZZ_TEST_SCHEMA_MODE=desired in
the default lane. Do not rerun migrations against a desired-state database.
When behavior should match in both schema paths, add explicit desired-state and
migration-applied coverage rather than making the bootstrap implicit.
Tests that inspect cluster-wide PostgreSQL state or open least-privilege
sessions include cluster_global_ in the function name. Migration-backed cases
use migration_schema_cluster_global_. Nextest serializes this small group
because separate databases still share pg_stat_activity and roles.
Run the lane locally
Start native PostgreSQL and Redis, activate Hermit, and run:
. ./bin/activate-hermit
scripts/test-postgres-test-discovery.sh
scripts/postgres-test-run.sh
Set BUZZ_POSTGRES_ADMIN_URL to a PostgreSQL maintenance database owned by a
role that can create and drop databases. Set PGHOST, PGPORT, PGUSER, and
PGPASSWORD for desired-state bootstrap, plus REDIS_URL for Redis-backed
tests. The complete privilege-boundary inventory also needs CREATEROLE and
membership in pg_read_all_stats, or an ephemeral superuser as CI uses.
The runner creates one desired-state source database per invocation and clones it for ordinary tests. Migration-mode tests start empty. Cleanup retries transient disconnect races before reporting a warning.
Invite upgrade tests start from the complete schema through migration 0073, including channel join roles, entity deletion approval, the unlisted channel setting and the user deletion target. They exercise the invitation schema expansion (migration 0074) through both migration and desired-state paths against populated data, retaining a non-default channel join role. Historical repair is validated separately from the application/schema change.