(server, timeout = 10000)
| 109 | }; |
| 110 | |
| 111 | export const stopHTTPServer = async (server, timeout = 10000) => { |
| 112 | if (!server) return; |
| 113 | |
| 114 | class="cm">// Try a graceful close first so in-flight requests can finish writing and |
| 115 | class="cm">// clients see clean FINs instead of RSTs. Forcefully tearing down sockets |
| 116 | class="cm">// up-front (closeAllConnections) is what produces dangling RSTs that the |
| 117 | class="cm">// next test on the same port can observe as EPIPE on its client write. |
| 118 | class="cm">// Force-close only after a short grace period. |
| 119 | const closed = new Promise((resolve) => server.close(resolve)); |
| 120 | const grace = Math.min(2000, Math.max(0, timeout / 2)); |
| 121 | |
| 122 | const winner = await Promise.race([ |
| 123 | closed.then(() => class="st">'graceful'), |
| 124 | setTimeoutAsync(grace).then(() => class="st">'grace_elapsed'), |
| 125 | ]); |
| 126 | |
| 127 | if (winner === class="st">'grace_elapsed') { |
| 128 | if (typeof server.closeAllConnections === class="st">'function') { |
| 129 | server.closeAllConnections(); |
| 130 | } |
| 131 | if (typeof server.closeAllSessions === class="st">'function') { |
| 132 | server.closeAllSessions(); |
| 133 | } |
| 134 | await Promise.race([closed, setTimeoutAsync(timeout - grace)]); |
| 135 | } |
| 136 | |
| 137 | untrackServer(server); |
| 138 | }; |
| 139 | |
| 140 | export const stopAllTrackedHTTPServers = async (timeout = 10000) => { |
| 141 | const servers = Array.from(trackedServers); |
no test coverage detected