Skip to content

test(agents): the listener check-in test waits for the write, not a fixed 150 ms - #3452

Merged
lilyshen0722 merged 1 commit into
mainfrom
cto/agent-states-test-settle
Nov 4, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
cto/agent-states-test-settle

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Why

agent-states-listener-check-in.test.js › "an MCP call alone is never-connected; a check-in on the User token flips it to listening" failed in two of the last five merge-queue runs on 11-04 (runs 41922149243 and 41923958639) with Expected: "listening" / Received: "never-connected", and dequeued unrelated PRs (#3446 twice).

The check-in write is fire-and-forget, and the test slept a fixed 150 ms before reading the route. That race is lost under queue load: it's the file's first test, running while #3443's new AgentEvent index builds. It is not a regression: it passes 3 of 3 on main locally, and main's push-run Backend tests are green, per SRE.

Change (test only)

The test now waits until the lastListenedAt stamp is in the database (Model.exists, polled every 25 ms, for up to 5 s), then reads the route once. Polling the route itself was tried first: it trips the route's rate limit (429).

Proof

  • Green: 3 of 3 local runs pass.
  • Reverse: with both recordListenerCheckIn calls removed, both tests still fail (Received: "never-connected"), so the wait can't hide a check-in that never writes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MDs9DPFVAooJnqCSwrdxVw

…ixed 150 ms

The check-in write is fire-and-forget, and the test slept 150 ms before
reading the route. In the merge queue on 11-04 that lost the race in two of
five runs (the file's first test, while a new AgentEvent index built),
dequeuing unrelated PRs. It now waits until the stamp is in the database,
up to 5 s, then reads the route once. Polling the route itself trips its
rate limit (429). A check-in that never writes still fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDs9DPFVAooJnqCSwrdxVw
@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The tests replace a fixed 150 ms delay with polling for lastListenedAt on the User or AgentInstallation record. Polling checks every 25 ms for up to five seconds.

Changes: Listener check-in tests

Layer / File(s) Summary
Poll for check-in timestamps
backend/__tests__/service/agent-states-listener-check-in.test.js
The helper polls for a matching record every 25 ms, up to five seconds. Both token tests wait for lastListenedAt to become non-null before asserting that the route reports listening.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Other

Possibly related PRs

Merge Risk: Minimal · up to d9b1a

This test change removes timing dependence while retaining failure detection for missing check-ins, so it is mergeable with normal checks.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title names the change accurately: the listener check-in test now waits for the database write instead of a fixed 150 ms delay. It is specific and matches the changeset. The title uses the convent…
Description check Passed The description is directly related to the changeset. It explains the flaky agent-states-listener-check-in test, the fixed 150 ms sleep race, and the fix that polls Model.exists every 25 ms for up to …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the change accurately: the listener check-in test now waits for the database write instead of a fixed 150 ms delay. It is specific and matches the changeset. The title uses the conventional test(agents): prefix, which is acceptable. Its length (80 characters) is at the upper end, but it remains a single clear sentence.

Full details: Description check

Explanation

The description is directly related to the changeset. It explains the flaky agent-states-listener-check-in test, the fixed 150 ms sleep race, and the fix that polls Model.exists every 25 ms for up to 5 s. It also covers the rejected route-polling approach (429), the local test runs, and the reverse check that removes both recordListenerCheckIn calls.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1b84804 and d9b1acf.

Files selected for processing: 1
  • backend/__tests__/service/agent-states-listener-check-in.test.js

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

HEAD: d9b1acf — GATE: PASS

One quick review round (Tier 0, test only).

  • The wait proves what the route reads. /agent-states → deriveAgentState → latestListen reads lastListenedAt straight from Mongo on AgentInstallation.runtimeTokens and on the bot User's agentRuntimeTokens, with no cache in between. Test 1 waits on the User field, which is the only source there, because its installation has no tokens. Test 2 waits on the installation field. $ne: null excludes both a missing field and a null one.
  • The filters are specific. Each test filters on a name only it uses (mcp-only, install-only), and neither row can match the other's filter.
  • A write that never lands still fails. landed returns after 5 s, then the route assertion fails with never-connected. That's under the 30 s testTimeout. The PR's reverse check confirms it.
  • Flake risk is low. There's a single route read, so no rate limit; the throttle resets beforeEach; and each update is atomic.

GATE: PASS

@lilyshen0722
lilyshen0722 added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit 2c18c37 Nov 4, 2026
34 checks passed
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.

1 participant