Skip to content

fix: gate federated conversation create on assertFullyConnected - #5430

Open
blackheaven wants to merge 2 commits into
developfrom
gdifolco/fix-flaky-tests-testAddUnreachableUserFromFederatingBackend
Open

fix: gate federated conversation create on assertFullyConnected#5430
blackheaven wants to merge 2 commits into
developfrom
gdifolco/fix-flaky-tests-testAddUnreachableUserFromFederatingBackend

Conversation

@blackheaven

Copy link
Copy Markdown
Contributor

Checklist

  • Add a new entry in an appropriate subdirectory of changelog.d
  • Read and follow the PR guidelines

Conversation.testAddUnreachableUserFromFederatingBackend[domain=other]
flaked in CI: the conversation create (Test/Conversation.hs) returned HTTP
533 ({unreachable_backends: [<fed2 domain>]}) instead of 201. The 7s test
duration (vs sub-second normally) is consistent with a federation RPC
timeout. The freshly-started dynamic backend C was reachable; only the
always-on static fed2 was reported unreachable -- a transient reachability
blip, not a correctness bug.

Root cause: this test's conversation spans two remote backends concurrently
-- bob on the static fed2 (otherDomain) and charlie on the dynamic backend
C. Conversation creation pings every remote backend concurrently and fails
closed with no retry:

  registerRemoteConversationMemberships
    -> ensureNoUnreachableBackends =<< runFederatedConcurrentlyEither
       (Wire/ConversationSubsystem/Util.hs:833-835)

which throws UnreachableBackends (-> 533, Wire/API/Error/Galley.hs:583-584)
and deletes the half-created conversation (deleteOnUnreachable,
Util.hs:897-905). Creation staying strict is deliberate (WPB-5208 relaxed
reachability only for adding members), so the fix belongs at the test
layer.

Add a reusable readiness gate `assertFullyConnected` in
API.GalleyInternal (polls getFederationStatus until HTTP 200 +
"fully-connected" via `eventually`, which retries on AssertionFailure every
100ms up to Env.timeOutSeconds) and call it before the create.
getFederationStatus pings the same backends and reuses the same reachability
verdict (ensureNoUnreachableBackends) the create will run, and the gate
covers exactly the create's backend set {ownDomain, otherDomain,
cDom.berDomain}. The downstream addMembers 533 assertion (targeting the
stopped dynamic C) is deterministic and unaffected.

A genuine fed2 outage is not masked: if fed2 stays down the gate never
reaches fully-connected within eventually's window and the test fails loudly
at assertFullyConnected (issuing no postConversation, so no create/delete
churn). A residual sub-second TOCTOU race between gate and create remains;
if CI shows it still bites, wrap gate+create together with retryT (not
eventually, since the create can throw a non-AssertionFailure exception).

Runtime trace excerpt:
  assertion failure: Actual: 533 / Expected: 201
  response body: { unreachable_backends: [ <fed2 domain> ] }
@blackheaven
blackheaven requested a review from a team as a code owner August 10, 2026 14:56
@zebot zebot added the ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants