Skip to content

Commit c757675

Browse files
authored
improve: keep isolated tests under one second (#100019)
* test: speed up isolated test suite * test: finish isolated latency cleanup * test: eliminate remaining isolated latency spikes * test: remove final isolated timing outliers * test: bound full-suite tooling processes * test: bound native test process lifetime * test: warm isolated runtime suites * test: eliminate final isolated timing outliers * test: fix isolated timing fixture types * test: make timeout cleanup timing deterministic * test: pin media manifests to source checkout * test: isolate provider manifest contracts * test: eliminate residual isolated timing spikes * test: restore final isolated timing fixes * test: eliminate remaining isolated timing spikes * test: warm Zalo lifecycle imports * test: keep isolated suites below one second * test: use readable browser response fixtures
1 parent 91f1883 commit c757675

93 files changed

Lines changed: 1815 additions & 993 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

extensions/browser/src/browser/pw-session.get-page-for-targetid.extension-fallback.test.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,15 @@ describe("pw-session getPageForTargetId", () => {
146146
urls: ["https://alpha.example", "https://beta.example"],
147147
}).pages;
148148

149-
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue({
150-
ok: true,
151-
json: async () => [
152-
{ id: "TARGET_A", url: "https://alpha.example" },
153-
{ id: "TARGET_B", url: "https://beta.example" },
154-
],
155-
} as Response);
149+
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(
150+
new Response(
151+
JSON.stringify([
152+
{ id: "TARGET_A", url: "https://alpha.example" },
153+
{ id: "TARGET_B", url: "https://beta.example" },
154+
]),
155+
{ headers: { "content-type": "application/json" } },
156+
),
157+
);
156158

157159
try {
158160
const resolved = await getPageForTargetId({
@@ -180,13 +182,15 @@ describe("pw-session getPageForTargetId", () => {
180182
});
181183
const [, pageB] = pages;
182184

183-
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue({
184-
ok: true,
185-
json: async () => [
186-
{ id: "TARGET_A", url: "https://alpha.example" },
187-
{ id: "TARGET_B", url: "https://beta.example" },
188-
],
189-
} as Response);
185+
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(
186+
new Response(
187+
JSON.stringify([
188+
{ id: "TARGET_A", url: "https://alpha.example" },
189+
{ id: "TARGET_B", url: "https://beta.example" },
190+
]),
191+
{ headers: { "content-type": "application/json" } },
192+
),
193+
);
190194

191195
try {
192196
const resolved = await getPageForTargetId({

extensions/browser/src/browser/routes/tabs.attach-only.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ describe("browser tab routes attachOnly loopback profiles", () => {
3939

4040
const fetchMock = vi.fn(async (url: unknown) => {
4141
expect(String(url)).toBe("http://127.0.0.1:9222/json/list");
42-
return {
43-
ok: true,
44-
json: async () => [
42+
return new Response(
43+
JSON.stringify([
4544
{
4645
id: "PAGE-1",
4746
title: "WordPress",
4847
url: "https://example.com/wp-login.php",
4948
webSocketDebuggerUrl: "ws://127.0.0.1:9222/devtools/page/PAGE-1",
5049
type: "page",
5150
},
52-
],
53-
} as unknown as Response;
51+
]),
52+
{ headers: { "content-type": "application/json" } },
53+
);
5454
});
5555
vi.stubGlobal("fetch", fetchMock);
5656

extensions/browser/src/browser/server.control-server.test-harness.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -551,15 +551,12 @@ export function makeResponse(
551551
body: unknown,
552552
init?: { ok?: boolean; status?: number; text?: string },
553553
): Response {
554-
const ok = init?.ok ?? true;
555-
const status = init?.status ?? 200;
556-
const text = init?.text ?? "";
557-
return {
558-
ok,
554+
const status = init?.status ?? (init?.ok === false ? 500 : 200);
555+
const responseBody = init?.text ?? JSON.stringify(body);
556+
return new Response(responseBody, {
559557
status,
560-
json: async () => body,
561-
text: async () => text,
562-
} as unknown as Response;
558+
headers: { "content-type": "application/json" },
559+
});
563560
}
564561

565562
function mockClearAll(obj: Record<string, { mockClear: () => unknown }>) {

extensions/browser/test-fetch.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,39 @@ type FetchWithPreconnect = {
1313
__openclawAcceptsDispatcher: true;
1414
};
1515

16+
type FetchFunction = (...args: unknown[]) => unknown;
17+
18+
// Bounded CDP readers consume arrayBuffer(); keep lightweight json-only test
19+
// responses compatible without weakening the production response boundary.
20+
function addArrayBufferFallback(response: unknown): unknown {
21+
if (!response || typeof response !== "object") {
22+
return response;
23+
}
24+
const partial = response as {
25+
arrayBuffer?: () => Promise<ArrayBuffer>;
26+
json?: () => Promise<unknown>;
27+
};
28+
if (typeof partial.arrayBuffer === "function" || typeof partial.json !== "function") {
29+
return response;
30+
}
31+
partial.arrayBuffer = async () =>
32+
new TextEncoder().encode(JSON.stringify(await partial.json!())).buffer;
33+
return response;
34+
}
35+
1636
/** Adds Browser test preconnect metadata to a fetch-like function. */
1737
export function withBrowserFetchPreconnect<T extends typeof fetch>(fn: T): T & FetchWithPreconnect;
1838
export function withBrowserFetchPreconnect<T extends object>(
1939
fn: T,
2040
): T & FetchWithPreconnect & typeof fetch;
2141
export function withBrowserFetchPreconnect(fn: object) {
22-
return Object.assign(fn, {
42+
const fetchFn = Object.assign(fn as FetchFunction, {
2343
preconnect: (_url: string | URL, _options?: FetchPreconnectOptions) => {},
2444
__openclawAcceptsDispatcher: true as const,
2545
});
46+
return new Proxy(fetchFn, {
47+
async apply(target, thisArg, args) {
48+
return addArrayBufferFallback(await Reflect.apply(target, thisArg, args));
49+
},
50+
});
2651
}

extensions/codex/src/app-server/compact.test.ts

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -860,43 +860,61 @@ describe("maybeCompactCodexAppServerSession", () => {
860860
rejectInterrupt: true,
861861
});
862862
const sessionFile = await writeTestBinding();
863+
const nativeSetTimeout = globalThis.setTimeout;
864+
let triggerCompletionTimeout: (() => void) | undefined;
865+
const setTimeoutSpy = vi
866+
.spyOn(globalThis, "setTimeout")
867+
.mockImplementation((callback, delay, ...args) => {
868+
if (delay === 1_000 && !triggerCompletionTimeout) {
869+
triggerCompletionTimeout = () => callback(...args);
870+
return nativeSetTimeout(() => undefined, 60_000);
871+
}
872+
return nativeSetTimeout(callback, delay, ...args);
873+
});
863874

864-
const pendingResult = maybeCompactCodexAppServerSessionImpl(
865-
{
866-
sessionId: "session-1",
867-
sessionKey: "agent:main:session-1",
868-
sessionFile,
869-
workspaceDir: tempDir,
870-
trigger: "manual",
871-
config: { agents: { defaults: { compaction: { timeoutSeconds: 1 } } } },
872-
},
873-
{
874-
clientFactory: async () => fake.client,
875-
nativeInterruptGraceMs: 10,
876-
},
877-
);
878-
await vi.waitFor(() => expect(fake.request).toHaveBeenCalledOnce());
879-
fake.emit({
880-
method: "turn/started",
881-
params: {
882-
threadId: "thread-1",
883-
turn: { id: "compact-turn-configured", threadId: "thread-1", status: "inProgress" },
884-
},
885-
});
875+
try {
876+
const pendingResult = maybeCompactCodexAppServerSessionImpl(
877+
{
878+
sessionId: "session-1",
879+
sessionKey: "agent:main:session-1",
880+
sessionFile,
881+
workspaceDir: tempDir,
882+
trigger: "manual",
883+
config: { agents: { defaults: { compaction: { timeoutSeconds: 1 } } } },
884+
},
885+
{
886+
clientFactory: async () => fake.client,
887+
nativeInterruptGraceMs: 10,
888+
},
889+
);
890+
await vi.waitFor(() => expect(fake.request).toHaveBeenCalledOnce());
891+
fake.emit({
892+
method: "turn/started",
893+
params: {
894+
threadId: "thread-1",
895+
turn: { id: "compact-turn-configured", threadId: "thread-1", status: "inProgress" },
896+
},
897+
});
886898

887-
await expect(pendingResult).resolves.toMatchObject({
888-
ok: false,
889-
compacted: false,
890-
reason: "codex app-server compaction did not reach terminal state after interruption",
891-
});
892-
expect(fake.request).toHaveBeenCalledWith(
893-
"turn/interrupt",
894-
{
895-
threadId: "thread-1",
896-
turnId: "compact-turn-configured",
897-
},
898-
{ timeoutMs: 10 },
899-
);
899+
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 1_000);
900+
expect(triggerCompletionTimeout).toBeDefined();
901+
triggerCompletionTimeout?.();
902+
expect(fake.request).toHaveBeenCalledWith(
903+
"turn/interrupt",
904+
{
905+
threadId: "thread-1",
906+
turnId: "compact-turn-configured",
907+
},
908+
{ timeoutMs: 10 },
909+
);
910+
await expect(pendingResult).resolves.toMatchObject({
911+
ok: false,
912+
compacted: false,
913+
reason: "codex app-server compaction did not reach terminal state after interruption",
914+
});
915+
} finally {
916+
setTimeoutSpy.mockRestore();
917+
}
900918
});
901919

902920
it("detaches a remote thread when its interrupted turn cannot be confirmed", async () => {

extensions/codex/src/web-search-provider.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from "node:path";
22
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
3-
import { describe, expect, it, vi } from "vitest";
3+
import { beforeAll, describe, expect, it, vi } from "vitest";
44
import { createCodexWebSearchProvider as createContractCodexWebSearchProvider } from "../web-search-contract-api.js";
55
import type { CodexAppServerClient } from "./app-server/client.js";
66
import type { CodexAppServerStartOptions } from "./app-server/config.js";
@@ -180,6 +180,12 @@ function createConfig(): OpenClawConfig {
180180
};
181181
}
182182

183+
beforeAll(async () => {
184+
// Execution cases share this lazy runtime. Import it once so the first case
185+
// does not absorb module initialization that every later case reuses.
186+
await import("./web-search-provider.runtime.js");
187+
});
188+
183189
describe("codex web search provider", () => {
184190
it("registers a selectable keyless provider contract", () => {
185191
const provider = createContractCodexWebSearchProvider();

extensions/discord/setup-entry.test.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,25 @@
22
import { describe, expect, it } from "vitest";
33
import setupEntry from "./setup-entry.js";
44

5+
type LegacyStateMigrationsApi = typeof import("./legacy-state-migrations-api.js");
6+
7+
const migrationDetector =
8+
(() => []) satisfies LegacyStateMigrationsApi["detectDiscordLegacyStateMigrations"];
9+
const setupEntryLoadOptions = {
10+
createLoaderForTest: (() => (specifier: string) => {
11+
expect(specifier).toMatch(/[\\/]legacy-state-migrations-api\.[jt]s$/u);
12+
return {
13+
detectDiscordLegacyStateMigrations: migrationDetector,
14+
} satisfies Pick<LegacyStateMigrationsApi, "detectDiscordLegacyStateMigrations">;
15+
}) as never,
16+
};
17+
518
describe("discord setup entry", () => {
6-
it("exposes legacy state migration detector through setup entry metadata", () => {
19+
it("resolves the legacy state migration detector through the setup entry", () => {
720
expect(setupEntry.kind).toBe("bundled-channel-setup-entry");
821
expect(setupEntry.features).toEqual({ legacyStateMigrations: true });
9-
expect(setupEntry.loadLegacyStateMigrationDetector?.()).toBeTypeOf("function");
22+
expect(setupEntry.loadLegacyStateMigrationDetector?.(setupEntryLoadOptions)).toBe(
23+
migrationDetector,
24+
);
1025
});
1126
});

extensions/google/image-generation-provider.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ describe("Google image-generation provider", () => {
307307

308308
it("accepts valid multi-image inline JSON responses above the generic provider JSON cap", async () => {
309309
mockGoogleApiKeyAuth();
310-
const imageBytes = Buffer.alloc(6 * 1024 * 1024, 1);
310+
const imageBytes = Buffer.alloc(4 * 1024 * 1024, 1);
311311
const imagePayload = imageBytes.toString("base64");
312312
vi.stubGlobal(
313313
"fetch",

0 commit comments

Comments
 (0)