Skip to content

test(breg): native timer fairness test fails intermittently in harness cleanup #2505

Open

Description

@jeremi

native_bounded_fairness_interleaves_all_timer_lanes_across_types_and_replicas (crates/registry-breg/tests/postgres_record_timer_native.rs) failed once in a merge-queue run and passed on the next attempt with no code change.

panicked at crates/registry-breg/tests/postgres_record_timer_native.rs:3126:35:
native timer result Ok(()); native timer cleanup found 1 failure(s); logs retained at /tmp/breg-record-timer-native-HQOq99

The journey itself returned Ok(()). The failure came from NativeTimerHarness::finish in crates/registry-breg/tests/support/record_timer_native.rs, which collects errors from replica.stop() and assert_logs_safe() but reports only their count. The retained logs live on the runner and are gone, so the cause can't be recovered from this run.

Suggested first step: include the collected failure messages in the finish error so the next occurrence says whether a replica failed to stop or a log check tripped. Then fix the actual cause.

Possibly related: three other PostgreSQL tests failed locally under heavy machine load and passed when rerun alone. They have not been seen failing on CI:

  • postgres_package::signed_schema_fingerprint_mismatch_is_refused_before_maintenance_and_never_ready
  • postgres_proposal::automatic_lease_expiring_during_a_write_rolls_back_and_recovers_within_its_budget
  • postgres_record_timer_native::native_reviewed_successor_refreshes_held_occurrence_once_after_restart

Activity

  1. jeremi commented on Oct 30, 2026

    @jeremi
    MemberAuthor

    Second occurrence, different test in the same file and the same harness cleanup path: native_database_session_loss_rolls_back_active_transaction_for_peer_recovery failed with native timer result Ok(()); native timer cleanup found 1 failure(s) in merge-queue run https://github.com/registrystack/registry-stack/actions/runs/41016229506 (job "Base Registry Engine product contracts (postgres:2/3)", 2026-10-30). That PR does not touch the timer tests. So this looks like a harness cleanup problem rather than one test's logic.

  2. jeremi commented on Nov 5, 2026

    @jeremi
    MemberAuthor

    Two more merge-queue occurrences in the same job ("Base Registry Engine product contracts (postgres:2/3)"), neither from a PR that touches the timer tests:

    • https://github.com/registrystack/registry-stack/actions/runs/41654925232 (2026-11-03): native_database_session_loss_rolls_back_active_transaction_for_peer_recovery, native timer result Ok(()); native timer cleanup found 1 failure(s) at line 3126 (the same signature as the second occurrence).
    • https://github.com/registrystack/registry-stack/actions/runs/42031631826 (2026-11-05): two tests failed in one run.
      • native_fixture_pause_resume_fences_pre_pause_claim_across_processes (line 3141): native timer result Err("native timer durable evidence query failed"); native timer cleanup found 1 failure(s): native timer process log warning/error codes differed: expected_ranges={}, actual={"<none>": 1}. The cleanup error now names its cause: one warning or error log line with no code.
      • native_fault_stale_resumed_owner_cannot_settle_after_peer (line 3135): native timer completion was not one atomic exact-once effect, with the timer still pending / scheduled at revision 1 and no outbox entry or action receipt.

    That makes four failures in eight days, across four different tests in postgres_record_timer_native.rs, all in the 2/3 shard. The uncoded log line in the latest run looks like the next thing to chase: finding which process emitted it should say whether this is harness cleanup or a real ordering problem. The second failure in that run asserts on the product's exactly-once evidence rather than on cleanup, so it may not be only the harness.

  3. jeremi commented on Nov 8, 2026

    @jeremi
    MemberAuthor

    Two more occurrences on 2026-11-07, both with an empty expected range and one unexpected process log code, so the same harness cleanup path:

    The second one is a different test on the same harness, and this time a replica failed before readiness rather than during the journey. The suggested first step still stands: the retained replica logs are on the runner and gone, so finish and the readiness failure should print the replica log tail into the panic message.

  4. jeremi commented on Nov 11, 2026

    @jeremi
    MemberAuthor

    Another occurrence, merge-queue run https://github.com/registrystack/registry-stack/actions/runs/42977045944 (job "Base Registry Engine product contracts (postgres:2/3)", 2026-11-11), from #2644, which touches no hook or timer runtime code.

    native_database_session_loss_rolls_back_active_transaction_for_peer_recovery panicked at postgres_record_timer_native.rs:3182. This time the message names the code (the finish change helped):

    • actual: {"hook.claim.identity_refused": 1, "hook.worker.iteration_failed": 1, "record_timer.worker.iteration_failed": 1}
    • offending line: level="WARN" message="hook state transition failed" code="hook.claim.identity_refused"
    • hook.claim.identity_refused is not in this test's expected ranges, which allow (0, 2) for the other hook.claim.* codes.

    So, at least for this test, the hook worker on the replica whose database session was killed can log one refused claim identity before it recovers. If that is the intended recovery path, the fix is to allow hook.claim.identity_refused (0, 2) in the session-loss test's expected ranges, like the other hook claim codes. If it is not intended, the hook claim path after session loss needs a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions