Skip to content

fix(xmtp_mls): stabilize flaky test_hmac_and_consent_preference_sync#3834

Draft
insipx wants to merge 1 commit into
xmtp:mainfrom
insipx:fix/issue-3749
Draft

fix(xmtp_mls): stabilize flaky test_hmac_and_consent_preference_sync#3834
insipx wants to merge 1 commit into
xmtp:mainfrom
insipx:fix/issue-3749

Conversation

@insipx

@insipx insipx commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Resolves #3749

Problem

worker::device_sync::tests::test_hmac_and_consent_preference_sync intermittently timed out waiting for the ConsentReceived metric to reach 2, panicking with Err(Expired) (previously reported as FLAKY 2/4).

Root cause (test-only race)

The second consent phase did:

alix1_group.update_consent_state(ConsentState::Allowed)?;   // async publish by alix1's worker
alix2.sync_all_welcomes_and_groups(None).await?;            // one-shot pull
alix2.worker().register_interest(SyncMetric::ConsentReceived, 2).wait().await?;

update_consent_state only queues work for alix1's device-sync worker, which publishes the consent update to the sync group asynchronously (incrementing ConsentSent). register_interest(...).wait() waits passively on the receiver metric — it does not itself drive any re-sync — so alix2's single sync_all_welcomes_and_groups call is the only opportunity to pull the second consent. That call filters out groups with no new server activity (filter_groups_needing_sync); if alix2 syncs before alix1's consent message lands on the server, the device-sync group is filtered out, alix2 never pulls the update, and ConsentReceived stays at 1 until the 10s timeout.

The first consent phase in the same test already guards against this by waiting for ConsentSent before the receiver syncs — the second phase simply omitted the same barrier.

Fix

Add the same barrier (clear → update → wait for ConsentSent) before alix2's sync, mirroring the first-consent phase. clear_metric runs before update_consent_state so the wait targets the Allowed publish specifically. Production code is untouched.

Verification

  • just test v3 test_hmac_and_consent_preference_sync20/20 stress runs pass.
  • just lint-rust (clippy -Dwarnings, fmt, hakari) passes clean.

🤖 Generated with Claude Code

Note

Stabilize flaky test_hmac_and_consent_preference_sync by awaiting consent propagation

The test had a race condition where alix2's sync could run before the consent update was visible on the server, causing the ConsentReceived wait to fail intermittently. Fixes this by clearing the ConsentSent metric, updating consent state, then awaiting one ConsentSent event before triggering alix2's sync in tests.rs.

Macroscope summarized 856aad1.

The second consent phase of this test did not wait for alix1 to publish
the consent update (SyncMetric::ConsentSent) before alix2 performed its
one-shot `sync_all_welcomes_and_groups`. Because
`register_interest(ConsentReceived).wait()` only waits passively on the
receiver metric and never drives a re-sync, that single sync was alix2's
only chance to pull the second consent. When it ran before alix1's
consent message landed on the server, `sync_all_welcomes_and_groups`
filtered the device-sync group out as "no new activity", so
ConsentReceived never reached 2 and the test timed out with Err(Expired).

Add the same ConsentSent barrier (clear -> update -> wait) the first
consent phase already uses, so the receiver sync is guaranteed to observe
the message. Test-only change; verified 20/20 stress runs pass.

Resolves xmtp#3749

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky CI Failure: test_hmac_and_consent_preference_sync times out waiting for ConsentReceived

1 participant