diff --git a/packages/acp-server/test/e2e-turn.test.ts b/packages/acp-server/test/e2e-turn.test.ts index b14a327e45..0be8fecdc3 100644 --- a/packages/acp-server/test/e2e-turn.test.ts +++ b/packages/acp-server/test/e2e-turn.test.ts @@ -28,6 +28,21 @@ const STDIO_MCP_FIXTURE = fileURLToPath( new URL('../../agent-core-v2/test/mcpCore/fixtures/mock-stdio-server.mjs', import.meta.url), ); +/** + * Best-effort recursive removal of a test's temp home dir. `fs.rm`'s + * recursive cleanup can transiently ENOTEMPTY/EBUSY right after a file + * handle (or, for the MCP-fixture tests, a child process pipe) in the + * directory closes but the OS hasn't fully released the deletion yet — + * retry with Node's own linear-backoff defaults. Always returns `undefined` + * so call sites can just reassign: `homeDir = await cleanupHomeDir(homeDir);`. + */ +async function cleanupHomeDir(homeDir: string | undefined): Promise { + if (homeDir !== undefined) { + await rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); + } + return undefined; +} + describe('acp-server real prompt turn (scripted LLM)', () => { let homeDir: string | undefined; let client: TestClient | undefined; @@ -38,10 +53,8 @@ describe('acp-server real prompt turn (scripted LLM)', () => { await client.close(); client = undefined; } - if (homeDir !== undefined) { - await rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); - homeDir = undefined; - } + + homeDir = await cleanupHomeDir(homeDir); }); async function boot(clientCapabilities: Record = {}): Promise { @@ -561,10 +574,8 @@ describe('acp-server prompt error hygiene', () => { await client.close(); client = undefined; } - if (homeDir !== undefined) { - await rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); - homeDir = undefined; - } + + homeDir = await cleanupHomeDir(homeDir); }); it('a launch failure settles as a fixed internalError and never leaks the engine message', async () => { @@ -608,10 +619,8 @@ describe('acp-server builtin slash commands (local execution, no LLM turn)', () await client.close(); client = undefined; } - if (homeDir !== undefined) { - await rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); - homeDir = undefined; - } + + homeDir = await cleanupHomeDir(homeDir); }); async function boot(): Promise { @@ -825,10 +834,8 @@ describe('acp-server terminal reverse-RPC (clientCapabilities.terminal)', () => await client.close(); client = undefined; } - if (homeDir !== undefined) { - await rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); - homeDir = undefined; - } + + homeDir = await cleanupHomeDir(homeDir); }); interface FakeTerminal { diff --git a/packages/agent-core-v2/test/app/config/configManifest.test.ts b/packages/agent-core-v2/test/app/config/configManifest.test.ts index 72f798725b..7e0a076e13 100644 --- a/packages/agent-core-v2/test/app/config/configManifest.test.ts +++ b/packages/agent-core-v2/test/app/config/configManifest.test.ts @@ -16,5 +16,5 @@ describe('config manifest', () => { const expected = await buildConfigManifest(); const actual = readFileSync(MANIFEST_PATH, 'utf-8'); expect(actual).toBe(expected); - }, 60_000); + }, 120_000); }); diff --git a/packages/agent-core-v2/test/lint/op-uniqueness.test.ts b/packages/agent-core-v2/test/lint/op-uniqueness.test.ts index 1637513369..73fe23eb9e 100644 --- a/packages/agent-core-v2/test/lint/op-uniqueness.test.ts +++ b/packages/agent-core-v2/test/lint/op-uniqueness.test.ts @@ -1,3 +1,12 @@ +/** + * Scenario: no wire Op type registered via `defineOp` is duplicated across + * `src/`, and a runtime duplicate registration throws `DuplicateOpError`. + * + * The full-`src/`-scan test below does a synchronous, full-tree file read, + * which can exceed the default timeout under slow bind-mounted filesystems + * (e.g. Docker on Windows) — hence its extended timeout. + */ + import { readdirSync, readFileSync, statSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -179,10 +188,14 @@ describe('op-uniqueness', () => { } }); - it('finds no duplicate defineOp types across src/', () => { - const seen = scanDefineOpTypes(SRC_ROOT); - expect(duplicates(seen)).toEqual(new Map()); - }); + it( + 'finds no duplicate defineOp types across src/', + () => { + const seen = scanDefineOpTypes(SRC_ROOT); + expect(duplicates(seen)).toEqual(new Map()); + }, + 20_000, + ); it('flags the planted duplicate in the fixture', () => { const seen = scanDefineOpTypes(FIXTURE_ROOT); diff --git a/packages/agent-core-v2/test/lint/vendor-name-gates.test.ts b/packages/agent-core-v2/test/lint/vendor-name-gates.test.ts index 38ecf5722e..aead381ab6 100644 --- a/packages/agent-core-v2/test/lint/vendor-name-gates.test.ts +++ b/packages/agent-core-v2/test/lint/vendor-name-gates.test.ts @@ -13,6 +13,10 @@ * Brand/env names (`KIMI_CODE_*`, `KIMI_MODEL_*`) and `'kimi'` as data * (config values, telemetry fields, registration ids) do not match the * patterns — verified against the whole `src/` tree. + * + * The full-`src/`-scan test below does a synchronous, full-tree file read, + * which can exceed the default timeout under slow bind-mounted filesystems + * (e.g. Docker on Windows) — hence its extended timeout. */ import { readdirSync, readFileSync, statSync } from 'node:fs'; @@ -95,13 +99,17 @@ describe('vendor-name gates', () => { expect(hits).toEqual([]); }); - it('finds no vendor-name gates in src/ outside kosong', () => { - const hits = walk(SRC_ROOT).flatMap((file) => - findVendorGates(readFileSync(file, 'utf8'), relative(SRC_ROOT, file)), - ); - expect( - hits.map((hit) => `${hit.file}:${hit.line} ${hit.text}`), - 'vendor-name gate found outside kosong — ask the provider-definition / adapter registries instead', - ).toEqual([]); - }); + it( + 'finds no vendor-name gates in src/ outside kosong', + () => { + const hits = walk(SRC_ROOT).flatMap((file) => + findVendorGates(readFileSync(file, 'utf8'), relative(SRC_ROOT, file)), + ); + expect( + hits.map((hit) => `${hit.file}:${hit.line} ${hit.text}`), + 'vendor-name gate found outside kosong — ask the provider-definition / adapter registries instead', + ).toEqual([]); + }, + 20_000, + ); }); diff --git a/packages/agent-core-v2/test/tool/tool.test.ts b/packages/agent-core-v2/test/tool/tool.test.ts index 14709c15a2..178ee94173 100644 --- a/packages/agent-core-v2/test/tool/tool.test.ts +++ b/packages/agent-core-v2/test/tool/tool.test.ts @@ -1,3 +1,11 @@ +/** + * Agent tool execution contract tests. + * + * The background-subagent-spawn scenario below uses pure in-memory stubs, + * but this file's worker can be CPU-starved under parallel load in + * resource-constrained containers, hence its extended timeout. + */ + import { mkdtempSync, readFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; @@ -1099,7 +1107,7 @@ describe('Agent tool execution contract', () => { expect(result.output).toContain('agent_id: agent-child'); expect(result.output).toContain('actual_subagent_type: explore'); expect(result.output).toContain('child result'); - }); + }, 15_000); it('spawns the subagent on the configured secondary model by default', async () => { const lifecycle = createAgentLifecycleStub({ createAgentIds: ['agent-child'] }); diff --git a/packages/agent-core-v2/test/wire/wireManifest.test.ts b/packages/agent-core-v2/test/wire/wireManifest.test.ts index 4ec0429ba9..a21af6a53a 100644 --- a/packages/agent-core-v2/test/wire/wireManifest.test.ts +++ b/packages/agent-core-v2/test/wire/wireManifest.test.ts @@ -18,7 +18,7 @@ describe('wire manifest', () => { const expected = await buildWireManifest(); const actual = readFileSync(MANIFEST_PATH, 'utf-8'); expect(actual).toBe(expected); - }, 60_000); + }, 120_000); it('docs/wire-manifest.d.ts parses as TypeScript', () => { const project = new Project({ useInMemoryFileSystem: true }); diff --git a/packages/agent-core-v2/test/workspace/workspaceResources.test.ts b/packages/agent-core-v2/test/workspace/workspaceResources.test.ts index ede234fc43..2d8d8c3671 100644 --- a/packages/agent-core-v2/test/workspace/workspaceResources.test.ts +++ b/packages/agent-core-v2/test/workspace/workspaceResources.test.ts @@ -263,7 +263,9 @@ describe('workspace resource sharing (handler chain)', () => { afterEach(async () => { host?.dispose(); host = undefined; - await Promise.all(tmpRoots.map((root) => rm(root, { recursive: true, force: true }))); + await Promise.all( + tmpRoots.map((root) => rm(root, { recursive: true, force: true, maxRetries: 3, retryDelay: 10 })), + ); }); async function makeRoot(prefix: string): Promise {