mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
improve: speed up targeted regression suites (#108609)
* test: speed up targeted regression suites * test: preserve subprocess startup headroom * test: keep secops-owned auth coverage unchanged
This commit is contained in:
committed by
GitHub
parent
2ab4f9f370
commit
c8c2b206e8
@@ -11,7 +11,6 @@ describe("base64 helpers", () => {
|
||||
const encoded = Buffer.alloc(1_900_000).toString("base64");
|
||||
|
||||
expect(canonicalizeBase64(encoded)).toBe(encoded);
|
||||
expect(canonicalizeBase64(encoded + "!")).toBeUndefined();
|
||||
});
|
||||
|
||||
it.each([
|
||||
|
||||
@@ -133,17 +133,15 @@ describe("ACP SDK protocol schema fixtures", () => {
|
||||
expect(
|
||||
validateJsonSchemaValue({
|
||||
schema,
|
||||
cacheKey: `acp:${name}:valid`,
|
||||
cacheKey: `acp:${name}`,
|
||||
value: valid,
|
||||
cache: false,
|
||||
}).ok,
|
||||
).toBe(true);
|
||||
expect(
|
||||
validateJsonSchemaValue({
|
||||
schema,
|
||||
cacheKey: `acp:${name}:invalid`,
|
||||
cacheKey: `acp:${name}`,
|
||||
value: invalid,
|
||||
cache: false,
|
||||
}).ok,
|
||||
).toBe(false);
|
||||
},
|
||||
|
||||
@@ -1,40 +1,33 @@
|
||||
// Child-process proof uses OpenClaw's real fatal unhandled-rejection handler so
|
||||
// a detached callback rejection would terminate the process.
|
||||
// The production subscriber call sites are covered in block-reply-rejections;
|
||||
// this child-process proof adds the real fatal unhandled-rejection handler.
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { spawnNodeEvalSync } from "../test-utils/node-process.js";
|
||||
|
||||
describe("embedded agent callback rejection containment", () => {
|
||||
it("keeps the production assistant progress path alive when its callback rejects", () => {
|
||||
it("keeps best-effort callbacks alive when their promises reject", () => {
|
||||
const result = spawnNodeEvalSync(
|
||||
`import { installUnhandledRejectionHandler } from "./src/infra/unhandled-rejections.ts";
|
||||
import { subscribeEmbeddedAgentSession } from "./src/agents/embedded-agent-subscribe.ts";
|
||||
import { runBestEffortCallback } from "./src/agents/embedded-agent-subscribe.callback.ts";
|
||||
installUnhandledRejectionHandler();
|
||||
let emit = () => {};
|
||||
let callbackCalls = 0;
|
||||
const session = {
|
||||
subscribe(handler) {
|
||||
emit = handler;
|
||||
return () => {};
|
||||
},
|
||||
};
|
||||
subscribeEmbeddedAgentSession({
|
||||
session,
|
||||
runId: "fatal-handler-proof",
|
||||
onAgentEvent: async () => {
|
||||
const warnings = [];
|
||||
runBestEffortCallback({
|
||||
label: "assistant agent event",
|
||||
log: { warn: (message) => warnings.push(message) },
|
||||
callback: async () => {
|
||||
callbackCalls += 1;
|
||||
throw new Error("assistant-progress-rejection");
|
||||
},
|
||||
});
|
||||
emit({
|
||||
type: "message_update",
|
||||
message: { role: "assistant" },
|
||||
assistantMessageEvent: { type: "text_delta", delta: "hello" },
|
||||
});
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
if (callbackCalls !== 1) {
|
||||
console.error("unexpected callback count: " + callbackCalls);
|
||||
process.exit(2);
|
||||
}
|
||||
if (!warnings.some((message) => message.includes("assistant-progress-rejection"))) {
|
||||
console.error("callback rejection was not logged");
|
||||
process.exit(3);
|
||||
}
|
||||
console.log("assistant callback rejection contained");`,
|
||||
{ imports: ["tsx"], timeout: 20_000 },
|
||||
);
|
||||
|
||||
@@ -90,7 +90,7 @@ describe("sessionsTailCommand", () => {
|
||||
let previousStateDir: string | undefined;
|
||||
|
||||
beforeEach(() => {
|
||||
setSessionsTailFollowIntervalMsForTests(10);
|
||||
setSessionsTailFollowIntervalMsForTests(2);
|
||||
previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-sessions-tail-"));
|
||||
process.env.OPENCLAW_STATE_DIR = path.join(tmpDir, "state");
|
||||
@@ -486,7 +486,7 @@ describe("sessionsTailCommand", () => {
|
||||
|
||||
fs.appendFileSync(trajectoryPath, line.subarray(0, markerOffset + 1));
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 100);
|
||||
setTimeout(resolve, 20);
|
||||
});
|
||||
fs.appendFileSync(trajectoryPath, line.subarray(markerOffset + 1));
|
||||
await waitForRuntimeOutput(runtime, "prompt skipped");
|
||||
@@ -570,7 +570,7 @@ describe("sessionsTailCommand", () => {
|
||||
expect(markerOffset).toBeGreaterThanOrEqual(0);
|
||||
fs.appendFileSync(trajectoryPath, partialLine.subarray(0, markerOffset + 1));
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 100);
|
||||
setTimeout(resolve, 20);
|
||||
});
|
||||
|
||||
const replacementPath = `${trajectoryPath}.replacement`;
|
||||
|
||||
@@ -220,12 +220,11 @@ describe("plugin lifecycle matrix probe", () => {
|
||||
["--input-type=module", "-e", parentScript],
|
||||
{
|
||||
env: { ...process.env, OPENCLAW_TEST_DESCENDANT_PID: descendantPidPath },
|
||||
timeoutKillGraceMs: 250,
|
||||
timeoutKillGraceMs: 100,
|
||||
timeoutMs: 500,
|
||||
},
|
||||
);
|
||||
await waitForFile(descendantPidPath, 2_000);
|
||||
await sleep(300);
|
||||
|
||||
await expect(run).rejects.toThrow(/timed out after 500ms/u);
|
||||
|
||||
|
||||
@@ -709,7 +709,7 @@ const grandchildScript = [
|
||||
" setTimeout(() => {",
|
||||
" fs.writeFileSync(process.argv[3], 'drained');",
|
||||
" process.exit(0);",
|
||||
" }, 50);",
|
||||
" }, 20);",
|
||||
"});",
|
||||
"fs.writeFileSync(process.argv[2], 'ready');",
|
||||
"setInterval(() => {}, 1000);",
|
||||
@@ -731,7 +731,7 @@ setInterval(() => {}, 1000);
|
||||
args: [scriptPath, readyPath, drainedPath],
|
||||
label: "timeout-leader-drain",
|
||||
phase: "probe",
|
||||
timeoutKillGraceMs: 1_000,
|
||||
timeoutKillGraceMs: 200,
|
||||
timeoutMs: 500,
|
||||
timeMode: "none",
|
||||
});
|
||||
@@ -953,19 +953,19 @@ const promise = runMeasuredCommandLive({
|
||||
)}, ${JSON.stringify(leaderExitedPath)}],
|
||||
label: "timeout-parent-termination",
|
||||
phase: "probe",
|
||||
timeoutKillGraceMs: 250,
|
||||
timeoutKillGraceMs: 150,
|
||||
timeoutMs: 200,
|
||||
timeMode: "none",
|
||||
});
|
||||
for (let attempt = 0; attempt < 200 && !fs.existsSync(${JSON.stringify(
|
||||
leaderExitedPath,
|
||||
)}); attempt += 1) {
|
||||
await delay(25);
|
||||
await delay(10);
|
||||
}
|
||||
if (!fs.existsSync(${JSON.stringify(leaderExitedPath)})) {
|
||||
process.exit(2);
|
||||
}
|
||||
await delay(50);
|
||||
await delay(20);
|
||||
process.kill(process.pid, "SIGTERM");
|
||||
await promise;
|
||||
process.exit(7);
|
||||
@@ -1067,7 +1067,7 @@ process.exit(7);
|
||||
"const marker = process.argv[1];",
|
||||
"fs.writeFileSync(marker, 'start\\n');",
|
||||
"process.on('SIGTERM', () => fs.appendFileSync(marker, 'term\\n'));",
|
||||
"setInterval(() => fs.appendFileSync(marker, 'tick\\n'), 5);",
|
||||
"setInterval(() => fs.appendFileSync(marker, 'tick\\n'), 1);",
|
||||
].join(""),
|
||||
markerPath,
|
||||
],
|
||||
@@ -1083,7 +1083,7 @@ process.exit(7);
|
||||
expect(row.wallMs).toBeLessThan(5_000);
|
||||
const afterReturn = await fs.readFile(markerPath, "utf8");
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 250);
|
||||
setTimeout(resolve, 30);
|
||||
});
|
||||
await expect(fs.readFile(markerPath, "utf8")).resolves.toBe(afterReturn);
|
||||
});
|
||||
|
||||
@@ -87,7 +87,7 @@ function writeStallingOpenClaw(
|
||||
"process.on('SIGTERM', () => {});",
|
||||
`setInterval(() => fs.appendFileSync(${JSON.stringify(
|
||||
options.gatewayDescendantMarkerPath,
|
||||
)}, "x"), 20);`,
|
||||
)}, "x"), 5);`,
|
||||
].join("\n")
|
||||
: "";
|
||||
const scriptPath = path.join(root, "fake-openclaw.mjs");
|
||||
@@ -283,7 +283,7 @@ describe("secret provider integration proof harness", () => {
|
||||
|
||||
const sizeAfterReturn = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 250);
|
||||
setTimeout(resolve, 40);
|
||||
});
|
||||
const sizeAfterWait = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
expect(sizeAfterWait).toBe(sizeAfterReturn);
|
||||
@@ -737,7 +737,7 @@ describe("secret provider integration proof harness", () => {
|
||||
"import fs from 'node:fs';",
|
||||
`fs.appendFileSync(${JSON.stringify(markerPath)}, "x");`,
|
||||
"process.on('SIGTERM', () => {});",
|
||||
`setInterval(() => fs.appendFileSync(${JSON.stringify(markerPath)}, "x"), 20);`,
|
||||
`setInterval(() => fs.appendFileSync(${JSON.stringify(markerPath)}, "x"), 5);`,
|
||||
].join("\n");
|
||||
fs.writeFileSync(
|
||||
scriptPath,
|
||||
@@ -763,7 +763,7 @@ describe("secret provider integration proof harness", () => {
|
||||
|
||||
const sizeAfterReturn = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 250);
|
||||
setTimeout(resolve, 40);
|
||||
});
|
||||
const sizeAfterWait = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
expect(sizeAfterWait).toBe(sizeAfterReturn);
|
||||
|
||||
@@ -983,7 +983,7 @@ describe("scripts/test-group-report child process guard", () => {
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
killGraceMs: 50,
|
||||
killGraceMs: 25,
|
||||
timeoutMs: 250,
|
||||
},
|
||||
);
|
||||
@@ -1015,13 +1015,13 @@ describe("scripts/test-group-report child process guard", () => {
|
||||
[
|
||||
"import fs from 'node:fs';",
|
||||
"process.on('SIGTERM', () => {});",
|
||||
`setInterval(() => fs.appendFileSync(${JSON.stringify(markerPath)}, "x"), 20);`,
|
||||
`setInterval(() => fs.appendFileSync(${JSON.stringify(markerPath)}, "x"), 5);`,
|
||||
].join("\n"),
|
||||
],
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
killGraceMs: 50,
|
||||
killGraceMs: 25,
|
||||
timeoutMs: 250,
|
||||
},
|
||||
);
|
||||
@@ -1035,7 +1035,7 @@ describe("scripts/test-group-report child process guard", () => {
|
||||
|
||||
const sizeAfterReturn = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 150);
|
||||
setTimeout(resolve, 40);
|
||||
});
|
||||
const sizeAfterWait = fs.existsSync(markerPath) ? fs.statSync(markerPath).size : 0;
|
||||
expect(sizeAfterWait).toBe(sizeAfterReturn);
|
||||
@@ -1066,7 +1066,7 @@ describe("scripts/test-group-report child process guard", () => {
|
||||
"const result = await spawnText(",
|
||||
' "/usr/bin/time",',
|
||||
` [process.execPath, "--eval", ${JSON.stringify(childScript)}],`,
|
||||
" { cwd: process.cwd(), env: process.env, killGraceMs: 50, timeoutMs: 500 },",
|
||||
" { cwd: process.cwd(), env: process.env, killGraceMs: 25, timeoutMs: 500 },",
|
||||
");",
|
||||
"process.stdout.write(JSON.stringify(result));",
|
||||
].join("\n");
|
||||
|
||||
Reference in New Issue
Block a user