返回 DeepSeek-Reasonix
smoke-lifecycle.test.mjs
根目录 / desktop / packaging / smoke-lifecycle.test.mjs
1 import assert from "node:assert/strict";
2 import { fork } from "node:child_process";
3 import { once } from "node:events";
4 import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
5 import { tmpdir } from "node:os";
6 import { join } from "node:path";
7 import { test } from "node:test";
8 import { closeAndVerify, processAlive, waitForProcessesToExit } from "./smoke-lifecycle.mjs";
9
10 async function ownedProcess(t) {
11 const directory = mkdtempSync(join(tmpdir(), "reasonix-smoke-lifecycle-"));
12 const script = join(directory, "child.cjs");
13 writeFileSync(script, 'process.on("message", () => process.exit(0)); process.send("ready");\n');
14 const child = fork(script, [], { stdio: ["ignore", "ignore", "ignore", "ipc"] });
15 t.after(async () => {
16 if (processAlive(child.pid)) {
17 const exited = once(child, "exit");
18 child.kill("SIGKILL");
19 await exited;
20 }
21 rmSync(directory, { recursive: true, force: true });
22 });
23 await once(child, "message");
24 return child;
25 }
26
27 test("normal app close must end both the actual shell and the Go service", async (t) => {
28 const shell = await ownedProcess(t);
29 const service = await ownedProcess(t);
30 let closeCalls = 0;
31 await closeAndVerify({ close: async () => { closeCalls++; shell.send("quit"); service.send("quit"); } }, { shellPid: shell.pid, servicePid: service.pid });
32 assert.equal(closeCalls, 1);
33 assert.equal(processAlive(shell.pid), false);
34 assert.equal(processAlive(service.pid), false);
35 });
36
37 test("a live process is a verification failure and is never force-killed by verification", async (t) => {
38 const service = await ownedProcess(t);
39 await assert.rejects(waitForProcessesToExit([service.pid], 0), /processes outlived normal app quit/);
40 assert.equal(processAlive(service.pid), true);
41 });
42
43 test("a hung normal app close fails without pretending forced cleanup is success", async (t) => {
44 const shell = await ownedProcess(t);
45 await assert.rejects(closeAndVerify({ close: () => new Promise(() => {}) }, { shellPid: shell.pid, servicePid: shell.pid }, 10), /normal app quit did not complete/);
46 assert.equal(processAlive(shell.pid), true);
47 });
48
48 lines Plain Text