From b7f7eb7378064aa7e94d8c70784d9df8552c5b34 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 26 Oct 2026 16:28:42 +0100 Subject: [PATCH] test(omp): enforce responsive history replay in CI Use a smaller structured transcript and a short selected chain to expose whole-file parsing without making large-output GC part of the CI gate. Disable unrelated provider discovery and route the regression through the existing integration job. --- packages/server/package.json | 2 +- .../agent/providers/omp/history.e2e.test.ts | 47 ++++++++++++------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/server/package.json b/packages/server/package.json index 4aeb01dc3f..f39d284343 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -89,7 +89,7 @@ "speech:transcribe:local": "tsx scripts/transcribe-local-wav.ts", "test": "npm run test:unit && npm run test:integration", "test:unit": "vitest run --fileParallelism --exclude \"**/*.e2e.test.ts\"", - "test:integration": "vitest run --maxWorkers=1 src/server/git-filename-diffs.e2e.test.ts src/server/daemon-e2e/checkout-diff-content.e2e.test.ts src/server/daemon-e2e/filesystem.e2e.test.ts src/server/daemon-e2e/file-download.e2e.test.ts src/server/daemon-e2e/cli-logs-follow.e2e.test.ts src/server/creation/creation.e2e.test.ts src/server/daemon-e2e/terminal-workspace-sdk.e2e.test.ts src/server/workspace-create-worktree-source.e2e.test.ts src/server/daemon-e2e/models.e2e.test.ts src/server/daemon-e2e/live-preferences.e2e.test.ts src/server/daemon-e2e/oversized-message.e2e.test.ts src/server/agent/model-catalog.e2e.test.ts src/server/plugins/plugin-paseo-api.e2e.test.ts src/server/connected-hosts/hosts.e2e.test.ts && vitest run --maxWorkers=1 src/server/daemon-e2e/git-operations.e2e.test.ts src/server/session.create-agent-worktree-autoarchive.e2e.test.ts src/server/agent/providers/opencode-bridge.local.e2e.test.ts src/server/daemon-e2e/relay-transport.e2e.test.ts -t \"merges into|creates a worktree and auto-archives both|versioned runtime|oversized attachments|connected hosts|password-protected daemon refuses\"", + "test:integration": "vitest run --maxWorkers=1 src/server/git-filename-diffs.e2e.test.ts src/server/daemon-e2e/checkout-diff-content.e2e.test.ts src/server/daemon-e2e/filesystem.e2e.test.ts src/server/daemon-e2e/file-download.e2e.test.ts src/server/daemon-e2e/cli-logs-follow.e2e.test.ts src/server/creation/creation.e2e.test.ts src/server/daemon-e2e/terminal-workspace-sdk.e2e.test.ts src/server/workspace-create-worktree-source.e2e.test.ts src/server/daemon-e2e/models.e2e.test.ts src/server/daemon-e2e/live-preferences.e2e.test.ts src/server/daemon-e2e/oversized-message.e2e.test.ts src/server/agent/model-catalog.e2e.test.ts src/server/plugins/plugin-paseo-api.e2e.test.ts src/server/connected-hosts/hosts.e2e.test.ts && vitest run --maxWorkers=1 src/server/agent/providers/omp/history.e2e.test.ts src/server/daemon-e2e/git-operations.e2e.test.ts src/server/session.create-agent-worktree-autoarchive.e2e.test.ts src/server/agent/providers/opencode-bridge.local.e2e.test.ts src/server/daemon-e2e/relay-transport.e2e.test.ts -t \"merges into|creates a worktree and auto-archives both|versioned runtime|oversized attachments|connected hosts|password-protected daemon refuses|replays selected OMP history\"", "test:hub-cli-contract": "vitest run --maxWorkers=1 src/server/hub/hub-cli-contract.test.ts", "test:integration:all": "npm run test:e2e", "test:integration:real": "vitest run real.e2e.test.ts", diff --git a/packages/server/src/server/agent/providers/omp/history.e2e.test.ts b/packages/server/src/server/agent/providers/omp/history.e2e.test.ts index 5450560922..77521a9687 100644 --- a/packages/server/src/server/agent/providers/omp/history.e2e.test.ts +++ b/packages/server/src/server/agent/providers/omp/history.e2e.test.ts @@ -1,3 +1,4 @@ +import { BUILTIN_PROVIDER_IDS } from "@getpaseo/protocol/provider-manifest"; import { mkdtemp, open, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -8,11 +9,17 @@ import { createTestPaseoDaemon } from "../../../test-utils/paseo-daemon.js"; import { DaemonClient } from "../../../test-utils/daemon-client.js"; import { readActiveOmpEntryChain } from "./history.js"; -test("replays a 300 MiB active chain without blocking the event loop", async () => { +test("replays selected OMP history without blocking the event loop", async () => { const directory = await mkdtemp(join(tmpdir(), "omp-history-budget-")); const sessionFile = join(directory, "session.jsonl"); + const started = performance.now(); try { - const daemon = await createTestPaseoDaemon(); + const daemon = await createTestPaseoDaemon({ + // This regression exercises file replay and daemon requests, not executable discovery. + providerOverrides: Object.fromEntries( + BUILTIN_PROVIDER_IDS.map((id) => [id, { enabled: false }]), + ), + }); const client = new DaemonClient({ url: `ws://127.0.0.1:${daemon.port}/ws`, appVersion: "0.13.2", @@ -22,11 +29,13 @@ test("replays a 300 MiB active chain without blocking the event loop", async () await client.fetchAgents({ subscribe: {} }); await client.getDaemonStatus(); const file = await open(sessionFile, "w"); - const text = "x".repeat(16 * 1024); + // Structured message blocks expose document-sized parsing at a modest byte size. + // Replay an earlier active entry so inactive payload retention cannot drive the probe. + const text = Array.from({ length: 64 }, () => ({ type: "text", text: "x" })); let bytes = 0; let count = 0; try { - while (bytes < 300 * 1024 * 1024) { + while (bytes < 28 * 1024 * 1024) { const line = JSON.stringify({ type: "message", @@ -51,7 +60,7 @@ test("replays a 300 MiB active chain without blocking the event loop", async () try { const replayState = { finished: false }; let repliesDuringReplay = 0; - const replay = readActiveOmpEntryChain(sessionFile).finally(() => { + const replay = readActiveOmpEntryChain(sessionFile, "row-0").finally(() => { replayState.finished = true; }); // A real WebSocket RPC served by the isolated daemon on the same event loop. @@ -64,24 +73,30 @@ test("replays a 300 MiB active chain without blocking the event loop", async () })(); const [entries] = await Promise.all([replay, requests]); await delay(10); - console.log(JSON.stringify({ bytes, count, longestGap, repliesDuringReplay })); - expect(repliesDuringReplay).toBeGreaterThan(0); - expect(entries.length).toBe(count); - for (let index = 0; index < entries.length; index++) { - expect(entries[index]).toEqual({ + console.log( + JSON.stringify({ + bytes, + count, + longestGap, + repliesDuringReplay, + generationAndLoadMs: performance.now() - started, + }), + ); + expect(entries).toEqual([ + { type: "message", - id: `row-${index}`, - parentId: index ? `row-${index - 1}` : null, + id: "row-0", + parentId: null, message: { role: "user", content: text }, - }); - } + }, + ]); expect(longestGap).toBeLessThan(50); + expect(repliesDuringReplay).toBeGreaterThan(0); } finally { clearInterval(probe); } } finally { - await client.close(); - await daemon.close(); + await client.close().finally(() => daemon.close()); } } finally { await rm(directory, { recursive: true, force: true });