summaryrefslogtreecommitdiff
path: root/packages/integrations/cloudflare/test/test-utils.js
diff options
context:
space:
mode:
authorGravatar Adrian Lyjak <adrianlyjak@gmail.com> 2023-09-22 10:58:00 -0400
committerGravatar GitHub <noreply@github.com> 2023-09-22 16:58:00 +0200
commitfaeead42325f378f9edac4e081eb7d6d50905136 (patch)
tree897800f1faec11405df814df6af945da44dce0a8 /packages/integrations/cloudflare/test/test-utils.js
parentb1310e6f13c029e880145cc08a7f31129412a06c (diff)
downloadastro-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.js157
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;
+};