Skip to content

test(b2): make the reauth waiter test deterministic - #238

Merged
ffumero2003 merged 1 commit into
mainfrom
fix-b2-issue-237-reauth-test-flake
Oct 30, 2026
Merged

ffumero2003 merged 1 commit into
mainfrom
fix-b2-issue-237-reauth-test-flake

Conversation

@ffumero2003

Copy link
Copy Markdown
Contributor

Problem

TestMappingReauthWaiterSurvivesCancelledLeader, added in #224 for #201's R4, failed intermittently in CI. It was seen on #211 (Go 1.27.3, ubuntu-latest, -race -shuffle=on, seed 1793310626879098904):

--- FAIL: TestMappingReauthWaiterSurvivesCancelledLeader
    bucket_mapping_edges_test.go:124: waiter error = b2_list_buckets: 401: expired, want nil

It did not reproduce locally with that seed or in 200 isolated runs, so it is timing-dependent and can fail any PR's CI.

Root cause (test fixture, not blazer)

The fake b2_authorize_account handler blocked the leader's reauthorization (call 2) until the test cancelled the leader, and then still answered it with success, using the expired token "t".

  • Usually the leader's HTTP client saw the cancellation first and failed with context.Canceled. The waiter then reauthorized itself and got the "fresh" token, as the test intends.
  • Occasionally the success response arrived first. Blazer then recorded a successful refresh with the stale token, the waiter correctly reused it, and got 401 expired again.

Blazer was correct in both orderings. The fixture should never report a successful refresh with an expired token.

Fix

Test-only, 8 lines in b2/bucket_mapping_edges_test.go. The leader's reauthorization now never gets an answer while the test runs. The handler waits on a channel that is closed at test cleanup, so the leader can only end through its cancelled context. That cleanup is registered after b2wiretest.New, so it runs before the recording server's own cleanup (t.Cleanup runs in reverse order), which waits for active handlers to return.

Verification

  • go test -race -count=500 -run '^TestMappingReauthWaiterSurvivesCancelledLeader$' ./b2 passes.
  • The R4 break this test exists for (if flight.leaderContextExpired → if false in b2/backend.go) now fails 50 out of 50 runs: waiter error = context canceled, want nil. It passes when restored.
  • go test -race -count=3 -shuffle=on ./b2 passes, and make ci passes, with B2_APPLICATION_KEY_ID, B2_APPLICATION_KEY, B2_ACCOUNT_ID and B2_ACCOUNT_KEY unset.

Notes for reviewers

Closes #237

The fake b2_authorize_account handler held the leader's reauthorization
until the leader was cancelled, then still answered it with success and
the expired token. If that response beat the client's cancellation, blazer
correctly recorded a successful refresh with the stale token, the waiter
reused it, and the test failed with 401 expired (seen once in CI).

Never answer the leader's reauthorization while the test runs; release it
at cleanup, which runs before the recording server's own cleanup. The
leader now always ends through its cancelled context, and the R4 break
(ignoring leaderContextExpired) fails the test on every run.

Closes #237
@ffumero2003 ffumero2003 added this to the 0.10.0 milestone Oct 29, 2026
@ffumero2003 ffumero2003 added the skip-changelog No changelog entry needed; skips the changelog check label Oct 29, 2026
@ffumero2003 ffumero2003 self-assigned this Oct 29, 2026
@goanpeca
goanpeca requested a balanced review from Copilot October 29, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified, though tests were not independently run.

No open issues 🎉

What changed in this PR

No issues found. This test-only change addresses #237 by removing the response-versus-cancellation race in the reauthorization waiter regression test. Production behavior is unchanged.

Changes:

  • Block the leader’s authorization handler until test cleanup, ensuring cancellation ends its request.
  • Release the handler before server cleanup to avoid hanging teardown.

Checked the supplied diff; tests were not independently run.

File Description
b2/​bucket_mapping_edges_test.go Adds a cleanup-controlled channel and documents why the blocked authorization must not respond during the test.

Review effort: Balanced

@ffumero2003
ffumero2003 merged commit fb84c54 into main Oct 30, 2026
26 checks passed
@ffumero2003
ffumero2003 deleted the fix-b2-issue-237-reauth-test-flake branch October 30, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog No changelog entry needed; skips the changelog check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(b2): make the reauth waiter test deterministic (flaky in CI)

3 participants