test(perf): reduce guardrail and media test overhead

This commit is contained in:
Peter Steinberger
2026-03-02 11:16:29 +00:00
parent bff785aecc
commit 1b98879295
3 changed files with 22 additions and 25 deletions

View File

@@ -7,6 +7,7 @@ import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/config.js";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { fetchRemoteMedia } from "../media/fetch.js"; import { fetchRemoteMedia } from "../media/fetch.js";
import { runExec } from "../process/exec.js";
import { withEnvAsync } from "../test-utils/env.js"; import { withEnvAsync } from "../test-utils/env.js";
import { clearMediaUnderstandingBinaryCacheForTests } from "./runner.js"; import { clearMediaUnderstandingBinaryCacheForTests } from "./runner.js";
@@ -33,6 +34,7 @@ vi.mock("../process/exec.js", () => ({
})); }));
let applyMediaUnderstanding: typeof import("./apply.js").applyMediaUnderstanding; let applyMediaUnderstanding: typeof import("./apply.js").applyMediaUnderstanding;
const mockedRunExec = vi.mocked(runExec);
const TEMP_MEDIA_PREFIX = "openclaw-media-"; const TEMP_MEDIA_PREFIX = "openclaw-media-";
let suiteTempMediaRootDir = ""; let suiteTempMediaRootDir = "";
@@ -191,8 +193,7 @@ async function setupAudioAutoDetectCase(stdout: string): Promise<{
content: "audio", content: "audio",
}); });
const cfg: OpenClawConfig = { tools: { media: { audio: {} } } }; const cfg: OpenClawConfig = { tools: { media: { audio: {} } } };
const execModule = await import("../process/exec.js"); mockedRunExec.mockResolvedValueOnce({
vi.mocked(execModule.runExec).mockResolvedValueOnce({
stdout, stdout,
stderr: "", stderr: "",
}); });
@@ -241,6 +242,7 @@ describe("applyMediaUnderstanding", () => {
beforeEach(() => { beforeEach(() => {
mockedResolveApiKey.mockClear(); mockedResolveApiKey.mockClear();
mockedFetchRemoteMedia.mockClear(); mockedFetchRemoteMedia.mockClear();
mockedRunExec.mockReset();
mockedFetchRemoteMedia.mockResolvedValue({ mockedFetchRemoteMedia.mockResolvedValue({
buffer: Buffer.from([0, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), buffer: Buffer.from([0, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
contentType: "audio/ogg", contentType: "audio/ogg",
@@ -403,8 +405,7 @@ describe("applyMediaUnderstanding", () => {
}, },
}; };
const execModule = await import("../process/exec.js"); mockedRunExec.mockResolvedValue({
vi.mocked(execModule.runExec).mockResolvedValue({
stdout: "cli transcript\n", stdout: "cli transcript\n",
stderr: "", stderr: "",
}); });
@@ -437,8 +438,6 @@ describe("applyMediaUnderstanding", () => {
await fs.writeFile(path.join(modelDir, "joiner.onnx"), "a"); await fs.writeFile(path.join(modelDir, "joiner.onnx"), "a");
const { ctx, cfg } = await setupAudioAutoDetectCase('{"text":"sherpa ok"}'); const { ctx, cfg } = await setupAudioAutoDetectCase('{"text":"sherpa ok"}');
const execModule = await import("../process/exec.js");
const mockedRunExec = vi.mocked(execModule.runExec);
await withMediaAutoDetectEnv( await withMediaAutoDetectEnv(
{ {
@@ -467,8 +466,6 @@ describe("applyMediaUnderstanding", () => {
await fs.writeFile(modelPath, "model"); await fs.writeFile(modelPath, "model");
const { ctx, cfg } = await setupAudioAutoDetectCase("whisper cpp ok\n"); const { ctx, cfg } = await setupAudioAutoDetectCase("whisper cpp ok\n");
const execModule = await import("../process/exec.js");
const mockedRunExec = vi.mocked(execModule.runExec);
await withMediaAutoDetectEnv( await withMediaAutoDetectEnv(
{ {
@@ -499,10 +496,6 @@ describe("applyMediaUnderstanding", () => {
}); });
const cfg: OpenClawConfig = { tools: { media: { audio: {} } } }; const cfg: OpenClawConfig = { tools: { media: { audio: {} } } };
const execModule = await import("../process/exec.js");
const mockedRunExec = vi.mocked(execModule.runExec);
mockedRunExec.mockReset();
await withMediaAutoDetectEnv( await withMediaAutoDetectEnv(
{ {
PATH: emptyBinDir, PATH: emptyBinDir,
@@ -548,8 +541,7 @@ describe("applyMediaUnderstanding", () => {
}, },
}; };
const execModule = await import("../process/exec.js"); mockedRunExec.mockResolvedValue({
vi.mocked(execModule.runExec).mockResolvedValue({
stdout: "image description\n", stdout: "image description\n",
stderr: "", stderr: "",
}); });
@@ -593,8 +585,7 @@ describe("applyMediaUnderstanding", () => {
}, },
}; };
const execModule = await import("../process/exec.js"); mockedRunExec.mockResolvedValue({
vi.mocked(execModule.runExec).mockResolvedValue({
stdout: "shared description\n", stdout: "shared description\n",
stderr: "", stderr: "",
}); });

View File

@@ -15,6 +15,13 @@ const windowsAuditEnv = {
USERNAME: "Tester", USERNAME: "Tester",
USERDOMAIN: "DESKTOP-TEST", USERDOMAIN: "DESKTOP-TEST",
}; };
const execDockerRawUnavailable: NonNullable<SecurityAuditOptions["execDockerRawFn"]> = async () => {
return {
stdout: Buffer.alloc(0),
stderr: Buffer.from("docker unavailable"),
code: 1,
};
};
function stubChannelPlugin(params: { function stubChannelPlugin(params: {
id: "discord" | "slack" | "telegram"; id: "discord" | "slack" | "telegram";
@@ -609,6 +616,7 @@ description: test skill
platform: "win32", platform: "win32",
env: windowsAuditEnv, env: windowsAuditEnv,
execIcacls, execIcacls,
execDockerRawFn: execDockerRawUnavailable,
}); });
const forbidden = new Set([ const forbidden = new Set([
@@ -655,6 +663,7 @@ description: test skill
platform: "win32", platform: "win32",
env: windowsAuditEnv, env: windowsAuditEnv,
execIcacls, execIcacls,
execDockerRawFn: execDockerRawUnavailable,
}); });
expect( expect(
@@ -2673,6 +2682,7 @@ description: test skill
includeChannelSecurity: false, includeChannelSecurity: false,
deep: false, deep: false,
stateDir: sharedCodeSafetyStateDir, stateDir: sharedCodeSafetyStateDir,
execDockerRawFn: execDockerRawUnavailable,
}); });
expect(nonDeepRes.findings.some((f) => f.checkId === "plugins.code_safety")).toBe(false); expect(nonDeepRes.findings.some((f) => f.checkId === "plugins.code_safety")).toBe(false);
@@ -2687,6 +2697,7 @@ description: test skill
deep: true, deep: true,
stateDir: sharedCodeSafetyStateDir, stateDir: sharedCodeSafetyStateDir,
probeGatewayFn: async (opts) => successfulProbeResult(opts.url), probeGatewayFn: async (opts) => successfulProbeResult(opts.url),
execDockerRawFn: execDockerRawUnavailable,
}); });
const pluginFinding = deepRes.findings.find( const pluginFinding = deepRes.findings.find(

View File

@@ -10,6 +10,8 @@ type QuoteScanState = {
quote: QuoteChar | null; quote: QuoteChar | null;
escaped: boolean; escaped: boolean;
}; };
const WEAK_RANDOM_SAME_LINE_PATTERN =
/(?:Date\.now[^\r\n]*Math\.random|Math\.random[^\r\n]*Date\.now)/u;
function shouldSkip(relativePath: string): boolean { function shouldSkip(relativePath: string): boolean {
return shouldSkipGuardrailRuntimeSource(relativePath); return shouldSkipGuardrailRuntimeSource(relativePath);
@@ -223,15 +225,8 @@ describe("temp path guard", () => {
if (hasDynamicTmpdirJoin(file.source)) { if (hasDynamicTmpdirJoin(file.source)) {
offenders.push(relativePath); offenders.push(relativePath);
} }
if (file.source.includes("Date.now") && file.source.includes("Math.random")) { if (WEAK_RANDOM_SAME_LINE_PATTERN.test(file.source)) {
const lines = file.source.split(/\r?\n/); weakRandomMatches.push(relativePath);
for (let idx = 0; idx < lines.length; idx += 1) {
const line = lines[idx] ?? "";
if (!line.includes("Date.now") || !line.includes("Math.random")) {
continue;
}
weakRandomMatches.push(`${relativePath}:${idx + 1}`);
}
} }
} }