From f02ab5b18a7e5cfcf0ffafaf8dc7a88b1f8430e3 Mon Sep 17 00:00:00 2001
From: Rafael Gonzaga <rafael.nunu@hotmail.com>
Date: Wed, 25 Jan 2023 05:11:35 +0000
Subject: [PATCH 1/2] doc: fix anchor links dispatcher.stream (#1881)

---
 docs/api/Dispatcher.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/api/Dispatcher.md b/docs/api/Dispatcher.md
index 54749964d67..6bb97b47208 100644
--- a/docs/api/Dispatcher.md
+++ b/docs/api/Dispatcher.md
@@ -631,7 +631,7 @@ try {
 
 A faster version of `Dispatcher.request`. This method expects the second argument `factory` to return a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream which the response will be written to. This improves performance by avoiding creating an intermediate [`stream.Readable`](https://nodejs.org/api/stream.html#stream_readable_streams) stream when the user expects to directly pipe the response body to a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream.
 
-As demonstrated in [Example 1 - Basic GET stream request](#example-1-basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](#example-2-stream-to-fastify-response) for more details.
+As demonstrated in [Example 1 - Basic GET stream request](#example-1---basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](#example-2---stream-to-fastify-response) for more details.
 
 Arguments:
 

From 25a8aac24ec5b1a4a45cd2abf316a52412fad8f1 Mon Sep 17 00:00:00 2001
From: Khafra <maitken033380023@gmail.com>
Date: Thu, 26 Jan 2023 02:32:25 -0500
Subject: [PATCH 2/2] wpt: make runner more resilient (#1884)

* wpt: make runner more resilient

* wpt: cleaner exit, hopefully
---
 package.json                      |  2 +-
 test/wpt/runner/runner/runner.mjs | 13 ++++++++++---
 test/wpt/server/server.mjs        |  2 +-
 test/wpt/start-FileAPI.mjs        |  8 +++++---
 test/wpt/start-fetch.mjs          |  8 +++++---
 test/wpt/start-mimesniff.mjs      |  8 +++++---
 test/wpt/start-websockets.mjs     |  4 ++--
 7 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/package.json b/package.json
index 9c4d7dae93b..d84e47a9722 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,7 @@
     "test:tdd": "tap test/*.js test/diagnostics-channel/*.js -w",
     "test:typescript": "tsd && tsc test/imports/undici-import.ts",
     "test:websocket": "node scripts/verifyVersion.js 18 || tap test/websocket/*.js",
-    "test:wpt": "node scripts/verifyVersion 18 || (node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs)",
+    "test:wpt": "node scripts/verifyVersion 18 || (node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node --no-warnings test/wpt/start-websockets.mjs)",
     "coverage": "nyc --reporter=text --reporter=html npm run test",
     "coverage:ci": "nyc --reporter=lcov npm run test",
     "bench": "PORT=3042 concurrently -k -s first npm:bench:server npm:bench:run",
diff --git a/test/wpt/runner/runner/runner.mjs b/test/wpt/runner/runner/runner.mjs
index da5cb96899c..3e558de3e0b 100644
--- a/test/wpt/runner/runner/runner.mjs
+++ b/test/wpt/runner/runner/runner.mjs
@@ -1,6 +1,7 @@
 import { deepStrictEqual } from 'node:assert'
-import { EventEmitter } from 'node:events'
+import { EventEmitter, once } from 'node:events'
 import { readdirSync, readFileSync, statSync } from 'node:fs'
+import { cpus } from 'node:os'
 import { basename, isAbsolute, join, resolve } from 'node:path'
 import { fileURLToPath } from 'node:url'
 import { Worker } from 'node:worker_threads'
@@ -82,10 +83,11 @@ export class WPTRunner extends EventEmitter {
     return [...files]
   }
 
-  run () {
+  async run () {
     const workerPath = fileURLToPath(join(import.meta.url, '../worker.mjs'))
     /** @type {Set<Worker>} */
     const activeWorkers = new Set()
+    let finishedFiles = 0
 
     for (const test of this.#files) {
       const code = test.includes('.sub.')
@@ -95,6 +97,7 @@ export class WPTRunner extends EventEmitter {
 
       if (this.#status[basename(test)]?.skip) {
         this.#stats.skipped += 1
+        finishedFiles++
         continue
       }
 
@@ -131,10 +134,14 @@ export class WPTRunner extends EventEmitter {
         activeWorkers.delete(worker)
         clearTimeout(timeout)
 
-        if (activeWorkers.size === 0) {
+        if (++finishedFiles === this.#files.length) {
           this.handleRunnerCompletion()
         }
       })
+
+      if (activeWorkers.size === cpus().length) {
+        await once(worker, 'exit')
+      }
     }
   }
 
diff --git a/test/wpt/server/server.mjs b/test/wpt/server/server.mjs
index 13b8856a1f4..9df64e75010 100644
--- a/test/wpt/server/server.mjs
+++ b/test/wpt/server/server.mjs
@@ -354,7 +354,7 @@ send({ server: `http://localhost:${server.address().port}` })
 
 process.on('message', (message) => {
   if (message === 'shutdown') {
-    server.close((err) => err ? send(err) : send({ message: 'shutdown' }))
+    server.close((err) => process.exit(err ? 1 : 0))
   }
 })
 
diff --git a/test/wpt/start-FileAPI.mjs b/test/wpt/start-FileAPI.mjs
index e601afc1120..fc85158ae13 100644
--- a/test/wpt/start-FileAPI.mjs
+++ b/test/wpt/start-FileAPI.mjs
@@ -10,15 +10,17 @@ const child = fork(serverPath, [], {
   stdio: ['pipe', 'pipe', 'pipe', 'ipc']
 })
 
+child.on('exit', (code) => process.exit(code))
+
 for await (const [message] of on(child, 'message')) {
   if (message.server) {
     const runner = new WPTRunner('FileAPI', message.server)
     runner.run()
 
     runner.once('completion', () => {
-      child.send('shutdown')
+      if (child.connected) {
+        child.send('shutdown')
+      }
     })
-  } else if (message.message === 'shutdown') {
-    process.exit()
   }
 }
diff --git a/test/wpt/start-fetch.mjs b/test/wpt/start-fetch.mjs
index 55d3f2e53ae..dbf66af59b8 100644
--- a/test/wpt/start-fetch.mjs
+++ b/test/wpt/start-fetch.mjs
@@ -10,15 +10,17 @@ const child = fork(serverPath, [], {
   stdio: ['pipe', 'pipe', 'pipe', 'ipc']
 })
 
+child.on('exit', (code) => process.exit(code))
+
 for await (const [message] of on(child, 'message')) {
   if (message.server) {
     const runner = new WPTRunner('fetch', message.server)
     runner.run()
 
     runner.once('completion', () => {
-      child.send('shutdown')
+      if (child.connected) {
+        child.send('shutdown')
+      }
     })
-  } else if (message.message === 'shutdown') {
-    process.exit()
   }
 }
diff --git a/test/wpt/start-mimesniff.mjs b/test/wpt/start-mimesniff.mjs
index 90e6bdd6c04..396e93dfa9a 100644
--- a/test/wpt/start-mimesniff.mjs
+++ b/test/wpt/start-mimesniff.mjs
@@ -10,15 +10,17 @@ const child = fork(serverPath, [], {
   stdio: ['pipe', 'pipe', 'pipe', 'ipc']
 })
 
+child.on('exit', (code) => process.exit(code))
+
 for await (const [message] of on(child, 'message')) {
   if (message.server) {
     const runner = new WPTRunner('mimesniff', message.server)
     runner.run()
 
     runner.once('completion', () => {
-      child.send('shutdown')
+      if (child.connected) {
+        child.send('shutdown')
+      }
     })
-  } else if (message.message === 'shutdown') {
-    process.exit()
   }
 }
diff --git a/test/wpt/start-websockets.mjs b/test/wpt/start-websockets.mjs
index a7078c6d8d3..603c2f31681 100644
--- a/test/wpt/start-websockets.mjs
+++ b/test/wpt/start-websockets.mjs
@@ -10,6 +10,8 @@ const child = fork(serverPath, [], {
   stdio: ['pipe', 'pipe', 'pipe', 'ipc']
 })
 
+child.on('exit', (code) => process.exit(code))
+
 for await (const [message] of on(child, 'message')) {
   if (message.server) {
     const runner = new WPTRunner('websockets', message.server)
@@ -20,7 +22,5 @@ for await (const [message] of on(child, 'message')) {
         child.send('shutdown')
       }
     })
-  } else if (message.message === 'shutdown') {
-    process.exit()
   }
 }