test(cli): cache subprocess compilation within each worker

This commit is contained in:
morluto
2026-10-11 18:01:32 +08:00
parent e4027e4afc
commit 6bcfeb0e55
3 changed files with 97 additions and 7 deletions
+10 -3
View File
@@ -983,9 +983,16 @@ runner. Preserve simultaneous launches where concurrency is itself under test.
Build/documentation writers hold checkout-local output locks. Tests do not
hold a broad command lock; `check:pr` finishes tests before document validation.
Vitest and Node persistent compile caches are deliberately not enabled by
default. To evaluate repeated local runs, opt in for both cold and warm
measurements with an isolated cache:
Vitest's persistent compile cache remains disabled. The `cliTest` fixture shares
a temporary Node compile cache among its fresh CLI subprocesses. The worker
removes it after test-scoped processes finish. Explicit child environment
settings take precedence; children requesting `NODE_V8_COVERAGE` do not receive
the fixture cache. These subprocesses are outside aggregate Vitest coverage;
subprocess coverage attachment remains disabled. Cold-start import checks launch
independently without this fixture cache.
To evaluate persistent compile caching for repeated local runs, opt in for both
cold and warm measurements with an isolated cache:
```bash
NODE_COMPILE_CACHE=.cache/node-compile npm test
@@ -0,0 +1,57 @@
import { readdir } from "node:fs/promises";
import { expect } from "vitest";
import { PRODUCT_IDENTITY } from "../../../src/identity.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, createTestCli } from "../../support/cli/cliFixture.js";
cliTest(
"reuses an owned CLI compile cache and preserves a caller-selected cache",
async ({ cli, cliCompileCache }) => {
const cached = await cli.run({ arguments: ["--version"] });
expect(cached.exitCode).toBe(0);
expect(cached.stdout).toContain(PRODUCT_IDENTITY.packageVersion);
expect(await readdir(cliCompileCache)).not.toHaveLength(0);
const selected = await createTestTempDirectory("rea-cli-selected-cache-");
const overridden = await cli.run({
arguments: ["--version"],
environment: { NODE_COMPILE_CACHE: selected },
});
expect(overridden.exitCode).toBe(0);
expect(overridden.stdout).toBe(cached.stdout);
expect(await readdir(selected)).not.toHaveLength(0);
},
);
cliTest(
"collects requested child coverage without populating the fixture cache",
async ({ processes }) => {
const cache = await createTestTempDirectory("rea-cli-coverage-cache-");
const coverage = await createTestTempDirectory("rea-cli-child-coverage-");
const cli = createTestCli(processes, cache);
const result = await cli.run({
arguments: ["--version"],
environment: { NODE_V8_COVERAGE: coverage },
});
expect(result.exitCode).toBe(0);
expect(result.stdout).toContain(PRODUCT_IDENTITY.packageVersion);
expect(await readdir(cache)).toEqual([]);
expect(
(await readdir(coverage)).some((path) => path.endsWith(".json")),
).toBe(true);
},
);
cliTest("preserves a caller's cold CLI launch", async ({ processes }) => {
const cache = await createTestTempDirectory("rea-cli-disabled-cache-");
const cli = createTestCli(processes, cache);
const result = await cli.run({
arguments: ["--version"],
environment: { NODE_DISABLE_COMPILE_CACHE: "1" },
});
expect(result.exitCode).toBe(0);
expect(result.stdout).toContain(PRODUCT_IDENTITY.packageVersion);
expect(await readdir(cache)).toEqual([]);
});
+30 -4
View File
@@ -1,5 +1,9 @@
import { resolve } from "node:path";
import {
createTestWorkspace,
removeTestWorkspace,
} from "../workspace/workspaceFixture.js";
import {
processTest,
type ProcessResult,
@@ -36,7 +40,10 @@ const parseJson = (stdout: string): unknown | undefined => {
};
/** Create a compiled CLI driver backed by the supplied process registry. */
export const createTestCli = (processes: TestProcesses): TestCli => ({
export const createTestCli = (
processes: TestProcesses,
compileCache?: string,
): TestCli => ({
run: async ({
arguments: arguments_,
cwd,
@@ -51,6 +58,10 @@ export const createTestCli = (processes: TestProcesses): TestCli => ({
cwd: cwd ?? process.cwd(),
env: {
PATH: process.env.PATH ?? "",
...(compileCache === undefined ||
environment?.NODE_V8_COVERAGE !== undefined
? {}
: { NODE_COMPILE_CACHE: compileCache }),
...environment,
},
...(input === undefined ? {} : { input }),
@@ -62,8 +73,23 @@ export const createTestCli = (processes: TestProcesses): TestCli => ({
});
/** Vitest API extended with an owned process registry and compiled CLI driver. */
export const cliTest = processTest.extend<{ cli: TestCli }>({
cli: async ({ processes }, use) => {
await use(createTestCli(processes));
export const cliTest = processTest.extend<{
$test: { cli: TestCli };
$worker: { cliCompileCache: string };
}>({
cliCompileCache: [
// oxlint-disable-next-line no-empty-pattern -- Vitest parses fixture dependencies from object destructuring.
async ({}, use) => {
const workspace = await createTestWorkspace("rea-cli-compile-cache-");
try {
await use(workspace.path("node-compile"));
} finally {
await removeTestWorkspace(workspace.root);
}
},
{ scope: "worker" },
],
cli: async ({ processes, cliCompileCache }, use) => {
await use(createTestCli(processes, cliCompileCache));
},
});