Files
openclaw/src/process/exec.test.ts

92 lines
2.6 KiB
TypeScript
Raw Normal View History

import { describe, expect, it } from "vitest";
import { withEnvAsync } from "../test-utils/env.js";
import { runCommandWithTimeout, shouldSpawnWithShell } from "./exec.js";
describe("runCommandWithTimeout", () => {
it("never enables shell execution (Windows cmd.exe injection hardening)", () => {
expect(
shouldSpawnWithShell({
resolvedCommand: "npm.cmd",
platform: "win32",
}),
).toBe(false);
});
it("merges custom env with process.env", async () => {
await withEnvAsync({ OPENCLAW_BASE_ENV: "base" }, async () => {
const result = await runCommandWithTimeout(
[
process.execPath,
"-e",
2026-01-30 03:15:10 +01:00
'process.stdout.write((process.env.OPENCLAW_BASE_ENV ?? "") + "|" + (process.env.OPENCLAW_TEST_ENV ?? ""))',
],
{
timeoutMs: 5_000,
2026-01-30 03:15:10 +01:00
env: { OPENCLAW_TEST_ENV: "ok" },
},
);
expect(result.code).toBe(0);
expect(result.stdout).toBe("base|ok");
expect(result.termination).toBe("exit");
});
});
it("kills command when no output timeout elapses", async () => {
const result = await runCommandWithTimeout(
2026-02-22 16:30:52 +00:00
[process.execPath, "-e", "setTimeout(() => {}, 40)"],
{
2026-02-22 16:30:52 +00:00
timeoutMs: 500,
noOutputTimeoutMs: 20,
},
);
expect(result.termination).toBe("no-output-timeout");
expect(result.noOutputTimedOut).toBe(true);
expect(result.code).not.toBe(0);
});
it("resets no output timer when command keeps emitting output", async () => {
const result = await runCommandWithTimeout(
[
process.execPath,
"-e",
2026-02-22 23:32:02 +01:00
[
'process.stdout.write(".");',
"let count = 0;",
'const ticker = setInterval(() => { process.stdout.write(".");',
"count += 1;",
"if (count === 4) {",
"clearInterval(ticker);",
"process.exit(0);",
"}",
2026-02-23 04:24:52 +00:00
"}, 60);",
2026-02-22 23:32:02 +01:00
].join(" "),
],
{
2026-02-22 23:32:02 +01:00
timeoutMs: 5_000,
2026-02-23 04:24:52 +00:00
noOutputTimeoutMs: 250,
},
);
2026-02-16 22:37:34 -05:00
expect(result.signal).toBeNull();
expect(result.code ?? 0).toBe(0);
expect(result.termination).toBe("exit");
expect(result.noOutputTimedOut).toBe(false);
2026-02-22 23:32:02 +01:00
expect(result.stdout.length).toBeGreaterThanOrEqual(5);
});
it("reports global timeout termination when overall timeout elapses", async () => {
const result = await runCommandWithTimeout(
2026-02-22 16:30:52 +00:00
[process.execPath, "-e", "setTimeout(() => {}, 40)"],
{
timeoutMs: 15,
},
);
expect(result.termination).toBe("timeout");
expect(result.noOutputTimedOut).toBe(false);
expect(result.code).not.toBe(0);
});
});