mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 18:30:44 +00:00
refactor: share system run plan test fixtures
This commit is contained in:
@@ -68,20 +68,36 @@ function createScriptOperandFixture(tmp: string, fixture?: RuntimeFixture): Scri
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function withFakeRuntimeBin<T>(params: { binName: string; run: () => T }): T {
|
function writeFakeRuntimeBin(binDir: string, binName: string) {
|
||||||
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), `openclaw-${params.binName}-bin-`));
|
|
||||||
const binDir = path.join(tmp, "bin");
|
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
|
||||||
const runtimePath =
|
const runtimePath =
|
||||||
process.platform === "win32"
|
process.platform === "win32" ? path.join(binDir, `${binName}.cmd`) : path.join(binDir, binName);
|
||||||
? path.join(binDir, `${params.binName}.cmd`)
|
|
||||||
: path.join(binDir, params.binName);
|
|
||||||
const runtimeBody =
|
const runtimeBody =
|
||||||
process.platform === "win32" ? "@echo off\r\nexit /b 0\r\n" : "#!/bin/sh\nexit 0\n";
|
process.platform === "win32" ? "@echo off\r\nexit /b 0\r\n" : "#!/bin/sh\nexit 0\n";
|
||||||
fs.writeFileSync(runtimePath, runtimeBody, { mode: 0o755 });
|
fs.writeFileSync(runtimePath, runtimeBody, { mode: 0o755 });
|
||||||
if (process.platform !== "win32") {
|
if (process.platform !== "win32") {
|
||||||
fs.chmodSync(runtimePath, 0o755);
|
fs.chmodSync(runtimePath, 0o755);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function withFakeRuntimeBin<T>(params: { binName: string; run: () => T }): T {
|
||||||
|
return withFakeRuntimeBins({
|
||||||
|
binNames: [params.binName],
|
||||||
|
tmpPrefix: `openclaw-${params.binName}-bin-`,
|
||||||
|
run: params.run,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function withFakeRuntimeBins<T>(params: {
|
||||||
|
binNames: string[];
|
||||||
|
tmpPrefix?: string;
|
||||||
|
run: () => T;
|
||||||
|
}): T {
|
||||||
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), params.tmpPrefix ?? "openclaw-runtime-bins-"));
|
||||||
|
const binDir = path.join(tmp, "bin");
|
||||||
|
fs.mkdirSync(binDir, { recursive: true });
|
||||||
|
for (const binName of params.binNames) {
|
||||||
|
writeFakeRuntimeBin(binDir, binName);
|
||||||
|
}
|
||||||
const oldPath = process.env.PATH;
|
const oldPath = process.env.PATH;
|
||||||
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
||||||
try {
|
try {
|
||||||
@@ -96,32 +112,44 @@ function withFakeRuntimeBin<T>(params: { binName: string; run: () => T }): T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function withFakeRuntimeBins<T>(params: { binNames: string[]; run: () => T }): T {
|
function expectMutableFileOperandApprovalPlan(fixture: ScriptOperandFixture, cwd: string) {
|
||||||
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-runtime-bins-"));
|
const prepared = buildSystemRunApprovalPlan({
|
||||||
const binDir = path.join(tmp, "bin");
|
command: fixture.command,
|
||||||
fs.mkdirSync(binDir, { recursive: true });
|
cwd,
|
||||||
for (const binName of params.binNames) {
|
});
|
||||||
const runtimePath =
|
expect(prepared.ok).toBe(true);
|
||||||
process.platform === "win32"
|
if (!prepared.ok) {
|
||||||
? path.join(binDir, `${binName}.cmd`)
|
throw new Error("unreachable");
|
||||||
: path.join(binDir, binName);
|
|
||||||
const runtimeBody =
|
|
||||||
process.platform === "win32" ? "@echo off\r\nexit /b 0\r\n" : "#!/bin/sh\nexit 0\n";
|
|
||||||
fs.writeFileSync(runtimePath, runtimeBody, { mode: 0o755 });
|
|
||||||
if (process.platform !== "win32") {
|
|
||||||
fs.chmodSync(runtimePath, 0o755);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const oldPath = process.env.PATH;
|
expect(prepared.plan.mutableFileOperand).toEqual({
|
||||||
process.env.PATH = `${binDir}${path.delimiter}${oldPath ?? ""}`;
|
argvIndex: fixture.expectedArgvIndex,
|
||||||
|
path: fs.realpathSync(fixture.scriptPath),
|
||||||
|
sha256: expect.any(String),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeScriptOperandFixture(fixture: ScriptOperandFixture) {
|
||||||
|
fs.writeFileSync(fixture.scriptPath, fixture.initialBody);
|
||||||
|
if (process.platform !== "win32") {
|
||||||
|
fs.chmodSync(fixture.scriptPath, 0o755);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function withScriptOperandPlanFixture<T>(
|
||||||
|
params: {
|
||||||
|
tmpPrefix: string;
|
||||||
|
fixture?: RuntimeFixture;
|
||||||
|
afterWrite?: (fixture: ScriptOperandFixture, tmp: string) => void;
|
||||||
|
},
|
||||||
|
run: (fixture: ScriptOperandFixture, tmp: string) => T,
|
||||||
|
) {
|
||||||
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), params.tmpPrefix));
|
||||||
|
const fixture = createScriptOperandFixture(tmp, params.fixture);
|
||||||
|
writeScriptOperandFixture(fixture);
|
||||||
|
params.afterWrite?.(fixture, tmp);
|
||||||
try {
|
try {
|
||||||
return params.run();
|
return run(fixture, tmp);
|
||||||
} finally {
|
} finally {
|
||||||
if (oldPath === undefined) {
|
|
||||||
delete process.env.PATH;
|
|
||||||
} else {
|
|
||||||
process.env.PATH = oldPath;
|
|
||||||
}
|
|
||||||
fs.rmSync(tmp, { recursive: true, force: true });
|
fs.rmSync(tmp, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,61 +460,37 @@ describe("hardenApprovedExecutionPaths", () => {
|
|||||||
withFakeRuntimeBins({
|
withFakeRuntimeBins({
|
||||||
binNames,
|
binNames,
|
||||||
run: () => {
|
run: () => {
|
||||||
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-approval-script-plan-"));
|
withScriptOperandPlanFixture(
|
||||||
const fixture = createScriptOperandFixture(tmp, runtimeCase);
|
{
|
||||||
fs.writeFileSync(fixture.scriptPath, fixture.initialBody);
|
tmpPrefix: "openclaw-approval-script-plan-",
|
||||||
const executablePath = fixture.command[0];
|
fixture: runtimeCase,
|
||||||
if (executablePath?.endsWith("pnpm.js")) {
|
afterWrite: (fixture, tmp) => {
|
||||||
const shimPath = path.join(tmp, "pnpm.js");
|
const executablePath = fixture.command[0];
|
||||||
fs.writeFileSync(shimPath, "#!/usr/bin/env node\nconsole.log('shim')\n");
|
if (executablePath?.endsWith("pnpm.js")) {
|
||||||
fs.chmodSync(shimPath, 0o755);
|
const shimPath = path.join(tmp, "pnpm.js");
|
||||||
}
|
fs.writeFileSync(shimPath, "#!/usr/bin/env node\nconsole.log('shim')\n");
|
||||||
try {
|
fs.chmodSync(shimPath, 0o755);
|
||||||
const prepared = buildSystemRunApprovalPlan({
|
}
|
||||||
command: fixture.command,
|
},
|
||||||
cwd: tmp,
|
},
|
||||||
});
|
(fixture, tmp) => {
|
||||||
expect(prepared.ok).toBe(true);
|
expectMutableFileOperandApprovalPlan(fixture, tmp);
|
||||||
if (!prepared.ok) {
|
},
|
||||||
throw new Error("unreachable");
|
);
|
||||||
}
|
|
||||||
expect(prepared.plan.mutableFileOperand).toEqual({
|
|
||||||
argvIndex: fixture.expectedArgvIndex,
|
|
||||||
path: fs.realpathSync(fixture.scriptPath),
|
|
||||||
sha256: expect.any(String),
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
fs.rmSync(tmp, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
it("captures mutable shell script operands in approval plans", () => {
|
it("captures mutable shell script operands in approval plans", () => {
|
||||||
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-approval-script-plan-"));
|
withScriptOperandPlanFixture(
|
||||||
const fixture = createScriptOperandFixture(tmp);
|
{
|
||||||
fs.writeFileSync(fixture.scriptPath, fixture.initialBody);
|
tmpPrefix: "openclaw-approval-script-plan-",
|
||||||
if (process.platform !== "win32") {
|
},
|
||||||
fs.chmodSync(fixture.scriptPath, 0o755);
|
(fixture, tmp) => {
|
||||||
}
|
expectMutableFileOperandApprovalPlan(fixture, tmp);
|
||||||
try {
|
},
|
||||||
const prepared = buildSystemRunApprovalPlan({
|
);
|
||||||
command: fixture.command,
|
|
||||||
cwd: tmp,
|
|
||||||
});
|
|
||||||
expect(prepared.ok).toBe(true);
|
|
||||||
if (!prepared.ok) {
|
|
||||||
throw new Error("unreachable");
|
|
||||||
}
|
|
||||||
expect(prepared.plan.mutableFileOperand).toEqual({
|
|
||||||
argvIndex: fixture.expectedArgvIndex,
|
|
||||||
path: fs.realpathSync(fixture.scriptPath),
|
|
||||||
sha256: expect.any(String),
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
fs.rmSync(tmp, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rejects bun package script names that do not bind a concrete file", () => {
|
it("rejects bun package script names that do not bind a concrete file", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user