From a0784c0d2cb70c48ecfeb0be23c6d68de5ee5be1 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Fri, 9 Oct 2026 03:49:31 +0800 Subject: [PATCH] test(process): retire native caches at worker teardown --- docs/testing.md | 7 ++++++- knip.json | 7 ++++++- .../androidAnalysisMcp.test.ts | 0 .../jadxIntegration.test.ts | 0 tests/processOwnershipRunner.ts | 18 ++++++++++++++++++ vitest.config.ts | 1 + 6 files changed, 31 insertions(+), 2 deletions(-) rename tests/boundary/{mcp => process}/androidAnalysisMcp.test.ts (100%) rename tests/boundary/{android => process}/jadxIntegration.test.ts (100%) create mode 100644 tests/processOwnershipRunner.ts 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.