diff --git a/Justfile b/Justfile index ca84a49590..bd45b1cc07 100644 --- a/Justfile +++ b/Justfile @@ -481,8 +481,12 @@ test-unit: # (JWKS source + refresh-loop composition), which `--lib` cannot reach # because they live in the binary target; the nested # `tests::postgres_tests::` stays in the PostgreSQL lane. + # The fourth clause adds the startup step timers (startup_steps) and the + # env- and log-capture tests in telemetry and config. All three modules + # are infra-free; config parses env into a struct and never connects. + # `^config::` is anchored so it does not also select nip_fi_config. cargo nextest run -p buzz-relay --lib --bin buzz-relay \ - -E 'test(/^api::admin::/) + test(/^handlers::channel_authz::/) + test(/^handlers::moderation_authz::/) + test(/^handlers::side_effects::tests::/) + test(/^storage_sweep::tests::/) + test(/^nip_fi_core::tests::/) + test(/^nip_fi_http::tests::/) + test(/^nip_fi_config::tests::/) + test(/^readiness::tests::/) + test(/^router::tests::/) + test(/^api::parse_query_tests::/) + test(/^api::git::transport::off_mode_precedence_tests::/) + test(/^audio::join::tests::/) + test(/^audio::handler::tests::/) + test(/^nip_fi_gate::tests::/) + test(/^nip_fi_session::tests::/) + test(/^nip_fi_shadow::tests::/) + test(/^nip_fi_shadow_session::tests::/) + test(=state::tests::neither_a_confirmed_inactive_community_nor_a_failed_lookup_admits_the_socket) + test(=handlers::req::tests::timed_out_historical_read_deregisters_before_closed) + test(=handlers::req::tests::superseded_timeout_leaves_replacement_intact) + test(=handlers::req::tests::search_claim_retires_live_and_yields_to_replacement) + test(=handlers::req::tests::concurrent_claims_and_stale_teardowns_keep_the_last_owner) + test(=handlers::req::tests::timeout_closed_is_emitted_before_a_replacement_can_claim) + test(=handlers::req::tests::revoke_then_replacement_keeps_replacement_whole) + test(=handlers::req::tests::claims_after_connection_cleanup_are_refused) + test(=handlers::req::tests::dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::revoke_dropped_terminal_frame_cancels_connection) + (kind(bin) & (test(/^tests::/) + test(/^composition_tests::/) + test(/^env_filter_tests::/)) - test(/^tests::postgres_tests::/))' + -E 'test(/^api::admin::/) + test(/^handlers::channel_authz::/) + test(/^handlers::moderation_authz::/) + test(/^handlers::side_effects::tests::/) + test(/^storage_sweep::tests::/) + test(/^nip_fi_core::tests::/) + test(/^nip_fi_http::tests::/) + test(/^nip_fi_config::tests::/) + test(/^readiness::tests::/) + test(/^router::tests::/) + test(/^api::parse_query_tests::/) + test(/^api::git::transport::off_mode_precedence_tests::/) + test(/^audio::join::tests::/) + test(/^audio::handler::tests::/) + test(/^nip_fi_gate::tests::/) + test(/^nip_fi_session::tests::/) + test(/^nip_fi_shadow::tests::/) + test(/^nip_fi_shadow_session::tests::/) + test(/^startup_steps::tests::/) + test(/^telemetry::tests::/) + test(/^config::tests::/) + test(=state::tests::neither_a_confirmed_inactive_community_nor_a_failed_lookup_admits_the_socket) + test(=handlers::req::tests::timed_out_historical_read_deregisters_before_closed) + test(=handlers::req::tests::superseded_timeout_leaves_replacement_intact) + test(=handlers::req::tests::search_claim_retires_live_and_yields_to_replacement) + test(=handlers::req::tests::concurrent_claims_and_stale_teardowns_keep_the_last_owner) + test(=handlers::req::tests::timeout_closed_is_emitted_before_a_replacement_can_claim) + test(=handlers::req::tests::revoke_then_replacement_keeps_replacement_whole) + test(=handlers::req::tests::claims_after_connection_cleanup_are_refused) + test(=handlers::req::tests::dropped_terminal_frame_cancels_connection) + test(=handlers::req::tests::revoke_dropped_terminal_frame_cancels_connection) + (kind(bin) & (test(/^tests::/) + test(/^composition_tests::/) + test(/^env_filter_tests::/)) - test(/^tests::postgres_tests::/))' # Note on audio::join::tests scope: the full suite is infra-free (no DB, # no Redis). The infra-free audio/FI regression witnesses — bootstrap # ordering barrier, CommitConfirmed arm, pending-close invisibility, diff --git a/crates/buzz-relay/src/test_support.rs b/crates/buzz-relay/src/test_support.rs index 2209bc21f0..b6d786de6f 100644 --- a/crates/buzz-relay/src/test_support.rs +++ b/crates/buzz-relay/src/test_support.rs @@ -6,8 +6,9 @@ const DEFAULT_DATABASE_URL: &str = "postgres://buzz:buzz_dev@localhost:5432/buzz /// process-wide from whichever dispatchers are live when it is first hit or /// rebuilt, so a parallel test's dispatcher (or a thread with none) can enable /// or disable another test's callsites. Not reentrant; take it once per test. -/// `router.rs`'s async otel-export test installs a dispatcher without it, -/// because the guard would be held across `.await`. +/// Two async tests install a dispatcher without it, because the guard would be +/// held across `.await`: `router.rs`'s otel-export test and +/// `api/bridge/thread_window/postgres_tests/failure_postgres_tests.rs`. pub(crate) fn tracing_dispatch_lock() -> std::sync::MutexGuard<'static, ()> { static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner()) diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index f89fb8c3ee..d4aa073dd8 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -203,6 +203,19 @@ run_unit_tests() { run_test_step "buzz-relay NIP-FI shadow session tests" \ cargo test -p buzz-relay --lib nip_fi_shadow_session::tests:: -- --nocapture + run_test_step "buzz-relay startup step tests" \ + cargo test -p buzz-relay --lib startup_steps::tests:: -- --nocapture + + # telemetry and config tests mutate process env. libtest runs one process + # with many threads (nextest, used by `just test-unit`, isolates each test), + # so run them single-threaded here. `--skip` keeps the substring filter + # `config::tests::` from also selecting nip_fi_config, which runs above. + run_test_step "buzz-relay telemetry tests" \ + cargo test -p buzz-relay --lib telemetry::tests:: -- --test-threads=1 --nocapture + + run_test_step "buzz-relay config tests" \ + cargo test -p buzz-relay --lib config::tests:: -- --skip nip_fi_config:: --test-threads=1 --nocapture + # Mirror the NIP-FI (S3) stanza from `just test-unit`: module filters, then # each exact name. Keep this list in step with that stanza's `test(=...)`s. run_test_step "buzz-relay NIP-FI config tests" \