mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 11:52:55 +00:00
fix(e2e): cap pty transcript output
This commit is contained in:
@@ -5,6 +5,7 @@ import { spawn } from "@lydell/node-pty";
|
||||
import { readPositiveIntEnv } from "./env-limits.mjs";
|
||||
|
||||
const [logPath, command, ...args] = process.argv.slice(2);
|
||||
const OUTPUT_MAX_BYTES = readPositiveIntEnv("OPENCLAW_E2E_PTY_OUTPUT_MAX_BYTES", 16 * 1024 * 1024);
|
||||
|
||||
if (!logPath || !command) {
|
||||
console.error("usage: run-with-pty.mjs <log-path> <command> [args...]");
|
||||
@@ -21,10 +22,37 @@ const pty = spawn(command, args, {
|
||||
});
|
||||
|
||||
let exiting = false;
|
||||
const outputLimitMarker = `\n[run-with-pty output truncated after ${OUTPUT_MAX_BYTES} bytes]\n`;
|
||||
const outputState = {
|
||||
bytes: 0,
|
||||
truncated: false,
|
||||
};
|
||||
|
||||
function writeCappedOutput(data) {
|
||||
if (outputState.truncated) {
|
||||
return;
|
||||
}
|
||||
const buffer = Buffer.from(data);
|
||||
const remainingBytes = OUTPUT_MAX_BYTES - outputState.bytes;
|
||||
if (buffer.byteLength <= remainingBytes) {
|
||||
outputState.bytes += buffer.byteLength;
|
||||
log.write(buffer);
|
||||
process.stdout.write(buffer);
|
||||
return;
|
||||
}
|
||||
if (remainingBytes > 0) {
|
||||
const head = buffer.subarray(0, remainingBytes);
|
||||
log.write(head);
|
||||
process.stdout.write(head);
|
||||
}
|
||||
outputState.bytes = OUTPUT_MAX_BYTES;
|
||||
outputState.truncated = true;
|
||||
log.write(outputLimitMarker);
|
||||
process.stdout.write(outputLimitMarker);
|
||||
}
|
||||
|
||||
pty.onData((data) => {
|
||||
log.write(data);
|
||||
process.stdout.write(data);
|
||||
writeCappedOutput(data);
|
||||
});
|
||||
|
||||
pty.onExit(({ exitCode, signal }) => {
|
||||
|
||||
@@ -11,19 +11,18 @@ const scriptPath = path.join(repoRoot, "scripts/e2e/lib/run-with-pty.mjs");
|
||||
function runPtyProbe(
|
||||
logPath: string,
|
||||
env: Record<string, string> = {},
|
||||
command: string[] = [
|
||||
"/bin/bash",
|
||||
"-lc",
|
||||
'printf "prompt\\n"; IFS= read -r value; printf "got:%s\\n" "$value"',
|
||||
],
|
||||
input = "abc\n",
|
||||
): Promise<{ code: number | null; stdout: string; stderr: string }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(
|
||||
process.execPath,
|
||||
[
|
||||
scriptPath,
|
||||
logPath,
|
||||
"/bin/bash",
|
||||
"-lc",
|
||||
'printf "prompt\\n"; IFS= read -r value; printf "got:%s\\n" "$value"',
|
||||
],
|
||||
{ env: { ...process.env, ...env }, stdio: ["pipe", "pipe", "pipe"] },
|
||||
);
|
||||
const child = spawn(process.execPath, [scriptPath, logPath, ...command], {
|
||||
env: { ...process.env, ...env },
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
});
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
const timeout = setTimeout(() => {
|
||||
@@ -47,7 +46,7 @@ function runPtyProbe(
|
||||
clearTimeout(timeout);
|
||||
resolve({ code, stdout, stderr });
|
||||
});
|
||||
child.stdin.end("abc\n");
|
||||
child.stdin.end(input);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,4 +80,27 @@ describe("run-with-pty", () => {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("caps noisy PTY output in stdout and transcript logs", async () => {
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), "openclaw-run-with-pty-"));
|
||||
const logPath = path.join(tempRoot, "pty.log");
|
||||
try {
|
||||
const result = await runPtyProbe(
|
||||
logPath,
|
||||
{ OPENCLAW_E2E_PTY_OUTPUT_MAX_BYTES: "64" },
|
||||
[process.execPath, "-e", "process.stdout.write('x'.repeat(2048))"],
|
||||
"",
|
||||
);
|
||||
const log = await readFile(logPath, "utf8");
|
||||
const marker = "[run-with-pty output truncated after 64 bytes]";
|
||||
|
||||
expect(result).toMatchObject({ code: 0, stderr: "" });
|
||||
expect(result.stdout).toContain(marker);
|
||||
expect(log).toContain(marker);
|
||||
expect(result.stdout.length).toBeLessThan(512);
|
||||
expect(log.length).toBeLessThan(512);
|
||||
} finally {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user