diff options
author | 2023-09-22 10:58:00 -0400 | |
---|---|---|
committer | 2023-09-22 16:58:00 +0200 | |
commit | faeead42325f378f9edac4e081eb7d6d50905136 (patch) | |
tree | 897800f1faec11405df814df6af945da44dce0a8 /packages/integrations/cloudflare/test/test-utils.js | |
parent | b1310e6f13c029e880145cc08a7f31129412a06c (diff) | |
download | astro-faeead42325f378f9edac4e081eb7d6d50905136.tar.gz astro-faeead42325f378f9edac4e081eb7d6d50905136.tar.zst astro-faeead42325f378f9edac4e081eb7d6d50905136.zip |
feat(@astrojs/cloudflare): Add support for wasm module imports (#8542)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Diffstat (limited to 'packages/integrations/cloudflare/test/test-utils.js')
-rw-r--r-- | packages/integrations/cloudflare/test/test-utils.js | 157 |
1 files changed, 116 insertions, 41 deletions
diff --git a/packages/integrations/cloudflare/test/test-utils.js b/packages/integrations/cloudflare/test/test-utils.js index 36515f831..50226c0c1 100644 --- a/packages/integrations/cloudflare/test/test-utils.js +++ b/packages/integrations/cloudflare/test/test-utils.js @@ -1,12 +1,10 @@ import { spawn } from 'node:child_process'; import { fileURLToPath } from 'node:url'; -import kill from 'kill-port'; import { loadFixture as baseLoadFixture } from '../../../astro/test/test-utils.js'; - +import * as net from 'node:net'; export { fixLineEndings } from '../../../astro/test/test-utils.js'; - /** - * @typedef {{ ready: Promise<void>, stop: Promise<void> }} WranglerCLI + * @typedef {{ stop: Promise<void>, port: number }} WranglerCLI * @typedef {import('../../../astro/test/test-utils').Fixture} Fixture */ @@ -21,70 +19,147 @@ const wranglerPath = fileURLToPath( new URL('../node_modules/wrangler/bin/wrangler.js', import.meta.url) ); +let lastPort = 8788; + /** * @returns {Promise<WranglerCLI>} */ -export async function runCLI(basePath, { silent, port }) { - // Hack: force existing process on port to be killed - try { - await kill(port, 'tcp'); - } catch { - // Will throw if port is not in use, but that's fine +export async function runCLI( + basePath, + { + silent, + maxAttempts = 3, + timeoutMillis = 2500, // really short because it often seems to just hang on the first try, but work subsequently, no matter the wait + backoffFactor = 2, // | - 2.5s -- 5s ---- 10s -> onTimeout + onTimeout = (ex) => { + new Error(`Timed out starting the wrangler CLI after ${maxAttempts} tries.`, { cause: ex }); + }, + } +) { + let triesRemaining = maxAttempts; + let timeout = timeoutMillis; + let cli; + let lastErr; + while (triesRemaining > 0) { + cli = await tryRunCLI(basePath, { silent, timeout, forceRotatePort: triesRemaining !== maxAttempts }); + try { + await cli.ready; + return cli; + } catch (err) { + lastErr = err; + console.error((err.message || err.name || err) + ' after ' + timeout + 'ms'); + cli.stop(); + triesRemaining -= 1; + timeout *= backoffFactor; + } } + onTimeout(lastErr); + return cli; +} - const script = fileURLToPath(new URL(`${basePath}/dist/_worker.js`, import.meta.url)); - const p = spawn('node', [ - wranglerPath, - 'dev', - script, - '--port', - port, - '--log-level', - 'info', - '--persist-to', - `${basePath}/.wrangler/state`, - ]); +async function tryRunCLI(basePath, { silent, timeout, forceRotatePort = false }) { + const port = await getNextOpenPort(lastPort + (forceRotatePort ? 1 : 0)); + lastPort = port; + + const fixtureDir = fileURLToPath(new URL(`${basePath}`, import.meta.url)); + const p = spawn( + 'node', + [ + wranglerPath, + 'pages', + 'dev', + 'dist', + '--port', + port, + '--log-level', + 'info', + '--persist-to', + '.wrangler/state', + ], + { + cwd: fixtureDir, + } + ); p.stderr.setEncoding('utf-8'); p.stdout.setEncoding('utf-8'); - const timeout = 20_000; - const ready = new Promise(async (resolve, reject) => { const failed = setTimeout(() => { - p.kill(); + p.kill('SIGKILL'); reject(new Error(`Timed out starting the wrangler CLI`)); }, timeout); - (async function () { - for (const msg of p.stderr) { - if (!silent) { - console.error(msg); - } - } - })(); + const success = () => { + clearTimeout(failed); + resolve(); + }; - for await (const msg of p.stdout) { + p.on('exit', (code) => reject(`wrangler terminated unexpectedly with exit code ${code}`)); + + p.stderr.on('data', (data) => { if (!silent) { - console.log(msg); + process.stdout.write(data); } - if (msg.includes(`[mf:inf] Ready on`)) { - break; + }); + let allData = ''; + p.stdout.on('data', (data) => { + if (!silent) { + process.stdout.write(data); } - } - - clearTimeout(failed); - resolve(); + allData += data; + if (allData.includes(`[mf:inf] Ready on`)) { + success(); + } + }); }); return { + port, ready, stop() { return new Promise((resolve, reject) => { - p.on('close', () => resolve()); + const timer = setTimeout(() => { + p.kill('SIGKILL'); + }, 1000); + p.on('close', () => { + clearTimeout(timer); + resolve(); + }); p.on('error', (err) => reject(err)); p.kill(); }); }, }; } + +const isPortOpen = async (port) => { + return new Promise((resolve, reject) => { + let s = net.createServer(); + s.once('error', (err) => { + s.close(); + if (err['code'] == 'EADDRINUSE') { + resolve(false); + } else { + reject(err); + } + }); + s.once('listening', () => { + resolve(true); + s.close(); + }); + s.listen(port, "0.0.0.0"); + }); +}; + +const getNextOpenPort = async (startFrom) => { + let openPort = null; + while (startFrom < 65535 || !!openPort) { + if (await isPortOpen(startFrom)) { + openPort = startFrom; + break; + } + startFrom++; + } + return openPort; +}; |