clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/prf-provision-custody
lofi / package / tooling / process_test.ts
process_test.ts 2.5K
1import { runDenoStatus } from "./process.ts";23function assert(condition: unknown, message: string): asserts condition {4 if (!condition) throw new Error(message);5}67Deno.test({8 name: "runDenoStatus distinguishes a forwarded shutdown signal from a child failure",9 // Spawns nested Deno processes and forwards SIGTERM through them; the signal10 // timing is unreliable on hosted CI runners, so this runs locally only.11 ignore: Deno.build.os === "windows" || Deno.env.get("CI") === "true",12 async fn() {13 const moduleUrl = new URL("./process.ts", import.meta.url).href;14 const wrapperSource = `15 import { runDenoStatus } from ${JSON.stringify(moduleUrl)};16 const status = await runDenoStatus(17 ["eval", "console.log('READY'); await new Promise(() => {})"],18 {},19 );20 console.log("STATUS " + JSON.stringify(status));21 if (status.forwardedSignal !== "SIGTERM") Deno.exit(1);22 `;23 const wrapper = new Deno.Command(Deno.execPath(), {24 args: ["eval", wrapperSource],25 clearEnv: true,26 stdout: "piped",27 stderr: "piped",28 }).spawn();29 const reader = wrapper.stdout.pipeThrough(new TextDecoderStream()).getReader();30 let stdout = "";31 try {32 while (!stdout.includes("READY")) {33 const next = await Promise.race([34 reader.read(),35 new Promise<never>((_, reject) =>36 setTimeout(() => reject(new Error("signal test child did not become ready")), 5_000)37 ),38 ]);39 if (next.done) throw new Error(`signal test child exited before readiness: ${stdout}`);40 stdout += next.value;41 }42 wrapper.kill("SIGTERM");43 while (true) {44 const next = await reader.read();45 if (next.done) break;46 stdout += next.value;47 }48 const [status, stderr] = await Promise.all([49 wrapper.status,50 new Response(wrapper.stderr).text(),51 ]);52 assert(status.success, `signal test wrapper failed (${status.code}): ${stderr}`);53 assert(54 stdout.includes('"forwardedSignal":"SIGTERM"'),55 `forwarded signal was not retained: ${stdout}`,56 );57 } finally {58 reader.releaseLock();59 try {60 wrapper.kill("SIGKILL");61 } catch {62 // The expected path already exited cleanly.63 }64 }6566 const unexpected = await runDenoStatus(["eval", "Deno.exit(17)"], {});67 assert(unexpected.code === 17, `unexpected child code changed: ${unexpected.code}`);68 assert(unexpected.forwardedSignal === null, "ordinary child failure was marked as a shutdown");69 },70});