Skip to content

test(relay): the embed socket check matches each port's own protocol - #8236

Merged
kixelated merged 3 commits into
mainfrom
quest/m0/test-flakes-2/embed-sockets-outlived
Nov 8, 2026
Merged

kixelated merged 3 commits into
mainfrom
quest/m0/test-flakes-2/embed-sockets-outlived

Conversation

@kixelated

@kixelated kixelated commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m0/test-flakes-2/embed-sockets-outlived.md.

Summary

The relay doesn't leak a socket. The test's ownership check was wrong.

bound(port) in rs/moq-relay/tests/integration/embed.rs collected every UDP socket and every TCP listener on a port number, for both the QUIC port and the HTTP port. UDP and TCP number their ports separately. So the test's own QUIC client counted as "owned by the relay" whenever its ephemeral UDP port happened to equal the relay's ephemeral TCP HTTP port. That client is still draining after drop(subscriber), so it is still open when run returns, and the check fails with "the owner's sockets outlived run". The chance is about 1 in 28k per run (the size of the ephemeral range), which fits a single CI hit with no local repro.

The fix: bound(kind, port) matches UDP sockets only on the QUIC port and TCP listeners only on the HTTP port. The #[ignore] and its sh/gh/test-inventory.allow entry are removed. The allow file's "Flaky" header had no entries left, so it is gone too.

Evidence

  • No natural repro: 150 runs of the whole embed:: module, then 1920 single-test runs of the worker variant (32 concurrent processes on a 24-core host at load ~27, like nextest's process-per-test). Zero socket failures.
  • Reading the worker teardown (moq_tokio::worker::Group::shutdown, the worker thread's runtime drop, EndpointDriver's Slot::release, and the shard Bound's dup'd fds) found no socket that outlives the join.
  • Forced repro: binding the test client to 127.0.0.1:<http port> fails both shared_tokio_custom_route_and_quic and worker_tokio_custom_route_and_quic every time, with the exact CI panic. The same forced setup passes all three variants (shared, worker, uring) once the fix is in.
  • After the fix, under the same 32-process load: shared 960/960 and worker 960/960. Uring passed 345/345 whenever it got a ring. Its other runs failed on this host's 8 MiB RLIMIT_MEMLOCK, which sh/rs/nextest.sh raises in CI, and none of those failures came from the socket check.
  • cargo fmt --all --check and cargo clippy -p moq-relay --all-targets --all-features -D warnings both pass.

moq-dev/moq#8208 (transport close) doesn't overlap: this was a test-check bug, not a transport-close bug, and the two PRs touch different files.

Choices made without asking

  • The fix is in the check, not in run, because the quest allowed either and the evidence points to the check.
  • Protocol is passed as socket2::Type rather than splitting into two helpers, which keeps one function.

Public API: none. Wire: none.

Models

Size: S
Implementer: Claude Code, claude-opus-5-5, medium effort

(Written by Claude Opus 5.5 with medium)

Review

Rewritten by quest review after each round.

  • Reviewer: Codex, gpt-6.1-sol, high effort
  • Session: 01a1b8e8-885b-7461-a97a-f0ee903b57ef, round 1
  • Head: e452261
  • Base: origin/main at 544f144
  • Score: 9/10, The protocol-specific filtering fixes the false ownership match while preserving relay socket-closure assertions, and appears sound from source inspection; builds and tests were not run as instructed.
  • Findings: none

Head ce14d50 only merges origin/main, hand-resolving sh/gh/test-inventory.allow to keep main's new gst quarantine. Its added and removed lines match the reviewed head e452261 exactly.

kixelated and others added 2 commits November 7, 2026 17:19
`bound` collected every UDP socket and TCP listener on a port number,
so the test's own QUIC client, still draining after `drop(subscriber)`,
counted as the relay's whenever its UDP port matched the HTTP
listener's TCP port. UDP and TCP number ports separately: match UDP on
the QUIC port and TCP listeners on the HTTP port. Re-enables
`embed::worker_tokio_custom_route_and_quic`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title The embedded relay's sockets are closed when run returns test(relay): the embed socket check matches each port's own protocol Nov 8, 2026
@kixelated
kixelated marked this pull request as ready for review November 8, 2026 02:07
@coderabbitai

coderabbitai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 4 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8cda7565-2993-4236-9b9c-b3029ea0a5a2
Commits

Reviewing files that changed from the base of the PR and between 544f144 and ce14d50.

Files selected for processing: 4

  • quest/m0/test-flakes-2/README.md
  • quest/m0/test-flakes-2/embed-sockets-outlived.md
  • rs/moq-relay/tests/integration/embed.rs
  • sh/gh/test-inventory.allow
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

…2/embed-sockets-outlived

# Conflicts:
#	sh/gh/test-inventory.allow

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed e452261.

No actionable findings. Filtering by socket type as well as port fixes the false ownership match: the HTTP listener's TCP port must not collect a draining QUIC client's UDP socket with the same number. The shared helper still captures every matching QUIC socket and only TCP listeners, then checks those original inodes after run returns. This preserves the shutdown assertion across shared Tokio, worker Tokio and io_uring rather than adding a delay or changing runtime teardown.

Direction: correcting the ownership check and restoring the quarantined test is appropriate. The forced-collision and stress results in the PR remain author-provided evidence.

Verification limits: GitHub-only static review of the four-file diff and complete embedding test, including descriptor duplication, protocol selection and shutdown assertions. No tests, stress reproduction or runtime teardown validation performed. Rechecked open/non-draft state, full head and published reviews immediately before this COMMENT.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • bound now takes a socket type — rs/moq-relay/tests/integration/embed.rs matches DGRAM sockets only for the QUIC port and STREAM listeners only for the HTTP port, so a still-draining test client's UDP socket can no longer be counted as the relay's when its ephemeral port coincides with the HTTP listener's TCP port. Keeping is_listener() also preserves the rule that accepted TCP connections are not the owner's.
  • Quarantine removed — the #[ignore] is gone from worker_tokio_custom_route_and_quic, so the Linux CI lane exercises it again. Capturing owned after the session still catches worker-mode SO_REUSEPORT sockets, which are bound lazily at serve time.
  • Inventory and quest tree cleaned up — the sh/gh/test-inventory.allow entry and its now-empty header are removed (the script errors once an allow-listed test is no longer ignored, and it validates the quest path), the completed quest file is deleted, its ## Required bullet is dropped, and the epic README records the diagnosis with a link to this PR. No remaining references to the deleted file were found.

The branch advanced to ce14d50 (a merge of origin/main 544f144) during this run; comparing that head against the new base shows the same four files and the same line counts, so this review covers it. CI Check, the only lane that runs this test, was still in progress on that head, so the re-enabled test had not yet completed a CI run.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • Only ce14d50 landed since the prior pullfrog review — a merge of origin/main (544f1441), not a code change. Compared against the new base it touches the same four files with the same +14/−57, and the test binary (rs/moq-relay/tests/integration/embed.rs) is byte-identical to the reviewed head.
  • The hand-resolved docs kept main's additions — the merge preserved main's new moq-gst stale-completion entries in sh/gh/test-inventory.allow and the epic README while still removing the embed entry, its "Flaky" header, the ## Required bullet, and the completed quest file.

The review of the actual fix stands unchanged.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit b9901ad Nov 8, 2026
8 of 9 checks passed
@kixelated
kixelated deleted the quest/m0/test-flakes-2/embed-sockets-outlived branch November 8, 2026 05:57
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