diff --git a/docs/testing.md b/docs/testing.md index fbd1765a4..afca62054 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -46,6 +46,11 @@ claim, even if a directory name calls it acceptance. Emit a verifier's final success report only after awaited cleanup. Observe final process lineage after closing its owned resources. +The Vitest runner releases cached native process inspectors during awaited +worker teardown. Fork termination does not run Node's normal exit hooks; a +per-file teardown would instead retire shared inspectors before later files +can use them. + Measure slow files before removing capacity regressions. Optimize repeated process startup, fixture construction, and production algorithms when they dominate runtime. Keep at least one input beyond each formerly failing size or @@ -356,7 +361,7 @@ are separate proof levels. Synthetic producer regressions run independently: ```sh -npm run test:focused -- tests/boundary/android/jadxIntegration.test.ts tests/boundary/mcp/androidAnalysisMcp.test.ts +npm run test:focused -- tests/boundary/process/jadxIntegration.test.ts tests/boundary/process/androidAnalysisMcp.test.ts ``` ## Optional NativeAOT Ghidra analysis diff --git a/knip.json b/knip.json index 5ac657f65..ae8742b2c 100644 --- a/knip.json +++ b/knip.json @@ -1,6 +1,11 @@ { "$schema": "./node_modules/knip/schema.json", - "entry": ["src/main.ts", "src/cli.ts", "src/contracts/errorSchemas.ts"], + "entry": [ + "src/main.ts", + "src/cli.ts", + "src/contracts/errorSchemas.ts", + "tests/processOwnershipRunner.ts" + ], "project": ["src/**/*.ts", "tests/**/*.ts", "scripts/**/*.mjs"], "vitepress": { "entry": ["docs/.vitepress/config.ts"] diff --git a/tests/boundary/mcp/androidAnalysisMcp.test.ts b/tests/boundary/process/androidAnalysisMcp.test.ts similarity index 100% rename from tests/boundary/mcp/androidAnalysisMcp.test.ts rename to tests/boundary/process/androidAnalysisMcp.test.ts diff --git a/tests/boundary/android/jadxIntegration.test.ts b/tests/boundary/process/jadxIntegration.test.ts similarity index 100% rename from tests/boundary/android/jadxIntegration.test.ts rename to tests/boundary/process/jadxIntegration.test.ts diff --git a/tests/processOwnershipRunner.ts b/tests/processOwnershipRunner.ts new file mode 100644 index 000000000..108c76295 --- /dev/null +++ b/tests/processOwnershipRunner.ts @@ -0,0 +1,18 @@ +import { TestRunner } from "vitest"; + +import type { ProcessOwnershipHost } from "../src/process/ProcessOwnership.js"; + +/** Retire each isolated graph's native cache when its test worker stops. */ +export default class ProcessOwnershipRunner extends TestRunner { + readonly #registeredHosts = new WeakSet(); + + async onBeforeRunFiles(): Promise { + const { systemProcessOwnershipHost } = + await import("../src/process/ProcessOwnershipObservation.js"); + if (this.#registeredHosts.has(systemProcessOwnershipHost)) return; + if (this.onCleanupWorkerContext === undefined) + throw new Error("The test pool does not support worker resource cleanup"); + this.#registeredHosts.add(systemProcessOwnershipHost); + this.onCleanupWorkerContext(() => systemProcessOwnershipHost.close?.()); + } +} diff --git a/vitest.config.ts b/vitest.config.ts index 0ab5bbc44..8c629580d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -134,6 +134,7 @@ export default defineConfig({ projects, retry: 0, reporters: ["default"], + runner: "./tests/processOwnershipRunner.ts", // Boundary projects may compete with TypeScript, docs, and package checks // under Turbo. Keep the deadline bounded while avoiding false failures from // host-level CPU and filesystem contention.