fix(qa-lab): resolve Windows PowerShell path

This commit is contained in:
Vincent Koc
2026-06-21 12:40:57 +02:00
parent 15c880aeff
commit b8a5dac1a2
4 changed files with 70 additions and 1 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
// Qa Lab plugin module implements process tree cpu behavior.
import { spawnSync } from "node:child_process";
import { parseStrictFiniteNumber, parseStrictInteger } from "openclaw/plugin-sdk/number-runtime";
import { resolveQaWindowsPowerShellExePath } from "./windows-system-tools.js";
type ProcessTreeSnapshot = {
childrenByParent: Map<number, number[]>;
@@ -175,7 +176,7 @@ function collectProcessTreeMetric(
function readWindowsProcessTreeSnapshot(): ProcessTreeSnapshot | null {
const result = spawnSync(
"powershell.exe",
resolveQaWindowsPowerShellExePath(),
[
"-NoProfile",
"-ExecutionPolicy",
@@ -0,0 +1,52 @@
// Qa Lab tests cover Windows process tree sampling command selection.
import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
const spawnSyncMock = vi.hoisted(() => vi.fn());
vi.mock("node:child_process", async () => {
const actual = await vi.importActual<typeof import("node:child_process")>("node:child_process");
return {
...actual,
spawnSync: spawnSyncMock,
};
});
import { readProcessTreeCpuMs } from "./process-tree-cpu.js";
afterEach(() => {
vi.restoreAllMocks();
vi.unstubAllEnvs();
spawnSyncMock.mockReset();
});
describe("readProcessTreeCpuMs on Windows", () => {
it("uses the trusted Windows PowerShell path", () => {
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
vi.stubEnv("SystemRoot", "D:\\Windows");
spawnSyncMock.mockReturnValue({
status: 0,
stdout: JSON.stringify([
{
ProcessId: 100,
ParentProcessId: 50,
KernelModeTime: "10000",
UserModeTime: "20000",
WorkingSetSize: "1000",
},
{
ProcessId: 101,
ParentProcessId: 100,
KernelModeTime: "30000",
UserModeTime: "40000",
WorkingSetSize: "2000",
},
]),
});
expect(readProcessTreeCpuMs(100)).toBe(10);
expect(spawnSyncMock.mock.calls[0]?.[0]).toBe(
path.win32.join("D:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
);
});
});
@@ -1,6 +1,7 @@
// Qa Lab tests cover Windows system tool path resolution.
import { describe, expect, it } from "vitest";
import {
resolveQaWindowsPowerShellExePath,
resolveQaWindowsSystem32ExePath,
resolveQaWindowsSystemRoot,
} from "./windows-system-tools.js";
@@ -11,6 +12,9 @@ describe("qa-lab windows system tools", () => {
expect(resolveQaWindowsSystem32ExePath("taskkill.exe", { SystemRoot: "D:\\Windows\\" })).toBe(
"D:\\Windows\\System32\\taskkill.exe",
);
expect(resolveQaWindowsPowerShellExePath({ SystemRoot: "D:\\Windows\\" })).toBe(
"D:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
);
});
it("falls back to the default Windows root when env roots are unsafe", () => {
@@ -60,3 +60,15 @@ export function resolveQaWindowsSystem32ExePath(
}
return path.win32.join(resolveQaWindowsSystemRoot(env), "System32", executableName);
}
export function resolveQaWindowsPowerShellExePath(
env: Record<string, string | undefined> = process.env,
): string {
return path.win32.join(
resolveQaWindowsSystemRoot(env),
"System32",
"WindowsPowerShell",
"v1.0",
"powershell.exe",
);
}