flake: TestRoutingPodEndToEnd port-wait deadline exceeded under load #15
Closed
opened 2026-05-18 15:23:58 +00:00 by mathias
·
1 comment
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#15
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom
TestRoutingPodEndToEndincmd/routing/main_test.gointermittently fails at line 58 with:The 5s deadline is
waitForPort(t, "127.0.0.1:33310", 5*time.Second)(main_test.go:58, 85–104) waiting for the freshly-built routing binary to bind its HTTP listener.Observed during #14 e2e work (2026-05-18)
Failed twice in a row:
task check(full project test suite with-race -count=1)go test -race -count=1 ./cmd/routing/...immediately afterBoth at ~5.23s. Then it stopped reproducing — 5/5 passes in isolation with
-race -count=1, including with cold test cache (go clean -testcache).Pattern: triggered under load, not by code.
Likely causes (untriaged)
go buildcost inside the test.buildRouting(t)compiles./cmd/routinginto a temp dir. Cold build +-raceinstrumentation can take >5s on a loaded machine. Running the produced binary directly outside the test starts in <2s, so the bottleneck is build, not bind.ss -tlnp | grep 33310was empty when checked, but a previous TIME_WAIT or another test could collide.osPath()returns empty PATH. Lines 116–122 iterateexec.Command("env").Envwhich is the child Cmd's env (nil unless set), not the parent's. The test passesPATH=(empty) to the routing subprocess. The binary doesn't need PATH at runtime (statically linked Go), so this is probably benign — but it is incorrect and worth fixing while we're here.Proposed fix
Cheap, low risk:
waitForPortdeadline to 30s (cost only paid on failure paths).33310with anet.Listen("tcp", ":0")random port allocation passed viaROUTING_PORTenv.osPath()to read parent process env viaos.Getenv("PATH")(or just drop the explicitPATH=and rely oncmd.Envinheriting).Acceptance criteria
go test -race -count=10 ./cmd/routing/...is greentask checkis green across 3 consecutive runsosPath()either correct or removedReferences
cmd/routing/main_test.go:30–80— test bodycmd/routing/main_test.go:85–104—waitForPortcmd/routing/main_test.go:116–122—osPath937355c).Fixed in
fe18e4e.Root cause (confirmed)
All three suspects from the issue body played a role:
task checkparallel package execution another test or stray process could hold the port long enough that the routing binary bound it late or failedListen. NowfreePort(t)grabs:0, releases, passes the OS-assigned port viaROUTING_PORT.waitForPortdeadline — too tight whengo build -raceruns cold under load. Bumped to 30s; only paid in failure mode.osPath()always returned empty — iteratingexec.Command("env").Envreads the childCmd's env (nil), not the parent's. The binary worked anyway (static Go), but the helper was a no-op masquerading as PATH inheritance. Replaced with explicitPATH=+HOME=viaos.Getenv.Why not
os.Environ()for full inheritanceTried that first. It leaked
ROUTING_MCP_TOKENfrom my shell into the test subprocess, flipping the routing pod into bearer-auth-required mode → all calls401 unauthorized. Explicit minimal env keeps the test hermetic.Verification
Diff: +28/-16, single file
cmd/routing/main_test.go.Closing.