The page workflows started one global webServer and ran with one worker. Each worker now owns its own tests/browser/server.py on an OS-chosen port, with its own temp root and database, through a shared `test` in tests/browser/fixtures.mjs. baseURL, and so page, request and browser.newContext, point at that worker's server. A server that dies fails the running test with its stderr tail and the next test gets a fresh one. The worker count comes from PM_TEST_WORKERS, else 1 under CI, else a quarter of the CPUs up to 8. Chromium workflows in the pinned image: 510 tests in 606 s with one worker on main, 511 (one new isolation spec) in 119 s with eight.
19 lines
774 B
JavaScript
19 lines
774 B
JavaScript
import { availableParallelism } from 'node:os';
|
|
|
|
const MAX_LOCAL_WORKERS = 8;
|
|
const CPUS_PER_WORKER = 4;
|
|
|
|
// PM_TEST_WORKERS wins; CI without it keeps one worker, so CI only changes
|
|
// through explicit workflow edits; locally a quarter of the CPUs, at most eight.
|
|
export function workflowWorkers({ env = process.env, cpus = availableParallelism() } = {}) {
|
|
if (env.PM_TEST_WORKERS !== undefined) {
|
|
const workers = Number(env.PM_TEST_WORKERS);
|
|
if (!Number.isInteger(workers) || workers < 1) {
|
|
throw new Error(`PM_TEST_WORKERS must be a positive integer, got "${env.PM_TEST_WORKERS}"`);
|
|
}
|
|
return workers;
|
|
}
|
|
if (env.CI) return 1;
|
|
return Math.max(1, Math.min(MAX_LOCAL_WORKERS, Math.floor(cpus / CPUS_PER_WORKER)));
|
|
}
|