





















@@ -64,8 +64,63 @@ const GATEWAY_START_TIMEOUT_MS = 60_000;
6464const GATEWAY_STOP_TIMEOUT_MS = 1_500;
6565const GATEWAY_ENTRYPOINT_PREPARE_TIMEOUT_MS = 120_000;
6666const COMMAND_TIMEOUT_MS = 30_000;
67+const LOG_TAIL_MAX_BYTES = 256 * 1024;
6768const entrypointPromises = new Map<string, Promise<string[]>>();
686970+type BoundedStringLog = string[] & {
71+byteLength?: number;
72+truncated?: boolean;
73+};
74+75+function createBoundedStringLog(): string[] {
76+const log = [] as BoundedStringLog;
77+log.byteLength = 0;
78+log.truncated = false;
79+return log;
80+}
81+82+function appendLogChunk(log: string[], chunk: unknown, maxBytes = LOG_TAIL_MAX_BYTES): void {
83+const chunks = log as BoundedStringLog;
84+const limit = Math.max(1, maxBytes);
85+const text = String(chunk);
86+const textBytes = Buffer.byteLength(text);
87+if (textBytes >= limit) {
88+const buffer = Buffer.from(text);
89+const tail = buffer.subarray(buffer.length - limit).toString("utf8");
90+chunks.splice(0, chunks.length, tail);
91+chunks.byteLength = Buffer.byteLength(tail);
92+chunks.truncated = true;
93+return;
94+}
95+96+chunks.push(text);
97+chunks.byteLength = (chunks.byteLength ?? 0) + textBytes;
98+while ((chunks.byteLength ?? 0) > limit && chunks.length > 0) {
99+const first = chunks[0] ?? "";
100+const firstBytes = Buffer.byteLength(first);
101+const overflow = (chunks.byteLength ?? 0) - limit;
102+if (firstBytes <= overflow) {
103+chunks.shift();
104+chunks.byteLength = (chunks.byteLength ?? 0) - firstBytes;
105+chunks.truncated = true;
106+continue;
107+}
108+109+const buffer = Buffer.from(first);
110+const tail = buffer.subarray(overflow).toString("utf8");
111+chunks[0] = tail;
112+chunks.byteLength = chunks.reduce((total, entry) => total + Buffer.byteLength(entry), 0);
113+chunks.truncated = true;
114+}
115+}
116+117+function readLogBuffer(log: string[]): string {
118+const text = log.join("");
119+return (log as BoundedStringLog).truncated
120+ ? `[output truncated to last ${LOG_TAIL_MAX_BYTES} bytes]\n${text}`
121+ : text;
122+}
123+69124async function resolveBuiltGatewayEntrypoint(cwd: string): Promise<string[] | null> {
70125const buildStampPath = path.join(cwd, "dist", BUILD_STAMP_FILE);
71126const runtimePostBuildStampPath = path.join(cwd, "dist", RUNTIME_POSTBUILD_STAMP_FILE);
@@ -90,17 +145,17 @@ async function prepareGatewayEntrypoint(cwd: string): Promise<string[]> {
90145return builtEntrypoint;
91146}
9214793-const stdout: string[] = [];
94-const stderr: string[] = [];
148+const stdout = createBoundedStringLog();
149+const stderr = createBoundedStringLog();
95150const child = spawn("node", ["scripts/run-node.mjs", "--help"], {
96151 cwd,
97152env: { ...process.env, VITEST: "1" },
98153stdio: ["ignore", "pipe", "pipe"],
99154});
100155child.stdout?.setEncoding("utf8");
101156child.stderr?.setEncoding("utf8");
102-child.stdout?.on("data", (d) => stdout.push(String(d)));
103-child.stderr?.on("data", (d) => stderr.push(String(d)));
157+child.stdout?.on("data", (d) => appendLogChunk(stdout, d));
158+child.stderr?.on("data", (d) => appendLogChunk(stderr, d));
104159105160const completed = await Promise.race([
106161new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {
@@ -112,15 +167,13 @@ async function prepareGatewayEntrypoint(cwd: string): Promise<string[]> {
112167113168if (completed === null) {
114169child.kill("SIGKILL");
115-throw new Error(
116-`timeout preparing gateway entrypoint\n--- stdout ---\n${stdout.join("")}\n--- stderr ---\n${stderr.join("")}`,
117-);
170+throw new Error(`timeout preparing gateway entrypoint\n${formatLogs(stdout, stderr)}`);
118171}
119172if (completed.code !== 0) {
120173throw new Error(
121174`failed preparing gateway entrypoint (code=${String(completed.code)} signal=${String(
122175 completed.signal,
123- )})\n--- stdout ---\n${stdout.join("")}\n--- stderr ---\n${stderr.join("")}`,
176+ )})\n${formatLogs(stdout, stderr)}`,
124177);
125178}
126179@@ -224,7 +277,7 @@ function mergeConfig(
224277}
225278226279function formatLogs(stdout: string[], stderr: string[]): string {
227-return `--- stdout ---\n${stdout.join("")}\n--- stderr ---\n${stderr.join("")}`;
280+return `--- stdout ---\n${readLogBuffer(stdout)}\n--- stderr ---\n${readLogBuffer(stderr)}`;
228281}
229282230283function createInstanceEnv(params: {
@@ -282,8 +335,8 @@ export async function createOpenClawTestInstance(
282335),
283336);
284337285-const stdout: string[] = [];
286-const stderr: string[] = [];
338+const stdout = createBoundedStringLog();
339+const stderr = createBoundedStringLog();
287340const env = createInstanceEnv({
288341stateEnv: state.env,
289342extraEnv: options.env ?? {},
@@ -343,8 +396,8 @@ export async function createOpenClawTestInstance(
343396344397child.stdout?.setEncoding("utf8");
345398child.stderr?.setEncoding("utf8");
346-child.stdout?.on("data", (d) => stdout.push(String(d)));
347-child.stderr?.on("data", (d) => stderr.push(String(d)));
399+child.stdout?.on("data", (d) => appendLogChunk(stdout, d));
400+child.stderr?.on("data", (d) => appendLogChunk(stderr, d));
348401349402try {
350403await waitForPortOpen(
@@ -410,17 +463,17 @@ async function runCommand(params: {
410463if (!command) {
411464throw new Error("missing command");
412465}
413-const stdout: string[] = [];
414-const stderr: string[] = [];
466+const stdout = createBoundedStringLog();
467+const stderr = createBoundedStringLog();
415468const child = spawn(command, args, {
416469cwd: params.cwd,
417470env: params.env,
418471stdio: ["ignore", "pipe", "pipe"],
419472});
420473child.stdout?.setEncoding("utf8");
421474child.stderr?.setEncoding("utf8");
422-child.stdout?.on("data", (d) => stdout.push(String(d)));
423-child.stderr?.on("data", (d) => stderr.push(String(d)));
475+child.stdout?.on("data", (d) => appendLogChunk(stdout, d));
476+child.stderr?.on("data", (d) => appendLogChunk(stderr, d));
424477425478const completed = await Promise.race([
426479new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {
@@ -438,7 +491,13 @@ async function runCommand(params: {
438491}
439492return {
440493 ...completed,
441-stdout: stdout.join(""),
442-stderr: stderr.join(""),
494+stdout: readLogBuffer(stdout),
495+stderr: readLogBuffer(stderr),
443496};
444497}
498+499+export const testing = {
500+ appendLogChunk,
501+ createBoundedStringLog,
502+ formatLogs,
503+};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。