

























@@ -495,6 +495,69 @@ exit 1
495495expect(vi.getTimerCount()).toBe(0);
496496});
497497498+it.runIf(process.platform !== "win32")(
499+"lets update stream descendants exit during timeout kill grace",
500+async () => {
501+const root = makeTempDir();
502+const scriptPath = path.join(root, "stream-update-grace.mjs");
503+const readyPath = path.join(root, "stream-ready");
504+const donePath = path.join(root, "stream-done");
505+const smoke = withEnv(
506+{ OPENAI_API_KEY: "test-key" },
507+() =>
508+new NpmUpdateSmoke({
509+ ...TEST_AUTH,
510+json: false,
511+packageSpec: "openclaw@latest",
512+platforms: new Set<Platform>(["linux"]),
513+provider: "openai",
514+updateTarget: "local-main",
515+}),
516+);
517+const runStreamingToJobLog = Reflect.get(smoke, "runStreamingToJobLog") as (
518+command: string,
519+args: string[],
520+timeoutMs: number,
521+ctx: {
522+append(chunk: string | Uint8Array): void;
523+logPath: string;
524+signal: AbortSignal;
525+},
526+) => Promise<number>;
527+const descendantScript = [
528+"import { writeFileSync } from 'node:fs';",
529+`writeFileSync(${JSON.stringify(readyPath)}, 'ready');`,
530+"process.on('SIGTERM', () => {",
531+` setTimeout(() => { writeFileSync(${JSON.stringify(donePath)}, 'done'); process.exit(0); }, 75);`,
532+"});",
533+"setInterval(() => {}, 1000);",
534+].join("\n");
535+writeFileSync(
536+scriptPath,
537+[
538+"import { spawn } from 'node:child_process';",
539+`spawn(process.execPath, ["--input-type=module", "--eval", ${JSON.stringify(
540+ descendantScript,
541+ )}], { stdio: "ignore" });`,
542+"process.on('SIGTERM', () => process.exit(0));",
543+"setInterval(() => {}, 1000);",
544+"",
545+].join("\n"),
546+"utf8",
547+);
548+549+const command = runStreamingToJobLog.call(smoke, process.execPath, [scriptPath], 500, {
550+append: () => undefined,
551+logPath: path.join(root, "update.log"),
552+signal: new AbortController().signal,
553+});
554+555+await waitFor(() => existsSync(readyPath), "update stream descendant readiness");
556+await expect(command).resolves.toBe(124);
557+expect(readFileSync(donePath, "utf8")).toBe("done");
558+},
559+);
560+498561it("runs Windows updates through a detached done-file runner", () => {
499562const script = readFileSync(SCRIPT_PATH, "utf8");
500563const transports = readFileSync(GUEST_TRANSPORTS_PATH, "utf8");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。