import test from "node:test"; import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import path from "node:path"; import { fileURLToPath } from "node:url"; const testDirectory = path.dirname(fileURLToPath(import.meta.url)); const brokerEntryPath = path.resolve(testDirectory, "../server.mjs"); test("server entrypoint starts the broker and stays alive until terminated", async () => { const child = spawn(process.execPath, [brokerEntryPath], { env: { ...process.env, PORT: "0", EDGE_AUTH_MODE: "stub", }, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); await new Promise((resolve, reject) => { const timeout = setTimeout(() => { reject(new Error(`Broker entrypoint did not report readiness.\nstdout:\n${stdout}\nstderr:\n${stderr}`)); }, 10_000); child.once("exit", (code, signal) => { clearTimeout(timeout); reject(new Error(`Broker entrypoint exited early with code=${code} signal=${signal}.\nstdout:\n${stdout}\nstderr:\n${stderr}`)); }); const poll = () => { if (/TruckWash edge broker listening on \d+/.test(stdout)) { clearTimeout(timeout); resolve(); return; } setTimeout(poll, 25); }; poll(); }); assert.equal(child.exitCode, null, `Broker exited unexpectedly.\nstdout:\n${stdout}\nstderr:\n${stderr}`); const exitResult = await new Promise((resolve, reject) => { child.once("exit", (code, signal) => resolve({ code, signal })); child.kill("SIGTERM"); setTimeout(() => reject(new Error("Broker did not exit after SIGTERM.")), 10_000); }); const exitedCleanly = exitResult.code === 0 || exitResult.signal === "SIGTERM"; assert.equal(exitedCleanly, true, `Broker exited unsuccessfully.\nstdout:\n${stdout}\nstderr:\n${stderr}`); });