Summary
Eight files pick a listen port as 30000 + Math.floor(Math.random() * 10000) with no retry and no port-0 bind. A collision fails listen(), and the test reads as flake — so the natural response is a retry, which is exactly the wrong instinct.
Context
Background
Found while verifying #173. A bun run test:tiers --all run failed with integration.bun-test — exit code 1. It did not reproduce: the tier passed 5/5 standalone, 3/3 through the tier runner, and 3/3 tiers together. The failing run took 10776ms against a normal 4633ms, which is the signature of a bind failure and retry-free abort rather than a slow assertion.
The change under test (tools/analysis/src/extract/handlers.ts) cannot reach tests/integration/ — those are relay and signalling tests and none imports the extractor. The failure was pre-existing.
This is the same shape as #173: a real defect that presents as flake, where retrying makes it worse rather than better.
Current State
packages/polly/tools/test/src/e2e-mesh/with-relay.ts:47-51 states the risk and accepts it:
function pickPort(): number {
// Same window the integration suite uses. Random port collision is
// possible but rare; e2e scripts run sequentially by default so the
// failure surface is small.
return 30000 + Math.floor(Math.random() * 10000);
}
That reasoning holds for the e2e scripts it was written for. It does not hold for tests/integration/, where 27 pickPort() call sites run in one bun test process:
| file |
call sites |
tests/integration/signaling-server.test.ts |
5 |
tests/integration/peer-repo-relay.test.ts |
4 |
tests/integration/peer-state-resilience.test.ts |
4 |
tests/integration/peer-state-relay.test.ts |
2 |
tests/integration/signaling-client-reconnect.test.ts |
2 |
tests/integration/signaling-custom-frames.test.ts |
2 |
tests/integration/signaling-peer-notifications.test.ts |
2 |
27 draws from a 10,000-port window is a 3.45% self-collision probability per integration run (birthday bound, 1 - exp(-n(n-1)/2N)). That is a lower bound: it counts only the suite colliding with itself, not with Docker, dev servers, or anything else holding a port in 30000–39999. This machine runs Docker containers continuously.
No site retries. signaling-server.test.ts:118 is representative:
const port = pickPort();
const app = new Elysia().use(signalingServer({ path: "/polly/signaling" })).listen(port);
Desired State
A test binds a port it is guaranteed to own. Port 0 asks the kernel for a free port and returns it, which removes the collision class entirely rather than making it rarer.
Requirements
Functional Requirements
Edge Cases
Acceptance Criteria
Implementation Notes
Files to Modify
packages/polly/tests/integration/signaling-server.test.ts:40 — definition; 5 call sites
packages/polly/tests/integration/peer-repo-relay.test.ts:52 — definition; 4 call sites
packages/polly/tests/integration/peer-state-resilience.test.ts:75 — definition; 4 call sites (two concurrent)
packages/polly/tests/integration/peer-state-relay.test.ts:81 — definition; 2 call sites
packages/polly/tests/integration/signaling-client-reconnect.test.ts:54 — definition; 2 call sites
packages/polly/tests/integration/signaling-custom-frames.test.ts:50 — definition; 2 call sites
packages/polly/tests/integration/signaling-peer-notifications.test.ts:41 — definition; 2 call sites
packages/polly/tools/test/src/e2e-mesh/with-relay.ts:47-51 and :86 — definition and listen
Suggested Approach
Bind port 0 and read back what the kernel assigned:
const app = new Elysia().use(signalingServer({ path })).listen(0);
const port = app.server?.port;
The server owns the port from the moment it is assigned, so there is no window in which another process can take it. That is strictly better than any retry loop, which only narrows the window.
Similar Patterns
packages/polly/tools/test/src/e2e-cli/with-temp-dir.ts:21-31 is the repo's mint-plus-cleanup shape (withTempDir(prefix) -> { dir, cleanup }). A withRelay-style helper returning { port, url, close } would match it — with-relay.ts already returns that shape and only needs its port source changed.
Dependencies
Out of Scope
- The
coverage.enforce timeout seen in the same run — filed separately
- Changing how the tier engine reports a failing case
- Port selection in
tools/test/src/browser/run.ts:84 unless it shares the helper naturally
Technical Notes
Observed across three bun run test:tiers --all runs on the same machine, same day:
| run |
integration tier |
| 1 |
pass, 4633ms |
| 2 |
fail, exit code 1, 10776ms |
| 3 |
pass, 5807ms |
Isolation runs after the failure: 5/5 pass via bun test --cwd tests integration, 3/3 pass via bun run test:tiers integration. The failure is load- and timing-dependent, not deterministic.
Summary
Eight files pick a listen port as
30000 + Math.floor(Math.random() * 10000)with no retry and no port-0 bind. A collision failslisten(), and the test reads as flake — so the natural response is a retry, which is exactly the wrong instinct.Context
Background
Found while verifying #173. A
bun run test:tiers --allrun failed withintegration.bun-test — exit code 1. It did not reproduce: the tier passed 5/5 standalone, 3/3 through the tier runner, and 3/3 tiers together. The failing run took 10776ms against a normal 4633ms, which is the signature of a bind failure and retry-free abort rather than a slow assertion.The change under test (
tools/analysis/src/extract/handlers.ts) cannot reachtests/integration/— those are relay and signalling tests and none imports the extractor. The failure was pre-existing.This is the same shape as #173: a real defect that presents as flake, where retrying makes it worse rather than better.
Current State
packages/polly/tools/test/src/e2e-mesh/with-relay.ts:47-51states the risk and accepts it:That reasoning holds for the e2e scripts it was written for. It does not hold for
tests/integration/, where 27pickPort()call sites run in onebun testprocess:tests/integration/signaling-server.test.tstests/integration/peer-repo-relay.test.tstests/integration/peer-state-resilience.test.tstests/integration/peer-state-relay.test.tstests/integration/signaling-client-reconnect.test.tstests/integration/signaling-custom-frames.test.tstests/integration/signaling-peer-notifications.test.ts27 draws from a 10,000-port window is a 3.45% self-collision probability per integration run (birthday bound,
1 - exp(-n(n-1)/2N)). That is a lower bound: it counts only the suite colliding with itself, not with Docker, dev servers, or anything else holding a port in 30000–39999. This machine runs Docker containers continuously.No site retries.
signaling-server.test.ts:118is representative:Desired State
A test binds a port it is guaranteed to own. Port 0 asks the kernel for a free port and returns it, which removes the collision class entirely rather than making it rarer.
Requirements
Functional Requirements
pickPort()with a helper that binds port 0 and reports the assigned porttests/integration/to use ittools/test/src/e2e-mesh/with-relay.ts:47to use it, and delete the comment that accepts the riskEADDRINUSEwith a bounded attempt count and fail with the bind error, not a timeoutEdge Cases
peer-state-resilience.test.ts:80-81bindsportAandportB): both must be distinct and both live at the same time — a helper that binds, reads the port and closes before the real listen reintroduces the race.listen(0): confirm the assigned port is readable from the app instance (app.server?.port) before any client connects0Acceptance Criteria
grep -rn "30000 + Math.floor" packages/pollyreturns nothingbun test --cwd tests integrationpasses 66/66bun run test:tiers --allpasses with the integration tier greenImplementation Notes
Files to Modify
packages/polly/tests/integration/signaling-server.test.ts:40— definition; 5 call sitespackages/polly/tests/integration/peer-repo-relay.test.ts:52— definition; 4 call sitespackages/polly/tests/integration/peer-state-resilience.test.ts:75— definition; 4 call sites (two concurrent)packages/polly/tests/integration/peer-state-relay.test.ts:81— definition; 2 call sitespackages/polly/tests/integration/signaling-client-reconnect.test.ts:54— definition; 2 call sitespackages/polly/tests/integration/signaling-custom-frames.test.ts:50— definition; 2 call sitespackages/polly/tests/integration/signaling-peer-notifications.test.ts:41— definition; 2 call sitespackages/polly/tools/test/src/e2e-mesh/with-relay.ts:47-51and:86— definition and listenSuggested Approach
Bind port 0 and read back what the kernel assigned:
The server owns the port from the moment it is assigned, so there is no window in which another process can take it. That is strictly better than any retry loop, which only narrows the window.
Similar Patterns
packages/polly/tools/test/src/e2e-cli/with-temp-dir.ts:21-31is the repo's mint-plus-cleanup shape (withTempDir(prefix) -> { dir, cleanup }). AwithRelay-style helper returning{ port, url, close }would match it —with-relay.tsalready returns that shape and only needs its port source changed.Dependencies
Out of Scope
coverage.enforcetimeout seen in the same run — filed separatelytools/test/src/browser/run.ts:84unless it shares the helper naturallyTechnical Notes
Observed across three
bun run test:tiers --allruns on the same machine, same day:Isolation runs after the failure: 5/5 pass via
bun test --cwd tests integration, 3/3 pass viabun run test:tiers integration. The failure is load- and timing-dependent, not deterministic.