@@ -10,6 +10,8 @@ const os = require('os'); |
10 | 10 | const { inspect } = require('util'); |
11 | 11 | const { Worker } = require('worker_threads'); |
12 | 12 |
|
| 13 | +const workerPath = path.join(__dirname, 'wpt/worker.js'); |
| 14 | + |
13 | 15 | function getBrowserProperties() { |
14 | 16 | const { node: version } = process.versions; // e.g. 18.13.0, 20.0.0-nightly202302078e6e215481 |
15 | 17 | const release = /^\d+\.\d+\.\d+$/.test(version); |
@@ -57,7 +59,8 @@ function codeUnitStr(char) { |
57 | 59 | } |
58 | 60 |
|
59 | 61 | class WPTReport { |
60 | | - constructor() { |
| 62 | + constructor(path) { |
| 63 | + this.filename = `report-${path.replaceAll('/', '-')}.json`; |
61 | 64 | this.results = []; |
62 | 65 | this.time_start = Date.now(); |
63 | 66 | } |
@@ -96,26 +99,18 @@ class WPTReport { |
96 | 99 | return result; |
97 | 100 | }); |
98 | 101 |
|
99 | | - if (fs.existsSync('out/wpt/wptreport.json')) { |
100 | | - const prev = JSON.parse(fs.readFileSync('out/wpt/wptreport.json')); |
101 | | - this.results = [...prev.results, ...this.results]; |
102 | | - this.time_start = prev.time_start; |
103 | | - this.time_end = Math.max(this.time_end, prev.time_end); |
104 | | - this.run_info = prev.run_info; |
105 | | - } else { |
106 | | - /** |
107 | | - * Return required and some optional properties |
108 | | - * https://github.com/web-platform-tests/wpt.fyi/blob/60da175/api/README.md?plain=1#L331-L335 |
109 | | - */ |
110 | | - this.run_info = { |
111 | | - product: 'node.js', |
112 | | - ...getBrowserProperties(), |
113 | | - revision: process.env.WPT_REVISION || 'unknown', |
114 | | - os: getOs(), |
115 | | - }; |
116 | | - } |
| 102 | + /** |
| 103 | + * Return required and some optional properties |
| 104 | + * https://github.com/web-platform-tests/wpt.fyi/blob/60da175/api/README.md?plain=1#L331-L335 |
| 105 | + */ |
| 106 | + this.run_info = { |
| 107 | + product: 'node.js', |
| 108 | + ...getBrowserProperties(), |
| 109 | + revision: process.env.WPT_REVISION || 'unknown', |
| 110 | + os: getOs(), |
| 111 | + }; |
117 | 112 |
|
118 | | - fs.writeFileSync('out/wpt/wptreport.json', JSON.stringify(this)); |
| 113 | + fs.writeFileSync(`out/wpt/${this.filename}`, JSON.stringify(this)); |
119 | 114 | } |
120 | 115 | } |
121 | 116 |
|
@@ -402,6 +397,29 @@ const kIncomplete = 'incomplete'; |
402 | 397 | const kUncaught = 'uncaught'; |
403 | 398 | const NODE_UNCAUGHT = 100; |
404 | 399 |
|
| 400 | +const limit = (concurrency) => { |
| 401 | + let running = 0; |
| 402 | + const queue = []; |
| 403 | + |
| 404 | + const execute = async (fn) => { |
| 405 | + if (running < concurrency) { |
| 406 | + running++; |
| 407 | + try { |
| 408 | + await fn(); |
| 409 | + } finally { |
| 410 | + running--; |
| 411 | + if (queue.length > 0) { |
| 412 | + execute(queue.shift()); |
| 413 | + } |
| 414 | + } |
| 415 | + } else { |
| 416 | + queue.push(fn); |
| 417 | + } |
| 418 | + }; |
| 419 | + |
| 420 | + return execute; |
| 421 | +}; |
| 422 | + |
405 | 423 | class WPTRunner { |
406 | 424 | constructor(path) { |
407 | 425 | this.path = path; |
@@ -425,7 +443,7 @@ class WPTRunner { |
425 | 443 | this.scriptsModifier = null; |
426 | 444 |
|
427 | 445 | if (process.env.WPT_REPORT != null) { |
428 | | - this.report = new WPTReport(); |
| 446 | + this.report = new WPTReport(path); |
429 | 447 | } |
430 | 448 | } |
431 | 449 |
|
@@ -543,6 +561,8 @@ class WPTRunner { |
543 | 561 |
|
544 | 562 | this.inProgress = new Set(queue.map((spec) => spec.filename)); |
545 | 563 |
|
| 564 | + const run = limit(os.availableParallelism()); |
| 565 | + |
546 | 566 | for (const spec of queue) { |
547 | 567 | const testFileName = spec.filename; |
548 | 568 | const content = spec.getContent(); |
@@ -576,15 +596,7 @@ class WPTRunner { |
576 | 596 | this.scriptsModifier?.(obj); |
577 | 597 | scriptsToRun.push(obj); |
578 | 598 |
|
579 | | - /** |
580 | | - * Example test with no META variant |
581 | | - * https://github.com/nodejs/node/blob/03854f6/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.https.any.js#L1-L4 |
582 | | - * |
583 | | - * Example test with multiple META variants |
584 | | - * https://github.com/nodejs/node/blob/03854f6/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js#L1-L9 |
585 | | - */ |
586 | | - for (const variant of meta.variant || ['']) { |
587 | | - const workerPath = path.join(__dirname, 'wpt/worker.js'); |
| 599 | + const runWorker = async (variant) => { |
588 | 600 | const worker = new Worker(workerPath, { |
589 | 601 | execArgv: this.flags, |
590 | 602 | workerData: { |
@@ -635,6 +647,17 @@ class WPTRunner { |
635 | 647 | }); |
636 | 648 |
|
637 | 649 | await events.once(worker, 'exit').catch(() => {}); |
| 650 | + }; |
| 651 | + |
| 652 | + /** |
| 653 | + * Example test with no META variant |
| 654 | + * https://github.com/nodejs/node/blob/03854f6/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.https.any.js#L1-L4 |
| 655 | + * |
| 656 | + * Example test with multiple META variants |
| 657 | + * https://github.com/nodejs/node/blob/03854f6/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js#L1-L9 |
| 658 | + */ |
| 659 | + for (const variant of meta.variant || ['']) { |
| 660 | + run(() => runWorker(variant)); |
638 | 661 | } |
639 | 662 | } |
640 | 663 |
|
|