Skip to content

Commit e856a24

Browse files
committed
fix(qa): bound docker e2e log replay
1 parent 9dbdefd commit e856a24

10 files changed

Lines changed: 120 additions & 16 deletions

scripts/e2e/agent-bundle-mcp-tools-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ set -e
3535

3636
if [ "$status" -ne 0 ]; then
3737
echo "Docker OpenClaw bundle MCP tool availability smoke failed"
38-
cat "$RUN_LOG"
38+
docker_e2e_print_log "$RUN_LOG"
3939
exit "$status"
4040
fi
4141

42-
cat "$RUN_LOG"
42+
docker_e2e_print_log "$RUN_LOG"
4343
echo "OK"

scripts/e2e/commitments-safety-docker.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ set -e
3131

3232
if [ "$status" -ne 0 ]; then
3333
echo "Docker commitments safety smoke failed"
34-
cat "$RUN_LOG"
34+
docker_e2e_print_log "$RUN_LOG"
3535
exit "$status"
3636
fi
3737

scripts/e2e/crestodian-first-run-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ set -e
3535

3636
if [ "$status" -ne 0 ]; then
3737
echo "Docker Crestodian first-run smoke failed"
38-
cat "$RUN_LOG"
38+
docker_e2e_print_log "$RUN_LOG"
3939
exit "$status"
4040
fi
4141

42-
cat "$RUN_LOG"
42+
docker_e2e_print_log "$RUN_LOG"
4343
echo "OK"

scripts/e2e/crestodian-planner-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ set -e
3535

3636
if [ "$status" -ne 0 ]; then
3737
echo "Docker Crestodian planner fallback smoke failed"
38-
cat "$RUN_LOG"
38+
docker_e2e_print_log "$RUN_LOG"
3939
exit "$status"
4040
fi
4141

42-
cat "$RUN_LOG"
42+
docker_e2e_print_log "$RUN_LOG"
4343
echo "OK"

scripts/e2e/crestodian-rescue-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ set -e
3535

3636
if [ "$status" -ne 0 ]; then
3737
echo "Docker Crestodian rescue smoke failed"
38-
cat "$RUN_LOG"
38+
docker_e2e_print_log "$RUN_LOG"
3939
exit "$status"
4040
fi
4141

42-
cat "$RUN_LOG"
42+
docker_e2e_print_log "$RUN_LOG"
4343
echo "OK"

scripts/e2e/plugin-binding-command-escape-docker.sh

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,24 @@ set -e
4040

4141
if [ "$status" -ne 0 ]; then
4242
echo "Docker plugin binding command escape smoke failed"
43-
cat "$RUN_LOG"
43+
docker_e2e_print_log "$RUN_LOG"
4444
exit "$status"
4545
fi
4646

4747
if ! node - "$RUN_LOG" <<'NODE'
4848
const fs = require("node:fs");
4949
const logPath = process.argv[2];
50-
const text = fs
51-
.readFileSync(logPath, "utf8")
52-
.replace(/\x1B\[[0-?]*[ -/]*[@-~]/gu, "");
50+
const scanBytes = 65536;
51+
const stat = fs.statSync(logPath);
52+
const length = Math.min(stat.size, scanBytes);
53+
const buffer = Buffer.alloc(length);
54+
const fd = fs.openSync(logPath, "r");
55+
try {
56+
fs.readSync(fd, buffer, 0, length, stat.size - length);
57+
} finally {
58+
fs.closeSync(fd);
59+
}
60+
const text = buffer.toString("utf8").replace(/\x1B\[[0-?]*[ -/]*[@-~]/gu, "");
5361
5462
if (!/(?:^|\n)\s*Tests\s+3 passed\b/u.test(text)) {
5563
console.error("expected focused Vitest summary for exactly 3 passed tests");
@@ -59,7 +67,7 @@ if (!/(?:^|\n)\s*Tests\s+3 passed\b/u.test(text)) {
5967
NODE
6068
then
6169
echo "Docker plugin binding command escape smoke did not stay focused"
62-
cat "$RUN_LOG"
70+
docker_e2e_print_log "$RUN_LOG"
6371
exit 1
6472
fi
6573

scripts/e2e/session-runtime-context-docker.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ set -e
3232

3333
if [ "$status" -ne 0 ]; then
3434
echo "Docker session runtime context smoke failed"
35-
cat "$RUN_LOG"
35+
docker_e2e_print_log "$RUN_LOG"
3636
exit "$status"
3737
fi
3838

scripts/plugin-sdk-surface-report.mjs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,46 @@ import {
1414
} from "./lib/plugin-sdk-entries.mjs";
1515

1616
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
17-
const checkOnly = process.argv.includes("--check");
17+
function usage() {
18+
return `Usage: node scripts/plugin-sdk-surface-report.mjs [--check]
19+
20+
Reports plugin SDK export surface metadata.
21+
22+
Options:
23+
--check Fail when SDK surface budgets are exceeded.
24+
-h, --help Show this help.
25+
`;
26+
}
27+
28+
function parseArgs(argv) {
29+
const args = { check: false, help: false };
30+
for (const arg of argv) {
31+
if (arg === "--check") {
32+
args.check = true;
33+
continue;
34+
}
35+
if (arg === "--help" || arg === "-h") {
36+
args.help = true;
37+
continue;
38+
}
39+
throw new Error(`Unknown plugin SDK surface report option: ${arg}`);
40+
}
41+
return args;
42+
}
43+
44+
let cliArgs;
45+
try {
46+
cliArgs = parseArgs(process.argv.slice(2));
47+
} catch (error) {
48+
console.error(error instanceof Error ? error.message : String(error));
49+
process.exit(1);
50+
}
51+
if (cliArgs.help) {
52+
process.stdout.write(usage());
53+
process.exit(0);
54+
}
55+
56+
const checkOnly = cliArgs.check;
1857
const publicEntrypointSet = new Set(publicPluginSdkEntrypoints);
1958
const localOnlyEntrypointSet = new Set(privateLocalOnlyPluginSdkEntrypoints);
2059
const deprecatedPublicEntrypointSet = new Set(deprecatedPublicPluginSdkEntrypoints);

test/scripts/docker-build-helper.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ const QR_IMPORT_DOCKER_E2E_PATH = "scripts/e2e/qr-import-docker.sh";
5656
const MULTI_NODE_UPDATE_DOCKER_E2E_PATH = "scripts/e2e/multi-node-update-docker.sh";
5757
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_E2E_PATH =
5858
"scripts/e2e/bundled-plugin-install-uninstall-docker.sh";
59+
const AGENT_BUNDLE_MCP_TOOLS_DOCKER_E2E_PATH =
60+
"scripts/e2e/agent-bundle-mcp-tools-docker.sh";
61+
const COMMITMENTS_SAFETY_DOCKER_E2E_PATH = "scripts/e2e/commitments-safety-docker.sh";
62+
const CRESTODIAN_FIRST_RUN_DOCKER_E2E_PATH = "scripts/e2e/crestodian-first-run-docker.sh";
63+
const CRESTODIAN_PLANNER_DOCKER_E2E_PATH = "scripts/e2e/crestodian-planner-docker.sh";
64+
const CRESTODIAN_RESCUE_DOCKER_E2E_PATH = "scripts/e2e/crestodian-rescue-docker.sh";
65+
const SESSION_RUNTIME_CONTEXT_DOCKER_E2E_PATH =
66+
"scripts/e2e/session-runtime-context-docker.sh";
5967
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_SWEEP_PATH =
6068
"scripts/e2e/lib/bundled-plugin-install-uninstall/sweep.sh";
6169
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_PROBE_PATH =
@@ -3360,6 +3368,31 @@ output="$(cat "$sampler_log")"
33603368
}
33613369
});
33623370

3371+
it("keeps captured Docker E2E run log replay bounded", () => {
3372+
for (const path of [
3373+
AGENT_BUNDLE_MCP_TOOLS_DOCKER_E2E_PATH,
3374+
COMMITMENTS_SAFETY_DOCKER_E2E_PATH,
3375+
CRESTODIAN_FIRST_RUN_DOCKER_E2E_PATH,
3376+
CRESTODIAN_PLANNER_DOCKER_E2E_PATH,
3377+
CRESTODIAN_RESCUE_DOCKER_E2E_PATH,
3378+
PLUGIN_BINDING_COMMAND_ESCAPE_DOCKER_E2E_PATH,
3379+
SESSION_RUNTIME_CONTEXT_DOCKER_E2E_PATH,
3380+
]) {
3381+
const runner = readFileSync(path, "utf8");
3382+
3383+
expect(runner, path).toContain('RUN_LOG="$(mktemp');
3384+
expect(runner, path).toContain('docker_e2e_print_log "$RUN_LOG"');
3385+
expect(runner, path).not.toContain('cat "$RUN_LOG"');
3386+
}
3387+
3388+
const pluginBinding = readFileSync(PLUGIN_BINDING_COMMAND_ESCAPE_DOCKER_E2E_PATH, "utf8");
3389+
expect(pluginBinding).toContain("const scanBytes = 65536");
3390+
expect(pluginBinding).toContain("fs.statSync(logPath)");
3391+
expect(pluginBinding).toContain("fs.readSync(fd, buffer, 0, length, stat.size - length)");
3392+
expect(pluginBinding).not.toContain("process.env.OPENCLAW_DOCKER_E2E_LOG_PRINT_BYTES");
3393+
expect(pluginBinding).not.toContain('readFileSync(logPath, "utf8")');
3394+
});
3395+
33633396
it("keeps Open WebUI Docker E2E resource-guarded", () => {
33643397
const runner = readFileSync(OPENWEBUI_DOCKER_E2E_PATH, "utf8");
33653398

test/scripts/plugin-sdk-surface-report.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@ function readDefaultPublicFunctionExportBudget() {
2727
}
2828

2929
describe("plugin SDK surface report", () => {
30+
it("rejects unknown CLI options before collecting SDK stats", () => {
31+
const result = spawnSync(process.execPath, ["scripts/plugin-sdk-surface-report.mjs", "--chekc"], {
32+
cwd: process.cwd(),
33+
encoding: "utf8",
34+
});
35+
36+
expect(result.status).toBe(1);
37+
expect(result.stdout).toBe("");
38+
expect(result.stderr.trim()).toBe("Unknown plugin SDK surface report option: --chekc");
39+
expect(result.stderr).not.toContain("at ");
40+
});
41+
42+
it("prints help before collecting SDK stats", () => {
43+
const result = spawnSync(process.execPath, ["scripts/plugin-sdk-surface-report.mjs", "--help"], {
44+
cwd: process.cwd(),
45+
encoding: "utf8",
46+
});
47+
48+
expect(result.status).toBe(0);
49+
expect(result.stdout).toContain("Usage: node scripts/plugin-sdk-surface-report.mjs");
50+
expect(result.stderr).toBe("");
51+
expect(result.stdout).not.toContain("all SDK entrypoints:");
52+
});
53+
3054
it("rejects loose numeric budget env vars before collecting SDK stats", () => {
3155
const result = runSurfaceReport({
3256
OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS: "1e9",

0 commit comments

Comments
 (0)