mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(e2e): reject loose lifecycle metric limits
This commit is contained in:
@@ -8,16 +8,25 @@ if (!summaryPath || !phase || separator !== "--" || !command) {
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const pageSize = Number.parseInt(process.env.OPENCLAW_PROC_PAGE_SIZE || "4096", 10);
|
||||
const clockTicks = Number.parseInt(process.env.OPENCLAW_PROC_CLK_TCK || "100", 10);
|
||||
const pollMs = Number.parseInt(process.env.OPENCLAW_PLUGIN_LIFECYCLE_METRIC_POLL_MS || "100", 10);
|
||||
const timeoutMs = Number.parseInt(
|
||||
process.env.OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS || "300000",
|
||||
10,
|
||||
);
|
||||
const timeoutKillGraceMs = Number.parseInt(
|
||||
process.env.OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS || "2000",
|
||||
10,
|
||||
function readPositiveIntEnv(name, fallback) {
|
||||
const text = String(process.env[name] ?? fallback).trim();
|
||||
if (!/^\d+$/u.test(text)) {
|
||||
throw new Error(`${name} must be a positive integer; got: ${text}`);
|
||||
}
|
||||
const value = Number(text);
|
||||
if (!Number.isSafeInteger(value) || value <= 0) {
|
||||
throw new Error(`${name} must be a positive integer; got: ${text}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const pageSize = readPositiveIntEnv("OPENCLAW_PROC_PAGE_SIZE", 4096);
|
||||
const clockTicks = readPositiveIntEnv("OPENCLAW_PROC_CLK_TCK", 100);
|
||||
const pollMs = readPositiveIntEnv("OPENCLAW_PLUGIN_LIFECYCLE_METRIC_POLL_MS", 100);
|
||||
const timeoutMs = readPositiveIntEnv("OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS", 300000);
|
||||
const timeoutKillGraceMs = readPositiveIntEnv(
|
||||
"OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS",
|
||||
2000,
|
||||
);
|
||||
|
||||
if (!fs.existsSync("/proc")) {
|
||||
|
||||
@@ -45,13 +45,51 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("plugin lifecycle resource sampler", () => {
|
||||
it("rejects loose numeric env values instead of parsing prefixes", () => {
|
||||
const dir = makeTempDir();
|
||||
const summary = path.join(dir, "summary.tsv");
|
||||
const result = spawnSync("node", [scriptPath, summary, "invalid-env", "--", "node", "-e", ""], {
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS: "150ms",
|
||||
},
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain(
|
||||
"OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS must be a positive integer; got: 150ms",
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects zero lifecycle timeouts instead of disabling the guard", () => {
|
||||
const dir = makeTempDir();
|
||||
const summary = path.join(dir, "summary.tsv");
|
||||
const result = spawnSync("node", [scriptPath, summary, "invalid-env", "--", "node", "-e", ""], {
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS: "0",
|
||||
},
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain(
|
||||
"OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS must be a positive integer; got: 0",
|
||||
);
|
||||
});
|
||||
|
||||
it("configures a phase timeout with process-group cleanup", () => {
|
||||
const script = readFileSync(scriptPath, "utf8");
|
||||
|
||||
expect(script).toContain("OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS");
|
||||
expect(script).toContain("OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS");
|
||||
expect(script).toContain("detached: true");
|
||||
expect(script).toContain('process.kill(-child.pid, signal)');
|
||||
expect(script).toContain("process.kill(-child.pid, signal)");
|
||||
expect(script).toContain('const summarySignal = timedOut ? "timeout"');
|
||||
expect(script).toContain("process.exit(124)");
|
||||
});
|
||||
@@ -78,7 +116,9 @@ describe("plugin lifecycle resource sampler", () => {
|
||||
|
||||
expect(result.status).toBe(124);
|
||||
expect(result.stdout).toContain("signal=timeout");
|
||||
expect(readFileSync(summary, "utf8")).toMatch(/^wedged\t\d+\t[\d.]+\t\d+\t[\d.]+\ttimeout$/mu);
|
||||
expect(readFileSync(summary, "utf8")).toMatch(
|
||||
/^wedged\t\d+\t[\d.]+\t\d+\t[\d.]+\ttimeout$/mu,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user