diff --git a/artifacts/api-server/package.json b/artifacts/api-server/package.json index 6b590436..4ba7be39 100644 --- a/artifacts/api-server/package.json +++ b/artifacts/api-server/package.json @@ -8,6 +8,7 @@ "build": "node ./build.mjs", "start": "node --enable-source-maps ./dist/index.mjs", "typecheck": "tsc -p tsconfig.json --noEmit", + "test:wait": "node ./scripts/wait-for-server.mjs", "test": "node --test 'tests/**/*.test.mjs'" }, "dependencies": { diff --git a/artifacts/api-server/scripts/wait-for-server.mjs b/artifacts/api-server/scripts/wait-for-server.mjs new file mode 100644 index 00000000..20ad5bc3 --- /dev/null +++ b/artifacts/api-server/scripts/wait-for-server.mjs @@ -0,0 +1,48 @@ +#!/usr/bin/env node +const API_BASE = process.env.TEST_API_BASE ?? "http://localhost:8080"; +const TIMEOUT_MS = Number(process.env.TEST_API_WAIT_TIMEOUT_MS ?? 30_000); +const INTERVAL_MS = Number(process.env.TEST_API_WAIT_INTERVAL_MS ?? 500); +const URL = `${API_BASE.replace(/\/$/, "")}/api/healthz`; + +const started = Date.now(); +let attempt = 0; +let lastError = null; + +while (Date.now() - started < TIMEOUT_MS) { + attempt += 1; + try { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 2_000); + const res = await fetch(URL, { signal: controller.signal }); + clearTimeout(timer); + if (res.ok) { + const body = await res.json().catch(() => ({})); + if (body && body.status === "ok") { + const elapsed = Date.now() - started; + console.log( + `API server ready at ${URL} after ${elapsed}ms (attempt ${attempt})`, + ); + process.exit(0); + } + lastError = new Error( + `Unexpected health payload: ${JSON.stringify(body)}`, + ); + } else { + lastError = new Error(`HTTP ${res.status} from ${URL}`); + } + } catch (err) { + lastError = err; + } + await new Promise((r) => setTimeout(r, INTERVAL_MS)); +} + +console.error( + `API server not reachable at ${URL} after ${TIMEOUT_MS}ms (${attempt} attempts).`, +); +console.error( + `Last error: ${lastError ? lastError.message ?? String(lastError) : "unknown"}`, +); +console.error( + `Start the API Server workflow (or set TEST_API_BASE) before running tests.`, +); +process.exit(1);