Skip to content

test: use upstream's per-test timeout, and fix what the full matrix showed - #3281

Merged
Pavel Feldman (pavelfeldman) merged 1 commit into
microsoft:mainfrom
pavelfeldman:slow_markers
Oct 21, 2026
Merged

Pavel Feldman (pavelfeldman) merged 1 commit into
microsoft:mainfrom
pavelfeldman:slow_markers

Conversation

@pavelfeldman

@pavelfeldman Pavel Feldman (pavelfeldman) commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Summary

  • A test times out after 30 s as upstream, fixtures included; @pytest.mark.slow triples it (the ports of upstream's test.slow() tests, and the Python-only tests that wait longer by design). The thread method of pytest-timeout: the signal method's exception is swallowed by asyncio's Handle._run(), which is why jobs hung to the 90-minute limit. The timer is cancelled before a failure's report is built, which fired inside pytest before. CI and test.sh drop their --timeout flags.
  • Ports are reserved free on both 127.0.0.1 and ::1, and a listener that loses ::1 to another process takes a new port: the browser resolves localhost to ::1 first and could reach another worker's server.
  • The child of the signal tests closes the browser on SIGHUP and exits 0, as the Node.js child does, and runs in a short temp dir (Chrome's ProcessSingleton socket path was too long under tmp_path, which crashed the stable channels). A zone closed from another context no longer raises on its ContextVar reset.
  • CI runs Linux on ubuntu-22.04 (headless Firefox has WebGL there, not on 24.04) and runs the async step after a failed sync step. The ports are not changed to pass: AGENTS.md says so now, tests/transform.md has the rules of the port of the tests, and transform.md moves to playwright/_impl/.

@pavelfeldman Pavel Feldman (pavelfeldman) changed the title test: use upstream's per-test timeout test: use upstream's per-test timeout, and fix two races of the test infrastructure Oct 21, 2026
@pavelfeldman Pavel Feldman (pavelfeldman) changed the title test: use upstream's per-test timeout, and fix two races of the test infrastructure test: use upstream's per-test timeout, and fix what the full matrix showed Oct 21, 2026
…howed

A test times out after 30 seconds, as upstream, and the fixtures count, as
upstream counts them (pyproject.toml). A test marked slow gets three times
that, as test.slow() gives upstream: the ports of the tests that call it
(IF-009, IF-011, FC-001, CC-040, BT-076, BT-077, BT-091, all of
screencast.spec.ts and signals.spec.ts), and the Python-only tests that wait
longer by design (the pause tests, the subprocess and multiprocessing tests).
The wheel installation test gets its own bound. CI and test.sh drop their
--timeout flags.

The timeout method is thread, which ends the process of a test that hangs;
xdist replaces the worker. The signal method can not be used: asyncio's
Handle._run() catches and logs every BaseException but SystemExit and
KeyboardInterrupt, so a timeout that fires while the event loop runs a
callback is lost and the test hangs on (the jobs that ran into the 90-minute
limit). tests/conftest.py cancels the timer before the report of a failure is
built, where it fired inside pytest when a test failed just before its
deadline, and gives the teardown a timer of its own.

Races and failures that the full suites on every bot showed:

- find_free_port() reserves a port with a dual-stack bind, and a listener that
  gets 127.0.0.1 but loses ::1 to another process takes a new port instead of
  going on with IPv4 only. The IPv6-only server of the socks tests could take a
  port that the test server of another worker held on 127.0.0.1, and the
  browser, which resolves localhost to ::1 first, reached the wrong server.
- The child of the signal tests closes the browser on SIGHUP and ends when it
  has closed, as the Node.js child does. The Python client has no SIGHUP
  handler, so the signal ended the child at once, and the driver, left without
  a client, killed the browser and could crash on its closed pipe before it
  logged the exit; SI-006 failed one time in two on WebKit.
- The child of the signal tests gets a short temporary directory: under
  tmp_path, the socket of Chrome's ProcessSingleton in the user data dir was
  longer than a Unix socket path allows, and the stable channels crashed at
  launch.
- A zone whose coroutine is closed from another context (GeneratorExit) can
  not reset its ContextVar token; the reset raised in every job.
- CI runs Linux on ubuntu-22.04, where headless Firefox has WebGL (CA-008,
  CA-009); the 24.04 image has none. The async step runs after a failed sync
  step too, so that each job reports both suites.

The ports are not changed to pass: AGENTS.md says so now, and tests/transform.md
has the rules of the port of the tests. transform.md, the rules of the port of
the client, moves to playwright/_impl.
@pavelfeldman
Pavel Feldman (pavelfeldman) merged commit c4ee123 into microsoft:main Oct 21, 2026
21 of 29 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