Skip to content

test(launcher): make WaitForURL late-bind test immune to port reuse - #1816

Merged
Dumbris merged 2 commits into
mainfrom
claude/admiring-cartwright-5b1bfa
Nov 2, 2026
Merged

Dumbris merged 2 commits into
mainfrom
claude/admiring-cartwright-5b1bfa

Conversation

@Dumbris

@Dumbris Dumbris commented Nov 2, 2026

Copy link
Copy Markdown
Member

Summary

  • TestWaitForURL_BoundLate reserved 127.0.0.1:0, closed it, then re-bound 400 ms later. On CI another process/test took the port first (bind: address already in use, seen on fix(scanner): inspect only the scanned server's tools, keep peers as index context #1812), failing the E2E job.
  • NeverBound and ContextCanceled used the same reserve-and-release pattern and could pass/fail spuriously if a stray listener took the port.
  • Fix: drive WaitForURLWithDial with a dial func that refuses (ECONNREFUSED) until a deadline. BoundLate holds its listener for the whole test so the port can't be stolen; the other two use no real port. Portable across darwin/linux/windows (cross-vet clean). WaitForURL itself is unchanged, so no CHANGELOG entry.

Test plan

  • go test -race -count=50 -run TestWaitForURL ./internal/upstream/launcher/
  • go test -race ./internal/upstream/launcher/
  • golangci-lint run --config .github/.golangci.yml ./internal/upstream/launcher/ — 0 issues
  • GOOS=windows go vet, GOOS=linux go vet

🤖 Generated with Claude Code

TestWaitForURL_BoundLate reserved a port, released it, and re-bound it
400ms later; under parallel `go test -race ./...` another process grabbed
the port in that window ("bind: address already in use"). NeverBound and
ContextCanceled used the same reserve-and-release pattern and could pass or
fail spuriously if a stray listener took the port.

Drive WaitForURLWithDial through a dial func that refuses until a deadline
instead. BoundLate keeps its listener bound for the whole test so the port
cannot be stolen; the other two no longer touch a real port. No change to
WaitForURL itself.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 187b4af
Status: ✅  Deploy successful!
Preview URL: https://e5e1f143.mcpproxy-docs.pages.dev
Branch Preview URL: https://claude-admiring-cartwright-5.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📦 Build Artifacts

Workflow Run: View Run
Branch: claude/admiring-cartwright-5b1bfa

Available Artifacts

  • archive-darwin-amd64 (32 MB)
  • archive-darwin-arm64 (29 MB)
  • archive-linux-amd64 (20 MB)
  • archive-linux-arm64 (18 MB)
  • archive-windows-amd64 (32 MB)
  • archive-windows-arm64 (28 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (28 MB)
  • installer-dmg-darwin-arm64 (25 MB)
  • smart-mcp-proxymcpproxy-goQUF1LR.dockerbuild (0 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 41474934043 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

BoundLate now refuses a fixed number of initial dial attempts (not a
wall-clock window) and asserts exactly refusals+1 attempts, with generous
timeouts. NeverBound only asserts the one guaranteed attempt, since a
loaded runner may delay the goroutine past the short deadline after a
single dial; its upper elapsed bound is also loosened.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Dumbris
Dumbris enabled auto-merge (squash) November 2, 2026 17:45
@Dumbris
Dumbris merged commit c320362 into main Nov 2, 2026
46 of 47 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.

2 participants