From 86a341be62877046b01eef9c1898531b03136470 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 23 Jan 2026 07:34:39 +0000 Subject: [PATCH] test: speed up history and cron suites --- src/gateway/server-constants.ts | 16 +++++++++++- src/gateway/server-methods/chat.ts | 4 +-- .../server.chat.gateway-server-chat-b.test.ts | 10 ++++--- src/gateway/server.cron.test.ts | 26 ++----------------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/gateway/server-constants.ts b/src/gateway/server-constants.ts index 58053a285..015164475 100644 --- a/src/gateway/server-constants.ts +++ b/src/gateway/server-constants.ts @@ -1,7 +1,21 @@ export const MAX_PAYLOAD_BYTES = 512 * 1024; // cap incoming frame size export const MAX_BUFFERED_BYTES = 1.5 * 1024 * 1024; // per-connection send buffer limit -export const MAX_CHAT_HISTORY_MESSAGES_BYTES = 6 * 1024 * 1024; // keep history responses comfortably under client WS limits +const DEFAULT_MAX_CHAT_HISTORY_MESSAGES_BYTES = 6 * 1024 * 1024; // keep history responses comfortably under client WS limits +let maxChatHistoryMessagesBytes = DEFAULT_MAX_CHAT_HISTORY_MESSAGES_BYTES; + +export const getMaxChatHistoryMessagesBytes = () => maxChatHistoryMessagesBytes; + +export const __setMaxChatHistoryMessagesBytesForTest = (value?: number) => { + if (!process.env.VITEST && process.env.NODE_ENV !== "test") return; + if (value === undefined) { + maxChatHistoryMessagesBytes = DEFAULT_MAX_CHAT_HISTORY_MESSAGES_BYTES; + return; + } + if (Number.isFinite(value) && value > 0) { + maxChatHistoryMessagesBytes = value; + } +}; export const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000; export const getHandshakeTimeoutMs = () => { if (process.env.VITEST && process.env.CLAWDBOT_TEST_HANDSHAKE_TIMEOUT_MS) { diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 92fd5f16a..8c71dca75 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -28,7 +28,7 @@ import { validateChatInjectParams, validateChatSendParams, } from "../protocol/index.js"; -import { MAX_CHAT_HISTORY_MESSAGES_BYTES } from "../server-constants.js"; +import { getMaxChatHistoryMessagesBytes } from "../server-constants.js"; import { capArrayByJsonBytes, loadSessionEntry, @@ -66,7 +66,7 @@ export const chatHandlers: GatewayRequestHandlers = { const max = Math.min(hardMax, requested); const sliced = rawMessages.length > max ? rawMessages.slice(-max) : rawMessages; const sanitized = stripEnvelopeFromMessages(sliced); - const capped = capArrayByJsonBytes(sanitized, MAX_CHAT_HISTORY_MESSAGES_BYTES).items; + const capped = capArrayByJsonBytes(sanitized, getMaxChatHistoryMessagesBytes()).items; let thinkingLevel = entry?.thinkingLevel; if (!thinkingLevel) { const configured = cfg.agents?.defaults?.thinkingDefault; diff --git a/src/gateway/server.chat.gateway-server-chat-b.test.ts b/src/gateway/server.chat.gateway-server-chat-b.test.ts index df3415953..78bd780e4 100644 --- a/src/gateway/server.chat.gateway-server-chat-b.test.ts +++ b/src/gateway/server.chat.gateway-server-chat-b.test.ts @@ -14,6 +14,7 @@ import { testState, writeSessionStore, } from "./test-helpers.js"; +import { __setMaxChatHistoryMessagesBytesForTest } from "./server-constants.js"; installGatewayTestHooks({ scope: "suite" }); async function waitFor(condition: () => boolean, timeoutMs = 1500) { const deadline = Date.now() + timeoutMs; @@ -52,6 +53,8 @@ describe("gateway server chat", () => { spy.mockResolvedValue(undefined); }; try { + const historyMaxBytes = 192 * 1024; + __setMaxChatHistoryMessagesBytesForTest(historyMaxBytes); await connectOk(ws); const sessionDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-gw-")); tempDirs.push(sessionDir); @@ -66,9 +69,9 @@ describe("gateway server chat", () => { }; await writeStore({ main: { sessionId: "sess-main", updatedAt: Date.now() } }); - const bigText = "x".repeat(155_000); + const bigText = "x".repeat(4_000); const largeLines: string[] = []; - for (let i = 0; i < 40; i += 1) { + for (let i = 0; i < 60; i += 1) { largeLines.push( JSON.stringify({ message: { @@ -91,7 +94,7 @@ describe("gateway server chat", () => { expect(cappedRes.ok).toBe(true); const cappedMsgs = cappedRes.payload?.messages ?? []; const bytes = Buffer.byteLength(JSON.stringify(cappedMsgs), "utf8"); - expect(bytes).toBeLessThanOrEqual(6 * 1024 * 1024); + expect(bytes).toBeLessThanOrEqual(historyMaxBytes); expect(cappedMsgs.length).toBeLessThan(60); await writeStore({ @@ -473,6 +476,7 @@ describe("gateway server chat", () => { : undefined; expect(run2).toBe("idem-2"); } finally { + __setMaxChatHistoryMessagesBytesForTest(); testState.sessionStorePath = undefined; sessionStoreSaveDelayMs.value = 0; ws.close(); diff --git a/src/gateway/server.cron.test.ts b/src/gateway/server.cron.test.ts index 1c6ee8c7c..4d7a136e9 100644 --- a/src/gateway/server.cron.test.ts +++ b/src/gateway/server.cron.test.ts @@ -5,7 +5,6 @@ import { describe, expect, test } from "vitest"; import { connectOk, installGatewayTestHooks, - onceMessage, rpcReq, startServerWithClient, testState, @@ -36,22 +35,6 @@ async function rmTempDir(dir: string) { await fs.rm(dir, { recursive: true, force: true }); } -async function waitForCronFinished( - ws: { send: (data: string) => void }, - jobId: string, - timeoutMs = 20_000, -) { - await onceMessage( - ws as never, - (o) => - o.type === "event" && - o.event === "cron" && - o.payload?.action === "finished" && - o.payload?.jobId === jobId, - timeoutMs, - ); -} - async function waitForNonEmptyFile(pathname: string, timeoutMs = 2000) { const startedAt = process.hrtime.bigint(); for (;;) { @@ -307,13 +290,10 @@ describe("gateway server cron", () => { const jobId = typeof jobIdValue === "string" ? jobIdValue : ""; expect(jobId.length > 0).toBe(true); - const finishedP = waitForCronFinished(ws, jobId); const runRes = await rpcReq(ws, "cron.run", { id: jobId, mode: "force" }, 20_000); expect(runRes.ok).toBe(true); - await finishedP; - const logPath = path.join(dir, "cron", "runs", `${jobId}.jsonl`); - const raw = await waitForNonEmptyFile(logPath); + const raw = await waitForNonEmptyFile(logPath, 5000); const line = raw .split("\n") .map((l) => l.trim()) @@ -359,9 +339,7 @@ describe("gateway server cron", () => { const autoJobId = typeof autoJobIdValue === "string" ? autoJobIdValue : ""; expect(autoJobId.length > 0).toBe(true); - await waitForCronFinished(ws, autoJobId); - - await waitForNonEmptyFile(path.join(dir, "cron", "runs", `${autoJobId}.jsonl`)); + await waitForNonEmptyFile(path.join(dir, "cron", "runs", `${autoJobId}.jsonl`), 5000); const autoEntries = (await rpcReq(ws, "cron.runs", { id: autoJobId, limit: 10 })).payload as | { entries?: Array<{ jobId?: unknown }> } | undefined;