mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:50:45 +00:00
perf(test): merge system run plan matrix tests
This commit is contained in:
@@ -222,6 +222,14 @@ const DENIED_RUNTIME_APPROVAL = {
|
|||||||
message: "SYSTEM_RUN_DENIED: approval cannot safely bind this interpreter/runtime command",
|
message: "SYSTEM_RUN_DENIED: approval cannot safely bind this interpreter/runtime command",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
function runNamedCase(name: string, run: () => void) {
|
||||||
|
try {
|
||||||
|
run();
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`case failed: ${name}`, { cause: error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function expectRuntimeApprovalDenied(command: string[], cwd: string) {
|
function expectRuntimeApprovalDenied(command: string[], cwd: string) {
|
||||||
const prepared = buildSystemRunApprovalPlan({ command, cwd });
|
const prepared = buildSystemRunApprovalPlan({ command, cwd });
|
||||||
expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
|
expect(prepared).toEqual(DENIED_RUNTIME_APPROVAL);
|
||||||
@@ -473,63 +481,67 @@ describe("hardenApprovedExecutionPaths", () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
it.runIf(process.platform !== "win32").each(cases)("$name", (testCase) => {
|
it.runIf(process.platform !== "win32")("handles approval hardening cases", () => {
|
||||||
const tmp = createFixtureDir("openclaw-approval-hardening-");
|
for (const testCase of cases) {
|
||||||
const oldPath = process.env.PATH;
|
runNamedCase(testCase.name, () => {
|
||||||
let pathToken: PathTokenSetup | null = null;
|
const tmp = createFixtureDir("openclaw-approval-hardening-");
|
||||||
if (testCase.withPathToken) {
|
const oldPath = process.env.PATH;
|
||||||
const binDir = path.join(tmp, "bin");
|
let pathToken: PathTokenSetup | null = null;
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
if (testCase.withPathToken) {
|
||||||
const link = path.join(binDir, "poccmd");
|
const binDir = path.join(tmp, "bin");
|
||||||
fs.symlinkSync("/bin/echo", link);
|
fs.mkdirSync(binDir, { recursive: true });
|
||||||
pathToken = { expected: fs.realpathSync(link) };
|
const link = path.join(binDir, "poccmd");
|
||||||
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
fs.symlinkSync("/bin/echo", link);
|
||||||
}
|
pathToken = { expected: fs.realpathSync(link) };
|
||||||
try {
|
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
||||||
if (testCase.mode === "build-plan") {
|
|
||||||
const prepared = buildSystemRunApprovalPlan({
|
|
||||||
command: testCase.argv,
|
|
||||||
cwd: tmp,
|
|
||||||
});
|
|
||||||
expect(prepared.ok).toBe(true);
|
|
||||||
if (!prepared.ok) {
|
|
||||||
throw new Error("unreachable");
|
|
||||||
}
|
}
|
||||||
expect(prepared.plan.argv).toEqual(testCase.expectedArgv({ pathToken }));
|
try {
|
||||||
if (testCase.expectedCmdText) {
|
if (testCase.mode === "build-plan") {
|
||||||
expect(prepared.plan.commandText).toBe(testCase.expectedCmdText);
|
const prepared = buildSystemRunApprovalPlan({
|
||||||
}
|
command: testCase.argv,
|
||||||
if (testCase.checkRawCommandMatchesArgv) {
|
cwd: tmp,
|
||||||
expect(prepared.plan.commandText).toBe(formatExecCommand(prepared.plan.argv));
|
});
|
||||||
}
|
expect(prepared.ok).toBe(true);
|
||||||
if ("expectedCommandPreview" in testCase) {
|
if (!prepared.ok) {
|
||||||
expect(prepared.plan.commandPreview ?? null).toBe(testCase.expectedCommandPreview);
|
throw new Error("unreachable");
|
||||||
}
|
}
|
||||||
return;
|
expect(prepared.plan.argv).toEqual(testCase.expectedArgv({ pathToken }));
|
||||||
}
|
if (testCase.expectedCmdText) {
|
||||||
|
expect(prepared.plan.commandText).toBe(testCase.expectedCmdText);
|
||||||
|
}
|
||||||
|
if (testCase.checkRawCommandMatchesArgv) {
|
||||||
|
expect(prepared.plan.commandText).toBe(formatExecCommand(prepared.plan.argv));
|
||||||
|
}
|
||||||
|
if ("expectedCommandPreview" in testCase) {
|
||||||
|
expect(prepared.plan.commandPreview ?? null).toBe(testCase.expectedCommandPreview);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const hardened = hardenApprovedExecutionPaths({
|
const hardened = hardenApprovedExecutionPaths({
|
||||||
approvedByAsk: true,
|
approvedByAsk: true,
|
||||||
argv: testCase.argv,
|
argv: testCase.argv,
|
||||||
shellCommand: testCase.shellCommand ?? null,
|
shellCommand: testCase.shellCommand ?? null,
|
||||||
cwd: tmp,
|
cwd: tmp,
|
||||||
});
|
});
|
||||||
expect(hardened.ok).toBe(true);
|
expect(hardened.ok).toBe(true);
|
||||||
if (!hardened.ok) {
|
if (!hardened.ok) {
|
||||||
throw new Error("unreachable");
|
throw new Error("unreachable");
|
||||||
}
|
}
|
||||||
expect(hardened.argv).toEqual(testCase.expectedArgv({ pathToken }));
|
expect(hardened.argv).toEqual(testCase.expectedArgv({ pathToken }));
|
||||||
if (typeof testCase.expectedArgvChanged === "boolean") {
|
if (typeof testCase.expectedArgvChanged === "boolean") {
|
||||||
expect(hardened.argvChanged).toBe(testCase.expectedArgvChanged);
|
expect(hardened.argvChanged).toBe(testCase.expectedArgvChanged);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (testCase.withPathToken) {
|
if (testCase.withPathToken) {
|
||||||
if (oldPath === undefined) {
|
if (oldPath === undefined) {
|
||||||
delete process.env.PATH;
|
delete process.env.PATH;
|
||||||
} else {
|
} else {
|
||||||
process.env.PATH = oldPath;
|
process.env.PATH = oldPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -776,39 +788,40 @@ describe("hardenApprovedExecutionPaths", () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
it.each(mutableOperandCases)(
|
it("captures mutable runtime operands in approval plans", () => {
|
||||||
"captures mutable $name operands in approval plans",
|
for (const runtimeCase of mutableOperandCases) {
|
||||||
(runtimeCase) => {
|
runNamedCase(runtimeCase.name, () => {
|
||||||
if (runtimeCase.skipOnWin32 && process.platform === "win32") {
|
if (runtimeCase.skipOnWin32 && process.platform === "win32") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const binNames =
|
const binNames =
|
||||||
runtimeCase.binNames ??
|
runtimeCase.binNames ??
|
||||||
(runtimeCase.binName ? [runtimeCase.binName] : ["bunx", "pnpm", "npm", "npx", "tsx"]);
|
(runtimeCase.binName ? [runtimeCase.binName] : ["bunx", "pnpm", "npm", "npx", "tsx"]);
|
||||||
withFakeRuntimeBins({
|
withFakeRuntimeBins({
|
||||||
binNames,
|
binNames,
|
||||||
run: () => {
|
run: () => {
|
||||||
withScriptOperandPlanFixture(
|
withScriptOperandPlanFixture(
|
||||||
{
|
{
|
||||||
tmpPrefix: "openclaw-approval-script-plan-",
|
tmpPrefix: "openclaw-approval-script-plan-",
|
||||||
fixture: runtimeCase,
|
fixture: runtimeCase,
|
||||||
afterWrite: (fixture, tmp) => {
|
afterWrite: (fixture, tmp) => {
|
||||||
const executablePath = fixture.command[0];
|
const executablePath = fixture.command[0];
|
||||||
if (executablePath?.endsWith("pnpm.js")) {
|
if (executablePath?.endsWith("pnpm.js")) {
|
||||||
const shimPath = path.join(tmp, "pnpm.js");
|
const shimPath = path.join(tmp, "pnpm.js");
|
||||||
fs.writeFileSync(shimPath, "#!/usr/bin/env node\nconsole.log('shim')\n");
|
fs.writeFileSync(shimPath, "#!/usr/bin/env node\nconsole.log('shim')\n");
|
||||||
fs.chmodSync(shimPath, 0o755);
|
fs.chmodSync(shimPath, 0o755);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
(fixture, tmp) => {
|
||||||
(fixture, tmp) => {
|
expectMutableFileOperandApprovalPlan(fixture, tmp);
|
||||||
expectMutableFileOperandApprovalPlan(fixture, tmp);
|
},
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
});
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
it("captures mutable shell script operands in approval plans", () => {
|
it("captures mutable shell script operands in approval plans", () => {
|
||||||
withScriptOperandPlanFixture(
|
withScriptOperandPlanFixture(
|
||||||
@@ -980,15 +993,19 @@ describe("hardenApprovedExecutionPaths", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each(unsafeRuntimeInvocationCases)("$name", (testCase) => {
|
it("rejects unsafe runtime invocation forms", () => {
|
||||||
withFakeRuntimeBin({
|
for (const testCase of unsafeRuntimeInvocationCases) {
|
||||||
binName: testCase.binName,
|
runNamedCase(testCase.name, () => {
|
||||||
run: () => {
|
withFakeRuntimeBin({
|
||||||
const tmp = createFixtureDir(testCase.tmpPrefix);
|
binName: testCase.binName,
|
||||||
testCase.setup?.(tmp);
|
run: () => {
|
||||||
expectRuntimeApprovalDenied(testCase.command, tmp);
|
const tmp = createFixtureDir(testCase.tmpPrefix);
|
||||||
},
|
testCase.setup?.(tmp);
|
||||||
});
|
expectRuntimeApprovalDenied(testCase.command, tmp);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("detects rewritten script operands for pnpm dlx approval plans", () => {
|
it("detects rewritten script operands for pnpm dlx approval plans", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user