

























@@ -366,6 +366,26 @@ describe("plugin gateway gauntlet helpers", () => {
366366await expect(fs.readFile(row.logPath, "utf8")).resolves.toContain("live stderr");
367367});
368368369+it("cleans parent signal handlers after live measured commands settle", async () => {
370+const logDir = path.join(repoRoot, "logs");
371+const before = process.listenerCount("SIGTERM");
372+373+const row = await runMeasuredCommandLive({
374+cwd: repoRoot,
375+env: process.env,
376+ logDir,
377+command: process.execPath,
378+args: ["-e", ""],
379+label: "live-signal-cleanup",
380+phase: "probe",
381+timeoutMs: 1000,
382+timeMode: "none",
383+});
384+385+expect(row.status).toBe(0);
386+expect(process.listenerCount("SIGTERM")).toBe(before);
387+});
388+369389it("bounds captured output from live measured commands", async () => {
370390const logDir = path.join(repoRoot, "logs");
371391const row = await runMeasuredCommandLive({
@@ -387,6 +407,40 @@ describe("plugin gateway gauntlet helpers", () => {
387407expect(log).toContain("[stdout truncated after 12 bytes]");
388408});
389409410+it("force kills timed-out live measured process groups that ignore SIGTERM", async () => {
411+const logDir = path.join(repoRoot, "logs");
412+const markerPath = path.join(repoRoot, "timeout-marker.txt");
413+const row = await runMeasuredCommandLive({
414+cwd: repoRoot,
415+env: process.env,
416+ logDir,
417+command: process.execPath,
418+args: [
419+"-e",
420+[
421+"const fs = require('node:fs');",
422+"const marker = process.argv[1];",
423+"fs.writeFileSync(marker, 'start\\n');",
424+"process.on('SIGTERM', () => fs.appendFileSync(marker, 'term\\n'));",
425+"setInterval(() => fs.appendFileSync(marker, 'tick\\n'), 50);",
426+].join(""),
427+markerPath,
428+],
429+label: "live-timeout",
430+phase: "probe",
431+timeoutMs: 1000,
432+timeoutKillGraceMs: 100,
433+});
434+435+expect(row.status).toBe(1);
436+expect(row.timedOut).toBe(true);
437+expect(row.spawnError?.code).toBe("ETIMEDOUT");
438+expect(row.wallMs).toBeLessThan(5_000);
439+const afterReturn = await fs.readFile(markerPath, "utf8");
440+await new Promise((resolve) => setTimeout(resolve, 250));
441+await expect(fs.readFile(markerPath, "utf8")).resolves.toBe(afterReturn);
442+});
443+390444it("cleans the isolated run root after a successful dry run", async () => {
391445const outputDir = path.join(repoRoot, "artifacts");
392446const result = spawnSync(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。