mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(qa): kill telegram credential trees on windows
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Telegram User Credential Io script supports OpenClaw repository automation.
|
||||
import { spawn } from "node:child_process";
|
||||
import { spawn, spawnSync } from "node:child_process";
|
||||
import { readBoundedResponseText } from "../lib/bounded-response.ts";
|
||||
|
||||
export type JsonObject = Record<string, unknown>;
|
||||
@@ -244,8 +244,22 @@ async function finishTimedOutChildProcessTree(
|
||||
}
|
||||
}
|
||||
|
||||
function signalChildProcessTree(child: ReturnType<typeof spawn>, signal: NodeJS.Signals) {
|
||||
if (process.platform !== "win32" && child.pid) {
|
||||
type ChildProcessTreeTarget = Pick<ReturnType<typeof spawn>, "kill" | "pid">;
|
||||
|
||||
export function signalChildProcessTree(
|
||||
child: ChildProcessTreeTarget,
|
||||
signal: NodeJS.Signals,
|
||||
{
|
||||
platform = process.platform,
|
||||
runTaskkill = spawnSync,
|
||||
useProcessGroup = platform !== "win32",
|
||||
}: {
|
||||
platform?: NodeJS.Platform;
|
||||
runTaskkill?: typeof spawnSync;
|
||||
useProcessGroup?: boolean;
|
||||
} = {},
|
||||
) {
|
||||
if (useProcessGroup && child.pid) {
|
||||
try {
|
||||
process.kill(-child.pid, signal);
|
||||
return;
|
||||
@@ -253,6 +267,16 @@ function signalChildProcessTree(child: ReturnType<typeof spawn>, signal: NodeJS.
|
||||
// The process group can disappear between timeout and cleanup.
|
||||
}
|
||||
}
|
||||
if (platform === "win32" && typeof child.pid === "number") {
|
||||
const args = ["/PID", String(child.pid), "/T"];
|
||||
if (signal === "SIGKILL") {
|
||||
args.push("/F");
|
||||
}
|
||||
const result = runTaskkill("taskkill", args, { stdio: "ignore" });
|
||||
if (!result.error && result.status === 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
child.kill(signal);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@ import { readFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import path, { win32 } from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { fetchJsonWithTimeout, runCommand } from "../../scripts/e2e/telegram-user-credential-io.ts";
|
||||
import {
|
||||
fetchJsonWithTimeout,
|
||||
runCommand,
|
||||
signalChildProcessTree,
|
||||
} from "../../scripts/e2e/telegram-user-credential-io.ts";
|
||||
import {
|
||||
expandHome,
|
||||
resolvePrivateJsonDirectory,
|
||||
@@ -403,6 +407,31 @@ setInterval(() => {}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
it("signals Windows credential helper process trees with taskkill", () => {
|
||||
const child = {
|
||||
kill: vi.fn(),
|
||||
pid: 12345,
|
||||
};
|
||||
const runTaskkill = vi.fn(() => ({ error: undefined, status: 0 }));
|
||||
|
||||
signalChildProcessTree(child, "SIGTERM", {
|
||||
platform: "win32",
|
||||
runTaskkill,
|
||||
});
|
||||
expect(runTaskkill).toHaveBeenNthCalledWith(1, "taskkill", ["/PID", "12345", "/T"], {
|
||||
stdio: "ignore",
|
||||
});
|
||||
|
||||
signalChildProcessTree(child, "SIGKILL", {
|
||||
platform: "win32",
|
||||
runTaskkill,
|
||||
});
|
||||
expect(runTaskkill).toHaveBeenNthCalledWith(2, "taskkill", ["/PID", "12345", "/T", "/F"], {
|
||||
stdio: "ignore",
|
||||
});
|
||||
expect(child.kill).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"exits promptly after forwarded SIGTERM children exit cleanly",
|
||||
async () => {
|
||||
|
||||
Reference in New Issue
Block a user