Skip to content

fix(flaky): replace sleep-based races in service.waiters and service.auto-accept tests#85

Open
ggonzalez94 wants to merge 1 commit into
mainfrom
claude/quirky-euler-h0DHq
Open

fix(flaky): replace sleep-based races in service.waiters and service.auto-accept tests#85
ggonzalez94 wants to merge 1 commit into
mainfrom
claude/quirky-euler-h0DHq

Conversation

@ggonzalez94

Copy link
Copy Markdown
Owner

Summary

Fixes two known flaky tests documented in PR #79 ("two pre-existing flaky tests: service.waiters.test.ts, service.auto-accept.test.ts") and PR #81 ("290/291 — one pre-existing migrate-wallet flake").

Root cause

Both tests used hardcoded await sleep(50) to wait for async processing to complete before making assertions. Under CI resource contention (shared runners, parallel test suites), 50ms is insufficient for the executionMutex-gated connect() flow to register its waiter or for the async connection-request processor to send a rejection response.

Changes

service.waiters.test.ts — "clears all pending waiters when service.stop() is called"

  • Before: await sleep(50) — hopes 50ms is enough for connect() to acquire the mutex, persist the journal entry, register the waiter, and call transport.send()
  • After: await waitFor(() => transport.sentMessages.length === 1) — deterministically waits until the connection/request is sent, which happens immediately after waiter registration (the waiter is registered at line 1142 of service.ts, send at line 1150)

service.auto-accept.test.ts — "does not call onConnectionEstablished hook when invite is invalid"

  • Before: await sleep(50) — hopes 50ms is enough for the async reject path to complete
  • After: await waitForCondition("rejected connection/result sent", ...) — deterministically waits until the rejection connection/result appears in transport.sentMessages, proving the async processing completed before checking the negative assertion

Not addressed

The migrate-wallet.test.ts flake (PR #81) is caused by OWS vault contention from parallel vitest workers sharing a file-backed wallet store. That requires deeper changes to OWS isolation and is out of scope here.

Test plan

  • Both fixed tests pass 5/5 runs in isolation
  • Full test suite passes (1172 passed, 37 skipped)
  • bun run lint clean
  • bun run typecheck clean
  • "clears all pending waiters" now runs in ~16ms instead of ~57ms (no wasted sleep)

https://claude.ai/code/session_01VKaHZFWnzKZmN1paVHxdQK


Generated by Claude Code

…vice tests

service.waiters.test.ts "clears all pending waiters" and
service.auto-accept.test.ts "does not call hook when invite is invalid"
used hardcoded `sleep(50)` to wait for async processing. Under CI load
50 ms is not enough for the execution mutex to release, so the tests
intermittently fail. Replace both sleeps with condition-based polling:
observe the transport's sent-message count (waiter test) or the
rejection result delivery (auto-accept test) to make assertions
deterministic regardless of scheduler timing.

https://claude.ai/code/session_01VKaHZFWnzKZmN1paVHxdQK

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9f2078b53

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +422 to +423
await waitForCondition("rejected connection/result sent", () =>
transport.sentMessages.some((m) => m.message.method === "connection/result"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require the rejected status before asserting the hook stayed idle

In this test, the predicate accepts any connection/result, including an accidental accepted result. The accepted path sends the result before it writes the contact and awaits onConnectionEstablished, so this wait can return as soon as FakeTransport.send() records the message and the negative assertion can run before the hook is invoked. In the invalid-invite scenario this means a regression that accepts the invite could pass; check the result params/status is "rejected" before returning from the wait.

Useful? React with 👍 / 👎.

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.

2 participants