Final review fixes for the per-worker test servers (#274):
- A failed test gets the stderr its server wrote during that test
attached as `server-stderr`, so an aiohttp traceback behind a 500
reaches the CI report. The launcher keeps the newest 256 KB with a
stream position per test (stderrMark/stderrSince), and the fixture
attaches it only when the test did not end as expected.
- The port announcement counts only as a complete line; a chunk ending
mid-number was read as a shorter port.
- server.py --exit-on-stdin-eof shuts down gracefully (database closed,
temp root removed) when stdin closes. The launcher holds that pipe,
so a SIGKILLed worker leaves no server behind, on every OS.
- settled() gives up after 600 frames with the observation stats
instead of hanging to the test timeout.
- The Classic text-sync test waits for the page's 50 ms timer to
install serializeValue instead of sleeping 60 ms. With that timer run
100 ms late (a scratch copy), the old wait failed 20/20 and the poll
passed 20/20; the spec passed 240/240 at 8 workers x10 and 240/240
at 1 CPU with 4 workers.
- The workflow test checks each npm cache key names its job's pinned
image tag.
Every new unit test failed before its change (missing export, the old
regex timing out on the split announcement, an unknown server flag, a
hung settle, a mismatched cache key).
The first sharded run lost a webkit shard to its 12-minute limit after all
267 tests passed, and npm ci stalled for 5 minutes in six of eight jobs. Each
npm ci now restores npm's download cache keyed on the vendor lockfile, and
browser job timeouts are the measured times plus at least 50%, never under 20
minutes. The workflow comment records the measurements.
Frontend coverage runs as three shards (PM_TEST_WORKERS=3 each) that upload
their raw V8 files as coverage-raw-N; a merge job downloads them, fails unless
all three arrived with raw files and no clashing names, then runs
coverage:merge. Firefox and WebKit page workflows run as two shards each with
three workers. The required viewerjs context keeps its name and now needs the
shards, the merge and the browser shards, failing unless every one succeeded.