mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
ci: run PostgreSQL tests in isolated lane (#6730)
## Why PR #6660 introduced four PostgreSQL-backed persistence tests and a focused CI selector, but an exact test-name list does not automatically cover future database tests. Broad ignored-test execution also exposed shared-schema races and ambiguity between desired-state and migration-applied schema expectations. ## What - Establish a discoverable convention: PostgreSQL unit modules use `postgres_tests`, PostgreSQL integration binaries use a `postgres_` prefix, and unrelated external-infrastructure tests use an `external_infra_` prefix. - Add a dedicated nextest PostgreSQL profile and archive-backed CI job covering the relevant crates without enumerating test names. - Create a run-scoped desired-state source database and a unique PostgreSQL database per test process for parallel-safe isolation, with cleanup on success, failure, or interruption. - Route destructive migration and migration-parity tests to clean `template0` databases while desired-state tests clone the desired-state database. - Document discovery, schema modes, required role privileges, and a bounded portable local runner. - Keep the existing infrastructure-free unit-test jobs unchanged. This is intentionally limited to test and CI harness behavior. It does not move production database code, change persistence semantics, or implement issue #20's broader shared test-utility refactor. ## Risk Low production risk because all changes are confined to tests, CI configuration, documentation, and test harness scripts. Remaining operational risks: - Cleanup retries `dropdb --force` five times across roughly four seconds. Exhaustion warns with the database name but deliberately does not mask the test result; individual PostgreSQL diagnostics are suppressed. - The seven-package boundary is duplicated between the runner and CI archive and must remain synchronized if PostgreSQL tests move to a new crate. - Portable SHA fallback branches were exercised on Linux; no macOS Blox workstation was needed for this Linux CI artifact. - GitHub's unchanged generic Unit Tests job currently fails while cold-linking `buzz-voice` because `sherpa-onnx-c-api` is absent. The branch changes no voice/build/toolchain inputs; the exact parent previously passed that job, and Blox passes the same infrastructure-free suite (1,450/1,450). A prior-head one-job retry and the final-head run both reproduced the hosted-runner failure. ## Verification Author Blox workstation `2020088`: - `cargo fmt --all -- --check` - `just clippy` - `just test-unit`: 1,450 passed; PostgreSQL tests remain skipped in fast jobs - PR #6660 focused tests: 4/4 passed through the final runner - Full lane: 282/282 passed in 10.087s with a non-superuser role limited to `CREATEDB`, `CREATEROLE`, and `pg_read_all_stats` - 272 desired-state tests - 10 migration-applied tests - 6 explicitly filtered external-infrastructure tests - Cleanup fault injection: a deliberately underprivileged 282-test run produced the expected 277 passes and 5 failures, and the post-run catalog audit found zero lane databases after retry cleanup. The restored successful run also left zero lane databases. GitHub exact final head `92c231e48f299ea2af23817763f5ae80ac013d68`: - [PostgreSQL Tests](https://github.com/block/buzz/actions/runs/32789030203/job/97630827823): 282/282 passed across 10 binaries in 98.886s; 1,240 skipped, including 6 via the profile filter - The shared relay/PostgreSQL archive predecessor completed successfully - [Unit Tests](https://github.com/block/buzz/actions/runs/32789030203/job/97626930420): unrelated `sherpa-onnx-c-api` native-link failure described above - Independent exact-head review on separate Blox workstation `2022762`: no substantive findings after all initial findings were addressed. The reviewer independently verified cleanup retry behavior, exit-status preservation, shell portability, syntax, and a clean exact-head worktree. ## References - Stacked on #6660 at exact head `561de54be4d9c2b622b7c2aa5b61bc3068f47e2a` - https://github.com/TheSentinel454/buzz/issues/20 - https://github.com/TheSentinel454/buzz/issues/20#issuecomment-5398526792 Generated with Codex. ## Update — August 24, 2026 review follow-up - Centralized the repeated PostgreSQL test URL resolution in crate-local, test-only helpers without introducing the broader shared utility refactor from issue #20. - Restored descriptive hybrid/Redis test function names. Structural `external_infra_*_tests` modules now own exclusion, and the nextest filter only recognizes module path segments. - Added a three-second source guard that scans every Rust file and fails CI when an ignored PostgreSQL test would be omitted or an external-infrastructure test would be included. Fixture tests cover accepted modules/binaries and both failure modes. - Removed the two implementation-plan documents. Performance profiling on Blox workstation `2027352` (same prebuilt archive and cargo-nextest 0.9.143 for every comparison): - Current per-test database model, 8 workers: 10.15–10.40s across three runs. The 283 `createdb` calls and 284 `dropdb` calls consumed 28.85–29.46 aggregate seconds, about 39–40% of aggregate test-process duration. - Reusing one database per worker without cleanup: 6.55–6.84s, about 35% faster, but all three runs failed because global matcher-queue tests inherited a quiesced community from an earlier test; the failing test varied with scheduling. - Reusing workers with `TRUNCATE … RESTART IDENTITY CASCADE`: all 282 tests passed, but total time regressed to 10.47–10.67s. The 265 truncate calls consumed 24.34–25.45 aggregate seconds, so truncation merely replaced most clone/drop cost. - Raising concurrency to 16 workers reduced one isolated-database run to 8.79s, but 24 workers exposed a cluster-global `pg_stat_activity` race. The profile remains at the proven-safe 8 workers. Decision: retain unique per-test databases. Harness cleanup uses `dropdb --if-exists --force`; it drops the database rather than truncating tables or deleting rows. Verification at local branch head `60086c1f6ee34a193c342255a5e8e6293b60e988`: - Discovery inventory: exactly 282 intended tests; all 6 hybrid/Redis tests present and structurally excluded. - PR #6660 focused persistence tests: 4/4 passed. - Full PostgreSQL lane: 282/282 passed three times; 1,240 skipped each run; wall time 9.72–9.96s without profiling shims. - Non-ignored tests with a desired-state database: 1,234/1,234 passed; one mesh-demo timeout from the first run passed immediately in isolation. - `cargo fmt --all -- --check` and all-target/all-feature clippy for `buzz-db`, `buzz-deletion`, and `buzz-relay` passed. Final independent re-review at exact head `42097c0136ab3fa8f0efe5720ae829c04575b9b6` on separate Blox workstation `2028455`: no substantive residual findings. The reviewer independently exercised ordinary strings, zero/one/three-hash raw strings, line/block comments, and string-contained lookalikes, then reran the full 353-file scan, shell syntax, Python AST parsing, and diff check. Independent review found that the source guard's initial regular expression could miss raw-string ignore reasons and treat a commented attribute as real. Final head `42097c0136ab3fa8f0efe5720ae829c04575b9b6` parses valid ordinary/raw Rust string literals only at attributes found in comment-sanitized source; regression fixtures cover both cases. The fixture suite, Python compilation, shell syntax, diff check, and full 353-file repository scan pass on Blox. ## Update — August 25, 2026 restack PR #6660 merged, so this follow-up was rebased from its former exact parent onto current `origin/main` (`8d2d0ff5ad42733e9949442c4b6358d0ba87f9a8`). The final candidate head is `05dcc2ab28948e3ab79bb44839a69f2ba44648a2`; the PR no longer carries #6660's pre-squash history. Fresh exact-head verification on Blox workstation `2028572`: - Discovery guard passed across 353 Rust files; inventory remained exactly 282 intended PostgreSQL tests. - PR #6660 focused persistence tests: 4/4 passed. - Full PostgreSQL lane: 282/282 passed three times; 1,243 skipped each run; wall time 9.70–9.87s. - `cargo fmt --all -- --check` and all-target/all-feature clippy for `buzz-db`, `buzz-deletion`, and `buzz-relay` passed. ## Update — August 25, 2026 final hosted verification - [GitHub PostgreSQL Tests](https://github.com/block/buzz/actions/runs/32801679226/job/97667835080): 282/282 passed in 53.787s; 1,243 skipped. - The final guard scanned all 353 Rust files successfully before the hosted lane ran. - The shared relay/archive prerequisite and infrastructure-free Unit Tests job both passed at exact final head `42097c0136ab3fa8f0efe5720ae829c04575b9b6`. --------- Signed-off-by: Luke Tornquist <tornquist@squareup.com> Signed-off-by: tornquist <tornquist@squareup.com>
This commit is contained in:
275
.github/workflows/ci.yml
vendored
275
.github/workflows/ci.yml
vendored
@@ -44,6 +44,14 @@ jobs:
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.config/nextest.toml'
|
||||
- 'scripts/postgres-test-*.sh'
|
||||
- 'scripts/reconcile-schema-after-pgschema.sql'
|
||||
- 'bin/pgschema'
|
||||
- 'bin/.pgschema-*.pkg'
|
||||
- 'scripts/check-postgres-test-discovery.py'
|
||||
- 'scripts/test-postgres-test-discovery.sh'
|
||||
- 'scripts/test-postgres-test-wrapper.sh'
|
||||
- 'deny.toml'
|
||||
- '.github/workflows/ci.yml'
|
||||
- 'scripts/run-tests.sh'
|
||||
@@ -73,6 +81,11 @@ jobs:
|
||||
- 'scripts/test-mobile-worktree-overrides.sh'
|
||||
- '.github/workflows/mobile-release-candidate.yml'
|
||||
- '.github/workflows/ci.yml'
|
||||
- name: Validate PostgreSQL test discovery
|
||||
if: github.event_name == 'push' || steps.filter.outputs.rust == 'true'
|
||||
run: |
|
||||
scripts/test-postgres-test-discovery.sh
|
||||
scripts/test-postgres-test-wrapper.sh
|
||||
- name: Release workflow source contract
|
||||
run: scripts/test-release-ref-contract.sh
|
||||
- name: Relay image eligibility contract
|
||||
@@ -350,7 +363,8 @@ jobs:
|
||||
target/ci/buzz-relay
|
||||
target/ci/git-credential-nostr
|
||||
target/ci/backend-integration-tests.tar.zst
|
||||
key: relay-artifacts-${{ runner.os }}-${{ hashFiles('crates/**', 'migrations/**', 'Dockerfile', 'Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo/config.toml', '.github/workflows/ci.yml') }}
|
||||
target/ci/postgres-tests.tar.zst
|
||||
key: relay-artifacts-${{ runner.os }}-${{ hashFiles('crates/**', 'migrations/**', 'Dockerfile', 'Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo/config.toml', '.config/nextest.toml', 'scripts/postgres-test-*.sh', 'scripts/check-postgres-test-discovery.py', '.github/workflows/ci.yml') }}
|
||||
- uses: rui314/setup-mold@7e4f20ad28a2e8ca6fd0892ccf72e2abb706b9c3 # v1
|
||||
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true'
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2.9.1
|
||||
@@ -384,9 +398,22 @@ jobs:
|
||||
-p buzz-relay \
|
||||
-p buzz-test-client \
|
||||
--lib \
|
||||
--bin buzz-relay \
|
||||
--test e2e_event_reminder \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst
|
||||
postgres_package_args=()
|
||||
while IFS= read -r package; do
|
||||
postgres_package_args+=(-p "$package")
|
||||
done < <(scripts/postgres-test-packages.sh)
|
||||
if [[ "${#postgres_package_args[@]}" -eq 0 ]]; then
|
||||
echo "no PostgreSQL test packages were discovered" >&2
|
||||
exit 1
|
||||
fi
|
||||
cargo nextest archive \
|
||||
--cargo-profile ci \
|
||||
"${postgres_package_args[@]}" \
|
||||
--lib \
|
||||
--tests \
|
||||
--archive-file target/ci/postgres-tests.tar.zst
|
||||
- name: Save relay artifacts cache
|
||||
# PR-scoped exact-source entries cannot warm main or other PRs and churn
|
||||
# the shared cache pool. sccache provides read-only PR reuse instead.
|
||||
@@ -397,7 +424,8 @@ jobs:
|
||||
target/ci/buzz-relay
|
||||
target/ci/git-credential-nostr
|
||||
target/ci/backend-integration-tests.tar.zst
|
||||
key: relay-artifacts-${{ runner.os }}-${{ hashFiles('crates/**', 'migrations/**', 'Dockerfile', 'Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo/config.toml', '.github/workflows/ci.yml') }}
|
||||
target/ci/postgres-tests.tar.zst
|
||||
key: relay-artifacts-${{ runner.os }}-${{ hashFiles('crates/**', 'migrations/**', 'Dockerfile', 'Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo/config.toml', '.config/nextest.toml', 'scripts/postgres-test-*.sh', 'scripts/check-postgres-test-discovery.py', '.github/workflows/ci.yml') }}
|
||||
- name: Upload relay artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
@@ -406,9 +434,86 @@ jobs:
|
||||
target/ci/buzz-relay
|
||||
target/ci/git-credential-nostr
|
||||
target/ci/backend-integration-tests.tar.zst
|
||||
target/ci/postgres-tests.tar.zst
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
postgres-tests:
|
||||
name: PostgreSQL Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: [changes, desktop-e2e-relay]
|
||||
if: github.event_name == 'push' || needs.changes.outputs.rust == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
env:
|
||||
POSTGRES_USER: buzz
|
||||
POSTGRES_PASSWORD: ${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: >-
|
||||
--health-cmd "pg_isready -U buzz -d postgres"
|
||||
--health-interval 5s
|
||||
--health-timeout 5s
|
||||
--health-retries 12
|
||||
redis:
|
||||
image: redis:7
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 5s
|
||||
--health-timeout 5s
|
||||
--health-retries 12
|
||||
env:
|
||||
PGHOST: localhost
|
||||
PGPORT: "5432"
|
||||
PGUSER: buzz
|
||||
PG_BIN_DIR: /usr/bin
|
||||
REDIS_URL: redis://localhost:6379
|
||||
PGSCHEMA_PLAN_HOST: localhost
|
||||
PGSCHEMA_PLAN_PORT: "5432"
|
||||
PGSCHEMA_PLAN_USER: buzz
|
||||
PGSCHEMA_PLAN_PASSWORD: buzz_dev
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Tune disposable PostgreSQL
|
||||
env:
|
||||
PGPASSWORD: ${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}
|
||||
run: |
|
||||
# Database-per-test cloning forces checkpoints. Durability is redundant
|
||||
# for this disposable service and makes runtime depend on runner disk I/O.
|
||||
psql --dbname postgres --set ON_ERROR_STOP=1 <<'SQL'
|
||||
ALTER SYSTEM SET fsync = off;
|
||||
ALTER SYSTEM SET full_page_writes = off;
|
||||
ALTER SYSTEM SET synchronous_commit = off;
|
||||
SELECT pg_reload_conf();
|
||||
SQL
|
||||
psql --dbname postgres --tuples-only --no-align --command \
|
||||
"SELECT bool_and(setting = 'off') FROM pg_settings WHERE name IN ('fsync', 'full_page_writes', 'synchronous_commit')" \
|
||||
| grep --fixed-strings --line-regexp t
|
||||
- name: Install cargo-nextest
|
||||
uses: taiki-e/install-action@0fd46367812ee04360509b4169d9f659d6892bb2 # v2.79.15
|
||||
with:
|
||||
tool: cargo-nextest@0.9.136
|
||||
- name: Download backend test archive
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: desktop-e2e-relay
|
||||
path: target/ci
|
||||
- name: PostgreSQL-backed tests
|
||||
env:
|
||||
BUZZ_POSTGRES_ADMIN_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/postgres
|
||||
PGPASSWORD: ${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}
|
||||
run: |
|
||||
scripts/postgres-test-run.sh \
|
||||
--archive-file target/ci/postgres-tests.tar.zst
|
||||
|
||||
desktop-e2e-integration-shard:
|
||||
name: Desktop E2E Integration (${{ matrix.shard }}/2)
|
||||
runs-on: ubuntu-latest
|
||||
@@ -689,68 +794,14 @@ jobs:
|
||||
VALUES ('00000000-0000-4000-8000-00000000c0de', 'localhost:3000')
|
||||
ON CONFLICT (lower(host)) DO NOTHING
|
||||
;"
|
||||
- name: Workflow message provenance tests
|
||||
- name: Workflow message provenance unit tests
|
||||
# The relay's workflow_sink suite is not selected by the infra-free
|
||||
# unit job. Run both its pure tests and ignored PostgreSQL tests here so
|
||||
# authored-template provenance cannot regress behind a green CI build.
|
||||
# unit job. Its ignored database cases run in the isolated PostgreSQL
|
||||
# lane; keep the pure provenance cases covered here without duplication.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(/workflow_sink/)' \
|
||||
--run-ignored all
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Replaceable persistence PostgreSQL tests
|
||||
# Transaction, concurrency, and mention-index coverage for the
|
||||
# replaceable-event store seam. These tests require real Postgres and
|
||||
# are ignored by the infrastructure-free unit-test job.
|
||||
run: |
|
||||
filter='package(buzz-db) and test(/tests::(parameterized_|concurrent_parameterized_)/)'
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E "${filter}" \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Database pressure observability PostgreSQL tests
|
||||
# Explicit pool acquisition and advisory-lock metrics require real
|
||||
# Postgres and are ignored by the infrastructure-free unit-test job.
|
||||
run: |
|
||||
filter='package(buzz-db) and test(/observability::tests::(pool_acquire_records_success_timeout_and_error_with_wait_time|advisory_lock_records_success_contention_timeout_and_error)/)'
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E "${filter}" \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Writer session timeout guardrails
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-db) and test(session_timeouts_install_through_db_new_and_bound_lock_waits)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Audit writer session timeout guardrails
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(audit_writer_pool_installs_timeouts_and_bounds_advisory_lock_waits)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Audit worker lock-timeout recovery
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(audit_worker_retries_lock_timeout_until_original_entry_is_appended_once)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
-E 'package(buzz-relay) and test(/workflow_sink/)'
|
||||
- name: Start relay
|
||||
run: |
|
||||
chmod +x ./target/ci/buzz-relay
|
||||
@@ -779,26 +830,6 @@ jobs:
|
||||
done
|
||||
cat /tmp/buzz-relay.log
|
||||
exit 1
|
||||
- name: Invite security tests
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E '(package(buzz-db) and test(/relay_invite::tests/)) or (package(buzz-relay) and test(/api::invites::tests/))' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Workspace profile (kind:9033) gate tests
|
||||
# Call-site integration for the 9033 authorization gate: open relay
|
||||
# rosterless/steward transitions and the closed-relay admin/owner rule,
|
||||
# against real Postgres. #[ignore]d in the default suite, selected
|
||||
# explicitly here — see handlers::relay_admin::tests.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(/handlers::relay_admin::tests/)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: NIP-ER reminder e2e
|
||||
# Feature e2e for NIP-ER (Event Reminders, kind:30300): write-path
|
||||
# validation, author-only read filtering, and scheduler delivery against
|
||||
@@ -811,88 +842,6 @@ jobs:
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
RELAY_URL: ws://localhost:3000
|
||||
- name: NIP-MP coordinate deletion guard
|
||||
# Verifies the never-delete-newer invariant of soft_delete_by_coordinate:
|
||||
# a stale tombstone (created_at earlier than the live head) spares that
|
||||
# head, and an equal-timestamp tombstone deletes it.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-db) and test(coordinate_delete_spares_head_newer_than_the_deletion)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Admin API nip98 read-write attribution test
|
||||
# The only real HTTP → nip98 operator principal → mutation → cross-table
|
||||
# attribution coverage: an authenticated operator's dismiss attributes
|
||||
# to the operator's own key with relay_operator authority. Staffing
|
||||
# PUT/DELETE attribution is covered by
|
||||
# nip98_staffing_put_and_delete_write_attributed_audit_rows in the
|
||||
# roster-audit lane below. #[ignore]d in the default suite — see
|
||||
# api::admin::tests::nip98_operator_dismiss_succeeds_attributed_to_operator.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(=api::admin::tests::nip98_operator_dismiss_succeeds_attributed_to_operator)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Admin API unrostered-signer replay invariant
|
||||
# The only causal proof that a validly-signing but unrostered key cannot
|
||||
# consume NIP-98 replay slots: it asserts principal resolution fails
|
||||
# BEFORE the replay ID is claimed (tracking.claim_count() == 0). This
|
||||
# test is non-ignored, so it runs neither in Backend Integration's
|
||||
# ignored-only selectors nor in the infra-free unit job — the unit job's
|
||||
# api::admin selector excludes it because DB-free it only passes by
|
||||
# waiting out the ~30s sqlx acquire timeout on a read-route fallthrough.
|
||||
# It lives here so a reachable Postgres resolves (and fails) the lookup
|
||||
# fast instead of timing out.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(=api::admin::tests::nip98_mode_unrostered_signer_does_not_consume_a_replay_slot)'
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Admin API roster-audit / timeout / canonicalization security tests
|
||||
# Security-review fixes for the roster admin API, all #[ignore]d in the
|
||||
# default suite (they need Postgres) and selected by no other job:
|
||||
# - buzz-db relay_operators::tests: audit pre-image trail, per-target
|
||||
# lock serialization, insertion-time audit ordering, and
|
||||
# audit-failure rollback coupling.
|
||||
# - buzz-db relay_operators::tests last-operator invariant: sole DB
|
||||
# operator cannot self-demote or self-delete to zero, config presence
|
||||
# lifts the guard, and concurrent cross-target deletes racing to zero
|
||||
# leave exactly one operator (roster-wide advisory lock).
|
||||
# - buzz-relay api::admin: NIP-98 staffing writes attributed audit rows,
|
||||
# adversarial expirationSecs rejected at the resolve route, mixed-case
|
||||
# staffing normalizes to one canonical row.
|
||||
#
|
||||
# --test-threads=1: the last-operator invariant counts the roster
|
||||
# globally, and the sole-operator tests clear the roster then assert
|
||||
# their operator is the only one. They must not race each other on the
|
||||
# shared test roster, so this lane runs serially.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
--test-threads=1 \
|
||||
-E '(package(buzz-db) and test(=relay_operators::tests::roster_mutations_write_pre_image_audit_rows)) or (package(buzz-db) and test(=relay_operators::tests::concurrent_upserts_serialize_and_record_true_pre_image)) or (package(buzz-db) and test(=relay_operators::tests::audit_order_follows_seq_under_backward_clock)) or (package(buzz-db) and test(=relay_operators::tests::audit_insert_failure_rolls_back_roster_mutation)) or (package(buzz-db) and test(=relay_operators::tests::demoting_sole_db_operator_without_config_is_rejected)) or (package(buzz-db) and test(=relay_operators::tests::deleting_sole_db_operator_without_config_is_rejected)) or (package(buzz-db) and test(=relay_operators::tests::config_present_allows_deleting_last_db_operator)) or (package(buzz-db) and test(=relay_operators::tests::concurrent_deletes_racing_to_zero_leave_one_operator)) or (package(buzz-relay) and test(=api::admin::tests::nip98_staffing_put_and_delete_write_attributed_audit_rows)) or (package(buzz-relay) and test(=api::admin::tests::resolve_route_rejects_adversarial_expiration_and_leaves_report_open)) or (package(buzz-relay) and test(=api::admin::tests::mixed_case_non_config_staffing_normalizes_to_one_row))' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Admin API escalation-scoping tests
|
||||
# Escalation scoping for the moderation queue, all #[ignore]d (they need
|
||||
# Postgres) and selected by no other job:
|
||||
# - GET /reports defaults to the escalated-only backstop, scope=all
|
||||
# restores full visibility, explicit status= overrides the default.
|
||||
# - member reports with category 'illegal' auto-escalate at ingestion
|
||||
# while every other category still lands 'open'.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E '(package(buzz-relay) and test(=api::admin::tests::reports_default_lists_escalated_only)) or (package(buzz-relay) and test(=api::admin::tests::reports_scope_all_lists_every_status)) or (package(buzz-relay) and test(=api::admin::tests::reports_explicit_status_filter_overrides_default)) or (package(buzz-db) and test(=moderation::tests::illegal_report_auto_escalates_at_ingest)) or (package(buzz-db) and test(=moderation::tests::non_illegal_report_lands_open_at_ingest)) or (package(buzz-db) and test(=relay_admin_actions::tests::auto_escalated_report_reopens_like_an_admin_escalated_one))' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Upload relay log
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
|
||||
Reference in New Issue
Block a user