Repository navigation
test(ci): keep Chromium's random local ports off test loopback connects on Windows - #553
Conversation
…ts on Windows Chromium 139+ sets SO_RANDOMIZE_PORT on every TCP socket on Windows 11 22H2 and later, which includes the Windows Server 2025 runners. When the random local port collides, connect() fails at once with WSAENOBUFS and the page sees net::ERR_NO_BUFFER_SPACE, even against a loopback dev host with no socket leak. The reference theme browser job hit it in two different specs. The browser suites now launch Chromium with TcpPortRandomizationWin disabled on Windows. Chromium keeps only the last --disable-features switch, so the helper reads Playwright's own list from the launched command line and extends it instead of replacing it. Refs #544
|
Local |
|
CI on e3288d8: The Playwright e2e step reported flaky tests that passed on retry: 3 in the push run and 1 in the pull_request run. All of them failed in Playwright's Node-side |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
# Conflicts: # packages/widget-cli/test/service-simulator-real-browser.e2e.spec.ts
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
|
Review attestation: ready to merge at A push to this PR makes this attestation stale; the new head needs its own review. |
Refs #544
Cause
The
ERR_NO_BUFFER_SPACEfailures inreference theme browser (windows-latest)do not come from sockets leaking or running out. They come from Chromium's local-port randomization on Windows.SO_RANDOMIZE_PORTbefore every TCP connect on Windows 11 22H2 and later (kTcpPortRandomizationWin, enabled by default, minimumWIN11_22H2;net/socket/tcp_socket_win.cc,net/base/features.cc). The runner is Windows Server 2025 (windows-2025-vs2026, build 26100), so it is affected. Chromium's Intent to Ship names rapid port reuse (the birthday problem) as the known risk.connect()fails at once with WSAENOBUFS, which the page reports asnet::ERR_NO_BUFFER_SPACE. Both CI failures were the first navigation of a test, 63 ms and 415 ms in, which fits an immediate connect failure rather than gradual exhaustion.Evidence (Windows 11 build 26200, Playwright 1.63 Chromium)
No leak, no exhaustion. I sampled
netstat -ano -p TCPevery 300 ms for loopback sockets during the job's commands. The dynamic port range is 16,384 ports.test:reference-theme-browser, before the fixtest:reference-theme-browser, after, 3 runstest:widget-browser, afterEvery host and browser is already closed in
afterEach/afterAll, and every SSE client is ended beforeserver.close(). No code path churns connections.Port randomization causes the error. I ran a stress harness with Playwright's Chromium against a loopback server, where each request makes a fresh TCP connect. The two arms were alternated run by run.
ERR_NO_BUFFER_SPACEERR_ADDRESS_IN_USE)TcpPortRandomizationWindisabledWhat changed
tools/chromium-test-args.ts(new) provideschromiumTestArgs(launcher). On Windows it returns one--disable-features=switch that holds Playwright's own disabled features plusTcpPortRandomizationWin. On other platforms it returns[].--disable-featuresswitch. I verified this with a third-party storage probe: Playwright's defaults gave"shared", and appending a bare--disable-features=TcpPortRandomizationWingavenull, because it silently re-enabledThirdPartyStoragePartitioning,PaintHolding,HttpsUpgradesand the rest. The helper therefore reads Playwright's list from the command line Chromium was actually launched with (Browser.getBrowserCommandLine, from one probe launch per process, Windows only) and extends that list. It does not copy the list, so it cannot drift. With the helper the probe gives"shared"again.widget-clireal-browser specs launch with these args:reference-theme-preview,semantic-composition,job-simulator,service-simulatoranddetach.playwright.config.tsadds the same args to the Chromium project. It runs the job's last step (reference-theme-compositionandwidget-appearance) on the same Windows runner.What stays the same
page.gotoretry. A retry would only cover navigation, and a colliding subresource connect would still fail a test throughrequestfailed.Verification (on e3288d8)
corepack pnpm run test:reference-theme-browser×3: 8/8, 8/8, 8/8 passed.corepack pnpm run test:widget-browser: 4/4 passed.corepack pnpm vitest run packages/widget-cli/test/detach-real-browser.e2e.spec.ts: 1/1 passed.corepack pnpm test:e2e apps/web/e2e/reference-theme-composition.spec.ts apps/web/e2e/widget-appearance.spec.ts: 20/20 passed. The config's top-level await works under Playwright Test.corepack pnpm typecheck: passed.corepack pnpm invariants: all 13 passed.eslinton the changed files: clean.corepack pnpm verify: results are in a follow-up comment.Known limitations
TcpPortRandomizationWin. If Chromium renames or removes it, the switch silently does nothing and the flake could return. The CDP probe fails loudly if Playwright stops allowingBrowser.getBrowserCommandLine.Docs impact
None. This changes only the test harness, not any user-visible behaviour, command or contract.