Skip to content

Wpt: vendor and run the workers corpus, in a real worker - #3225

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:wpt/workers-corpus
Aug 22, 2026
Merged

lahma merged 1 commit into
sebastienros:mainfrom
lahma:wpt/workers-corpus

Conversation

@lahma

@lahma lahma commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

The capstone of #3167: the reachable subset of web-platform-tests' workers/ directory, vendored at the existing pin and run against the shipped implementation — inside a real worker. Every reachable .any.js there is // META: global=worker, so running them in the driver's top-level engine would prove nothing; the driver instead grew a worker lane that makes the file the body of a genuine new Worker(…, { type: 'module' }), with parent and worker pumped cooperatively on the test's own thread through a thread-free WptWorkerProvider. Results are read off the worker engine between turns rather than posted back, so a serializer defect fails an assertion instead of silencing every worker suite. A lane-classification pin (EveryWorkerLaneFileIsAWorkersFile) holds both directions of the routing rule.

11 of 31 upstream files vendored (the rest named in the not-vendored table with reasons — browsing-context, classic-worker and SharedWorker material), 15 assertions, 0.46 s. Seven exclusion rows in three categories: NeedsDeclinedWorkerGlobals (the interface objects, location and WorkerNavigator the design declines by name), NeedsWorkerNesting (off by default, by design), and one genuine NeedsTriage — self is installed writable everywhere while WorkerGlobalScope.self is readonly, now tracked as #3224. NeedsMessageChannel's stale "Jint has no worker story" wording is rewritten to what remains true.

Two findings beyond the table: the flagship modules/dedicated-worker-import.any.js suite (nine tests of the feature Jint ships) stalls on the canonical self instanceof DedicatedWorkerGlobalScope sniff and had to be not-vendored — posted to #3195 as a concrete cost datum for the exposure ruling — and Vendor/README.md on main carried live merge-conflict markers from #3215, fixed here since the file was being edited anyway.

Closes the implementation plan of #3167.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PnghUC3EKrYa12xQ2LaYyd

The workers/ corpus is the capstone of sebastienros#3167: it is reachable at all only because Jint now has a
Worker. Eleven files, 15 assertions, run as the body of a real module worker built by a real
`new Worker(…, { type: 'module' })` — not in the driver's top-level engine, where every one of them
would have passed and proved nothing.

Two lanes. WptWorkerProvider is a WorkerProvider — the shipped host extension point — and the driver
pumps the parent and every live worker in turn on its own thread; nothing here starts one, so a
suite's outcome cannot depend on how two schedulers interleaved. Results are read off the worker
engine between turns rather than posted back, so a serializer defect would present as a failing
assertion rather than as every worker suite reporting nothing. WptHarness.RunsInAWorker picks the
lane from the directory *and* the `// META: global=` key, because neither half does the job alone,
and EveryWorkerLaneFileIsAWorkersFile pins both directions — no previously vendored file moves.

Eight of the 15 pass, and what passes is the worker global doing its job: dispatching a custom event
at itself, taking `onmessage` eight times over, replacing `self.MessageEvent`, exposing atob/btoa,
and — the best of them — refusing `postMessage(formData)` with a DataCloneError, so the worker
global's postMessage really is the port's, running the real serializer.

Six of the seven failures were decided in writing before a line of this ran, which is the point of
running it: five are the three globals the design declines by name (WorkerGlobalScope,
WorkerLocation, WorkerNavigator — divergences 5, 6 and 7) and one is nesting being off by default.
The seventh is NeedsTriage and is not in the worker code: `self` is installed once for every global
as a writable data property, against Window's [Replaceable] definition, where WorkerGlobalScope's is
read-only. Recorded rather than fixed — the install predates Worker and is shared with the top-level
lane. The shim stops assuming `self` is assignable so that fix will not break the harness.

Twenty upstream .any.js files cannot be reached and are named with reasons. One row is a finding
rather than a decision: workers/modules/ holds the flagship module-worker suite, and every one of its
nine fixtures installs its onmessage handler inside
`if ('DedicatedWorkerGlobalScope' in self && self instanceof DedicatedWorkerGlobalScope)`. Jint
deliberately exposes no such interface object, so no handler is installed, the worker never answers,
and the file hangs — the canonical "am I in a worker" sniff, failing in the fixture where no per-test
exclusion can name it. The design named that wrinkle; this is what it costs.

Also fixes leftover merge-conflict markers in Vendor/README.md, left by sebastienros#3215.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lahma
lahma merged commit 9817530 into sebastienros:main Aug 22, 2026
5 checks passed
@lahma
lahma deleted the wpt/workers-corpus branch August 23, 2026 10:00
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.

1 participant