Skip to content

fix(test): stop asserting a freed ephemeral port stays free - #1399

Merged
zackees merged 1 commit into
mainfrom
fix/ipc-readiness-port-reuse-race
Aug 24, 2026
Merged

fix(test): stop asserting a freed ephemeral port stays free#1399
zackees merged 1 commit into
mainfrom
fix/ipc-readiness-port-reuse-race

Conversation

@zackees

@zackees zackees commented Aug 24, 2026

Copy link
Copy Markdown
Member

Symptom

tcp_readiness_distinguishes_live_and_free_endpoints failed on a macOS
runner, on #1398 — a PR touching only fbuild-library:

assertion failed: !tcp_endpoint_ready(address, Duration::from_millis(100)).await

The probe is right; the test was wrong

tcp_endpoint_ready is a plain connect-with-timeout:

matches!(
    tokio::time::timeout(timeout, tokio::net::TcpStream::connect(address)).await,
    Ok(Ok(_))
)

So "ready" means something genuinely accepted a connection. The test then
asserts that after drop(listener), nothing will.

That is not a property the OS guarantees. Once the listener is dropped the
port returns to the ephemeral pool and can be handed to anyone — including
a sibling test in this same binary calling
bind_tcp_listener("127.0.0.1:0"), since tests run in parallel. When that
happened the probe correctly reported "ready" and the assertion blamed the
probe.

Fix

The live half is sound as a single sample — we hold the listener, so
nothing else can be answering. Unchanged.

The dead half now retries with a freshly-bound-then-dropped port each
attempt. A real defect in the probe fails all eight; a port-reuse collision
would have to win the race eight times running.

What this is not

It is not a >=-style loosening. The assertion still fails if a closed
endpoint ever reads as ready — that property is intact and is the one worth
having. What changed is how many samples it takes before concluding it, because
one sample cannot distinguish "the probe is broken" from "someone took the
port"
. Those need different fixes, and the old test reported the second as
the first.

Verification

A timing race can't be proven fixed by a green run; the argument is that the
test no longer asserts something the OS is free to violate.

Summary by CodeRabbit

  • Bug Fixes
    • Improved TCP readiness checks to more reliably distinguish active endpoints from closed or unavailable ports.
    • Reduced false-positive readiness results caused by port reuse and timing-related races.

`tcp_readiness_distinguishes_live_and_free_endpoints` failed on a macOS
runner, on a PR touching only fbuild-library:

    assertion failed: !tcp_endpoint_ready(address, Duration::from_millis(100)).await

The probe was right and the test was wrong. `tcp_endpoint_ready` is a plain
connect-with-timeout, so reporting "ready" means something genuinely
accepted. Once the listener is dropped the port returns to the ephemeral
pool and the OS may hand it to anyone — including a sibling test in the same
binary calling `bind_tcp_listener("127.0.0.1:0")`, since these run in
parallel. The test asserted a property the OS does not guarantee, then blamed
the probe when the OS exercised its freedom.

The live half is sound as a single sample: we hold the listener, so nothing
else can answer. Only the dead half needed changing — it now retries with a
freshly-bound-then-dropped port each attempt. A real defect in the probe
fails all eight; a port-reuse collision would have to win the race eight
times running.

Deliberately not a `>= `-style loosening of what is asserted: the assertion
still fails if a closed endpoint ever reads as ready, which is the property
worth having. What changed is the number of samples it takes before
concluding that, because one sample cannot distinguish "probe is broken"
from "someone took the port".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c8b85935-5f51-4459-b2cc-168d954f6beb

📥 Commits

Reviewing files that changed from the base of the PR and between ea2a8ff and 2f74574.

📒 Files selected for processing (1)
  • crates/fbuild-core/src/platform/ipc.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The TCP readiness test now retries checks against freshly bound and dropped ephemeral ports. It returns when readiness correctly fails and panics only when all attempts incorrectly report readiness.

Changes

TCP readiness test

Layer / File(s) Summary
Retry closed-endpoint probes
crates/fbuild-core/src/platform/ipc.rs
The closed-endpoint check performs up to eight probe-and-rebind attempts. It tolerates port-reuse races and fails only when every readiness probe succeeds.

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

Merge Risk: ⚪ Minimal · up to 2f745

This localized test-only change replaces a flaky assertion about ephemeral port reuse with repeated fresh-port checks while preserving the readiness behavior being tested; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the test change to avoid asserting that a freed ephemeral port remains unused.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ipc-readiness-port-reuse-race

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

Comment @coderabbitai help to get the list of available commands.

@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Aug 24, 2026
@zackees
zackees merged commit a287987 into main Aug 24, 2026
21 checks passed
@zackees
zackees deleted the fix/ipc-readiness-port-reuse-race branch August 24, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant