mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 07:24:32 +00:00
test(perf): reduce guardrail and media test overhead
This commit is contained in:
@@ -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: "",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user