Use the pinned Vitest parser for coverage and shard flags. Keep ordinary CLI workers at 384 MiB and covered workers at the tested 512 MiB with unchanged concurrency. Retain complete coverage and add actual-config regressions for false, provider-only and spaced-shard options. Validation: 27 focused cases; 16 covered cases with CLI preloaded; 5 docs checks; typecheck/lint; exact discovery of 1578 files. Measured covered control: 22.18s elapsed, 46.52s CPU, about 2.33 GiB sampled summed process-family RSS on macOS arm64. Full Linux CI pending. No runtime/device verification claimed. Fixes #4960
144 lines
4.6 KiB
TypeScript
144 lines
4.6 KiB
TypeScript
import { execFileSync } from "node:child_process";
|
|
import { readFile, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
BUILT_TEST_PROJECTS,
|
|
SOURCE_TEST_PROJECTS,
|
|
projectForTest,
|
|
} from "../../../scripts/lib/test-projects.mjs";
|
|
import {
|
|
developmentTestPlan,
|
|
parseDevelopmentTestRequest,
|
|
} from "../../../scripts/lib/development-tests.mjs";
|
|
|
|
import { execFileOutput } from "../../../src/process/ExecFileOutput.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
const repository = process.cwd();
|
|
|
|
describe("canonical test-project ownership", () => {
|
|
it("assigns every tracked test file exactly once to source or built", () => {
|
|
const files = execFileSync("git", ["ls-files", "*.test.ts"], {
|
|
cwd: repository,
|
|
encoding: "utf8",
|
|
})
|
|
.trim()
|
|
.split("\n")
|
|
.filter(Boolean);
|
|
const grouped = new Map<string, string[]>();
|
|
for (const file of files) {
|
|
const project = projectForTest(file);
|
|
grouped.set(project.group, [...(grouped.get(project.group) ?? []), file]);
|
|
}
|
|
|
|
expect(grouped.get("source")).not.toBeUndefined();
|
|
expect(grouped.get("built")).not.toBeUndefined();
|
|
expect(
|
|
(grouped.get("source")?.length ?? 0) +
|
|
(grouped.get("built")?.length ?? 0),
|
|
).toBe(files.length);
|
|
expect(
|
|
SOURCE_TEST_PROJECTS.reduce(
|
|
(count, project) => count + project.include.length,
|
|
0,
|
|
),
|
|
).toBeGreaterThan(0);
|
|
expect(
|
|
BUILT_TEST_PROJECTS.every((project) => project.group === "built"),
|
|
).toBe(true);
|
|
expect(() => projectForTest("tests/unowned/example.test.ts")).toThrow(
|
|
"No test project owns",
|
|
);
|
|
});
|
|
|
|
it("owns the Hopper real-provider conformance test as built and requires preparation", () => {
|
|
const testPath =
|
|
"tests/conformance/providers/hopper/realHopperSearch.test.ts";
|
|
expect(projectForTest(testPath)).toMatchObject({
|
|
name: "boundary",
|
|
group: "built",
|
|
});
|
|
expect(() => parseDevelopmentTestRequest("local", [testPath])).toThrow(
|
|
`Use test:focused for built test projects: ${testPath}`,
|
|
);
|
|
const request = parseDevelopmentTestRequest("focused", [testPath]);
|
|
expect(developmentTestPlan(request)).toMatchObject({ needsBuild: true });
|
|
});
|
|
|
|
it("uses canonical selectors in Vitest while retaining independent runner policy", async () => {
|
|
const config = await readFile(join(repository, "vitest.config.ts"), "utf8");
|
|
expect(config).toContain(
|
|
"[...SOURCE_TEST_PROJECTS, ...BUILT_TEST_PROJECTS]",
|
|
);
|
|
expect(config).toContain("PROJECT_POLICIES");
|
|
expect(config).not.toContain('"src/{contracts,domain}/**/*.test.ts"');
|
|
});
|
|
|
|
it.each([
|
|
{ flags: [], heap: 384, timeout: 30_000, lines: 68 },
|
|
{ flags: ["--coverage"], heap: 512, timeout: 60_000, lines: 68 },
|
|
{ flags: ["--coverage.enabled"], heap: 512, timeout: 60_000, lines: 68 },
|
|
{ flags: ["--coverage=false"], heap: 384, timeout: 30_000, lines: 68 },
|
|
{
|
|
flags: ["--coverage.enabled=false"],
|
|
heap: 384,
|
|
timeout: 30_000,
|
|
lines: 68,
|
|
},
|
|
{
|
|
flags: ["--coverage.provider=v8"],
|
|
heap: 384,
|
|
timeout: 30_000,
|
|
lines: 68,
|
|
},
|
|
{
|
|
flags: ["--coverage.enabled", "--shard", "1/6"],
|
|
heap: 512,
|
|
timeout: 60_000,
|
|
lines: 0,
|
|
},
|
|
{
|
|
flags: ["--coverage.enabled=false", "--shard=1/6"],
|
|
heap: 384,
|
|
timeout: 30_000,
|
|
lines: 0,
|
|
},
|
|
])(
|
|
"resolves worker resources from actual CLI options: $flags",
|
|
async ({ flags, heap, timeout, lines }) => {
|
|
const root = await createTestTempDirectory("rea-vitest-worker-policy-");
|
|
const script = join(root, "worker-policy.mjs");
|
|
await writeFile(
|
|
script,
|
|
`
|
|
import config from ${JSON.stringify(pathToFileURL(join(repository, "vitest.config.ts")).href)};
|
|
const project = config.test.projects.find(project => project.test.name === 'cli-boundary');
|
|
console.log(JSON.stringify({
|
|
execArgv: project.test.execArgv,
|
|
timeout: config.test.testTimeout,
|
|
lines: config.test.coverage.thresholds.lines,
|
|
}));
|
|
`,
|
|
);
|
|
const result = await execFileOutput(
|
|
process.execPath,
|
|
["--import", "tsx", script, ...flags],
|
|
{
|
|
cwd: repository,
|
|
timeout: 10_000,
|
|
maxBuffer: 64 * 1024,
|
|
stopSignal: "SIGTERM",
|
|
},
|
|
);
|
|
expect(JSON.parse(result.stdout)).toEqual({
|
|
execArgv: [`--max-old-space-size=${String(heap)}`],
|
|
timeout,
|
|
lines,
|
|
});
|
|
},
|
|
);
|
|
});
|