diff --git a/tools/wpt.ts b/tools/wpt.ts index 5cd97ac39a..b8e9a88c0c 100755 --- a/tools/wpt.ts +++ b/tools/wpt.ts @@ -31,6 +31,7 @@ import { updateManifest, wptreport, } from "./wpt/utils.ts"; +import { pooledMap } from "../test_util/std/async/pool.ts"; import { blue, bold, green, red, yellow } from "../test_util/std/fmt/colors.ts"; import { writeAll, writeAllSync } from "../test_util/std/streams/conversion.ts"; import { saveExpectation } from "./wpt/utils.ts"; @@ -155,18 +156,34 @@ async function run() { console.log(`Going to run ${tests.length} test files.`); const results = await runWithTestUtil(false, async () => { - const results = []; + const results: { test: TestToRun; result: TestResult }[] = []; + const cores = navigator.hardwareConcurrency; + const inParallel = !(cores === 1 || tests.length === 1); + // ideally we would parallelize all tests, but we ran into some flakiness + // on the CI, so here we're partitioning based on the start of the test path + const partitionedTests = partitionTests(tests); - for (const test of tests) { - console.log(`${blue("-".repeat(40))}\n${bold(test.path)}\n`); - const result = await runSingleTest( - test.url, - test.options, - createReportTestCase(test.expectation), - inspectBrk, - ); - results.push({ test, result }); - reportVariation(result, test.expectation); + const iter = pooledMap(cores, partitionedTests, async (tests) => { + for (const test of tests) { + if (!inParallel) { + console.log(`${blue("-".repeat(40))}\n${bold(test.path)}\n`); + } + const result = await runSingleTest( + test.url, + test.options, + inParallel ? () => {} : createReportTestCase(test.expectation), + inspectBrk, + ); + results.push({ test, result }); + if (inParallel) { + console.log(`${blue("-".repeat(40))}\n${bold(test.path)}\n`); + } + reportVariation(result, test.expectation); + } + }); + + for await (const _ of iter) { + // ignore } return results; @@ -723,3 +740,16 @@ function discoverTestsToRun( return testsToRun; } + +function partitionTests(tests: TestToRun[]): TestToRun[][] { + const testsByKey: { [key: string]: TestToRun[] } = {}; + for (const test of tests) { + // Paths looks like: /fetch/corb/img-html-correctly-labeled.sub-ref.html + const key = test.path.split("/")[1]; + if (!(key in testsByKey)) { + testsByKey[key] = []; + } + testsByKey[key].push(test); + } + return Object.values(testsByKey); +}