perf(test): trim runtime lookups and add changed bench

This commit is contained in:
Peter Steinberger
2026-04-06 16:48:32 +01:00
parent 8477f1841a
commit 8a33a8d607
11 changed files with 430 additions and 63 deletions

View File

@@ -88,6 +88,8 @@ Think of the suites as “increasing realism” (and increasing flakiness/cost):
- Perf-debug note:
- `pnpm test:perf:imports` enables Vitest import-duration reporting plus import-breakdown output.
- `pnpm test:perf:imports:changed` scopes the same profiling view to files changed since `origin/main`.
- `pnpm test:perf:changed:bench -- --ref <git-ref>` compares routed `test:changed` against the native root-project path for that committed diff and prints wall time plus macOS max RSS.
- `pnpm test:perf:changed:bench -- --worktree` benchmarks the current dirty tree by routing the changed file list through `scripts/test-projects.mjs` and the root Vitest config.
- `pnpm test:perf:profile:main` writes a main-thread CPU profile for Vitest/Vite startup and transform overhead.
- `pnpm test:perf:profile:runner` writes runner CPU+heap profiles for the unit suite with file parallelism disabled.

View File

@@ -22,6 +22,8 @@ title: "Tests"
- `pnpm test:extensions`: runs extension/plugin suites.
- `pnpm test:perf:imports`: enables Vitest import-duration + import-breakdown reporting, while still using scoped lane routing for explicit file/directory targets.
- `pnpm test:perf:imports:changed`: same import profiling, but only for files changed since `origin/main`.
- `pnpm test:perf:changed:bench -- --ref <git-ref>` benchmarks the routed changed-mode path against the native root-project run for the same committed git diff.
- `pnpm test:perf:changed:bench -- --worktree` benchmarks the current worktree change set without committing first.
- `pnpm test:perf:profile:main`: writes a CPU profile for the Vitest main thread (`.artifacts/vitest-main-profile`).
- `pnpm test:perf:profile:runner`: writes CPU + heap profiles for the unit runner (`.artifacts/vitest-runner-profile`).
- Gateway integration: opt-in via `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` or `pnpm test:gateway`.

View File

@@ -1176,6 +1176,7 @@
"test:parallels:npm-update": "bash scripts/e2e/parallels-npm-update-smoke.sh",
"test:parallels:windows": "bash scripts/e2e/parallels-windows-smoke.sh",
"test:perf:budget": "node scripts/test-perf-budget.mjs",
"test:perf:changed:bench": "node scripts/bench-test-changed.mjs",
"test:perf:hotspots": "node scripts/test-hotspots.mjs",
"test:perf:imports": "OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 node scripts/test-projects.mjs",
"test:perf:imports:changed": "OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 node scripts/test-projects.mjs --changed origin/main",

View File

@@ -0,0 +1,187 @@
import { spawnSync } from "node:child_process";
import path from "node:path";
import { floatFlag, parseFlagArgs, stringFlag } from "./lib/arg-utils.mjs";
import { formatMs } from "./lib/vitest-report-cli-utils.mjs";
function parseArgs(argv) {
const args = parseFlagArgs(
argv,
{
cwd: process.cwd(),
ref: "origin/main",
rss: process.platform === "darwin",
mode: "ref",
},
[
stringFlag("--cwd", "cwd"),
stringFlag("--ref", "ref"),
floatFlag("--max-workers", "maxWorkers", { min: 1 }),
],
{
allowUnknownOptions: true,
onUnhandledArg(arg, target) {
if (arg === "--no-rss") {
target.rss = false;
return "handled";
}
if (arg === "--worktree") {
target.mode = "worktree";
return "handled";
}
return undefined;
},
},
);
return {
cwd: path.resolve(args.cwd),
mode: args.mode,
ref: args.ref,
rss: args.rss,
...(typeof args.maxWorkers === "number" ? { maxWorkers: Math.trunc(args.maxWorkers) } : {}),
};
}
function quoteArg(arg) {
return /[^A-Za-z0-9_./:-]/.test(arg) ? JSON.stringify(arg) : arg;
}
function runGitList(args, cwd) {
const result = spawnSync("git", args, {
cwd,
encoding: "utf8",
});
if (result.status !== 0) {
throw new Error(result.stderr || result.stdout || `git ${args.join(" ")} failed`);
}
return result.stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0);
}
function listChangedPaths(opts) {
if (opts.mode === "worktree") {
return [
...new Set([
...runGitList(["diff", "--name-only", "--relative", "HEAD", "--"], opts.cwd),
...runGitList(["ls-files", "--others", "--exclude-standard"], opts.cwd),
]),
].toSorted((left, right) => left.localeCompare(right));
}
return runGitList(["diff", "--name-only", `${opts.ref}...HEAD`], opts.cwd);
}
function parseMaxRssKb(output) {
const match = output.match(/(\d+)\s+maximum resident set size/u);
return match ? Number.parseInt(match[1], 10) : null;
}
function formatRss(valueKb) {
if (valueKb === null) {
return "n/a";
}
return `${(valueKb / 1024).toFixed(1)}MB`;
}
function runBenchCommand(params) {
const env = { ...process.env };
if (typeof params.maxWorkers === "number") {
env.OPENCLAW_VITEST_MAX_WORKERS = String(params.maxWorkers);
}
const startedAt = process.hrtime.bigint();
const commandArgs = params.rss ? ["-l", ...params.command] : params.command;
const result = spawnSync(
params.rss ? "/usr/bin/time" : commandArgs[0],
params.rss ? commandArgs : commandArgs.slice(1),
{
cwd: params.cwd,
env,
encoding: "utf8",
maxBuffer: 1024 * 1024 * 32,
},
);
const elapsedMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000;
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`;
return {
elapsedMs,
maxRssKb: params.rss ? parseMaxRssKb(output) : null,
status: result.status ?? 1,
output,
};
}
function printRunSummary(label, result) {
console.log(
`${label.padEnd(8, " ")} wall=${formatMs(result.elapsedMs).padStart(9, " ")} rss=${formatRss(
result.maxRssKb,
).padStart(9, " ")}`,
);
}
const opts = parseArgs(process.argv.slice(2));
const changedPaths = listChangedPaths(opts);
if (changedPaths.length === 0) {
console.log(
opts.mode === "worktree"
? "[bench-test-changed] no changed paths in worktree"
: `[bench-test-changed] no changed paths for ${opts.ref}...HEAD`,
);
process.exit(0);
}
console.log(
opts.mode === "worktree"
? "[bench-test-changed] mode=worktree"
: `[bench-test-changed] ref=${opts.ref}`,
);
console.log("[bench-test-changed] changed paths:");
for (const changedPath of changedPaths) {
console.log(`- ${changedPath}`);
}
const routedCommand =
opts.mode === "worktree"
? [process.execPath, "scripts/test-projects.mjs", ...changedPaths]
: [process.execPath, "scripts/test-projects.mjs", "--changed", opts.ref];
const rootCommand = [
process.execPath,
"scripts/run-vitest.mjs",
"run",
"--config",
"vitest.config.ts",
...changedPaths,
];
console.log(`[bench-test-changed] routed: ${routedCommand.map(quoteArg).join(" ")}`);
const routed = runBenchCommand({
command: routedCommand,
cwd: opts.cwd,
rss: opts.rss,
...(typeof opts.maxWorkers === "number" ? { maxWorkers: opts.maxWorkers } : {}),
});
if (routed.status !== 0) {
process.stderr.write(routed.output);
process.exit(routed.status);
}
console.log(`[bench-test-changed] root: ${rootCommand.map(quoteArg).join(" ")}`);
const root = runBenchCommand({
command: rootCommand,
cwd: opts.cwd,
rss: opts.rss,
...(typeof opts.maxWorkers === "number" ? { maxWorkers: opts.maxWorkers } : {}),
});
if (root.status !== 0) {
process.stderr.write(root.output);
process.exit(root.status);
}
printRunSummary("routed", routed);
printRunSummary("root", root);
console.log(
`[bench-test-changed] delta wall=${formatMs(root.elapsedMs - routed.elapsedMs)} rss=${
routed.maxRssKb !== null && root.maxRssKb !== null
? formatRss(root.maxRssKb - routed.maxRssKb)
: "n/a"
}`,
);

View File

@@ -17,6 +17,9 @@ describe("command secret targets module import", () => {
const mod = await import("./command-secret-targets.js");
expect(listSecretTargetRegistryEntries).not.toHaveBeenCalled();
expect(mod.getModelsCommandSecretTargetIds().has("models.providers.*.apiKey")).toBe(true);
expect(mod.getQrRemoteCommandSecretTargetIds().has("gateway.remote.token")).toBe(true);
expect(listSecretTargetRegistryEntries).not.toHaveBeenCalled();
expect(() => mod.getChannelsCommandSecretTargetIds()).toThrow("registry touched too early");
expect(listSecretTargetRegistryEntries).toHaveBeenCalledTimes(1);

View File

@@ -53,11 +53,25 @@ vi.mock("../secrets/target-registry.js", () => ({
import {
getAgentRuntimeCommandSecretTargetIds,
getModelsCommandSecretTargetIds,
getQrRemoteCommandSecretTargetIds,
getScopedChannelsCommandSecretTargets,
getSecurityAuditCommandSecretTargetIds,
} from "./command-secret-targets.js";
describe("command secret target ids", () => {
it("keeps static qr remote targets out of the registry path", () => {
const ids = getQrRemoteCommandSecretTargetIds();
expect(ids).toEqual(new Set(["gateway.remote.token", "gateway.remote.password"]));
});
it("keeps static model targets out of the registry path", () => {
const ids = getModelsCommandSecretTargetIds();
expect(ids.has("models.providers.*.apiKey")).toBe(true);
expect(ids.has("models.providers.*.request.tls.key")).toBe(true);
expect(ids.has("channels.discord.token")).toBe(false);
});
it("includes memorySearch remote targets for agent runtime commands", () => {
const ids = getAgentRuntimeCommandSecretTargetIds();
expect(ids.has("agents.defaults.memorySearch.remote.apiKey")).toBe(true);

View File

@@ -5,6 +5,50 @@ import {
listSecretTargetRegistryEntries,
} from "../secrets/target-registry.js";
const STATIC_QR_REMOTE_TARGET_IDS = ["gateway.remote.token", "gateway.remote.password"] as const;
const STATIC_MODEL_TARGET_IDS = [
"models.providers.*.apiKey",
"models.providers.*.headers.*",
"models.providers.*.request.headers.*",
"models.providers.*.request.auth.token",
"models.providers.*.request.auth.value",
"models.providers.*.request.proxy.tls.ca",
"models.providers.*.request.proxy.tls.cert",
"models.providers.*.request.proxy.tls.key",
"models.providers.*.request.proxy.tls.passphrase",
"models.providers.*.request.tls.ca",
"models.providers.*.request.tls.cert",
"models.providers.*.request.tls.key",
"models.providers.*.request.tls.passphrase",
] as const;
const STATIC_AGENT_RUNTIME_TARGET_IDS = [
...STATIC_MODEL_TARGET_IDS,
"agents.defaults.memorySearch.remote.apiKey",
"agents.list[].memorySearch.remote.apiKey",
"messages.tts.providers.*.apiKey",
"skills.entries.*.apiKey",
"tools.web.search.apiKey",
"plugins.entries.brave.config.webSearch.apiKey",
"plugins.entries.google.config.webSearch.apiKey",
"plugins.entries.xai.config.webSearch.apiKey",
"plugins.entries.moonshot.config.webSearch.apiKey",
"plugins.entries.perplexity.config.webSearch.apiKey",
"plugins.entries.firecrawl.config.webSearch.apiKey",
"plugins.entries.firecrawl.config.webFetch.apiKey",
"plugins.entries.tavily.config.webSearch.apiKey",
"plugins.entries.minimax.config.webSearch.apiKey",
] as const;
const STATIC_STATUS_TARGET_IDS = [
"agents.defaults.memorySearch.remote.apiKey",
"agents.list[].memorySearch.remote.apiKey",
] as const;
const STATIC_SECURITY_AUDIT_TARGET_IDS = [
"gateway.auth.token",
"gateway.auth.password",
"gateway.remote.token",
"gateway.remote.password",
] as const;
function idsByPrefix(prefixes: readonly string[]): string[] {
return listSecretTargetRegistryEntries()
.map((entry) => entry.id)
@@ -12,48 +56,28 @@ function idsByPrefix(prefixes: readonly string[]): string[] {
.toSorted();
}
function idsByPredicate(predicate: (id: string) => boolean): string[] {
return listSecretTargetRegistryEntries()
.map((entry) => entry.id)
.filter(predicate)
.toSorted();
}
type CommandSecretTargets = {
qrRemote: string[];
channels: string[];
models: string[];
agentRuntime: string[];
status: string[];
securityAudit: string[];
};
let cachedCommandSecretTargets: CommandSecretTargets | undefined;
let cachedChannelSecretTargetIds: string[] | undefined;
function getChannelSecretTargetIds(): string[] {
cachedChannelSecretTargetIds ??= idsByPrefix(["channels."]);
return cachedChannelSecretTargetIds;
}
function buildCommandSecretTargets(): CommandSecretTargets {
const webPluginSecretTargets = idsByPredicate((id) =>
/^plugins\.entries\.[^.]+\.config\.(webSearch|webFetch)\.apiKey$/.test(id),
);
const channelTargetIds = getChannelSecretTargetIds();
return {
qrRemote: ["gateway.remote.token", "gateway.remote.password"],
channels: idsByPrefix(["channels."]),
models: idsByPrefix(["models.providers."]),
agentRuntime: idsByPrefix([
"channels.",
"models.providers.",
"agents.defaults.memorySearch.remote.",
"agents.list[].memorySearch.remote.",
"skills.entries.",
"messages.tts.",
"tools.web.search",
]).concat(webPluginSecretTargets),
status: idsByPrefix([
"channels.",
"agents.defaults.memorySearch.remote.",
"agents.list[].memorySearch.remote.",
]),
securityAudit: idsByPrefix(["channels.", "gateway.auth.", "gateway.remote."]),
channels: channelTargetIds,
agentRuntime: [...STATIC_AGENT_RUNTIME_TARGET_IDS, ...channelTargetIds],
status: [...STATIC_STATUS_TARGET_IDS, ...channelTargetIds],
securityAudit: [...STATIC_SECURITY_AUDIT_TARGET_IDS, ...channelTargetIds],
};
}
@@ -127,7 +151,7 @@ export function getScopedChannelsCommandSecretTargets(params: {
}
export function getQrRemoteCommandSecretTargetIds(): Set<string> {
return toTargetIdSet(getCommandSecretTargets().qrRemote);
return toTargetIdSet(STATIC_QR_REMOTE_TARGET_IDS);
}
export function getChannelsCommandSecretTargetIds(): Set<string> {
@@ -135,7 +159,7 @@ export function getChannelsCommandSecretTargetIds(): Set<string> {
}
export function getModelsCommandSecretTargetIds(): Set<string> {
return toTargetIdSet(getCommandSecretTargets().models);
return toTargetIdSet(STATIC_MODEL_TARGET_IDS);
}
export function getAgentRuntimeCommandSecretTargetIds(): Set<string> {

View File

@@ -9,6 +9,7 @@ import { getRuntimeConfigSnapshot } from "../config/runtime-snapshot.js";
import type { OpenClawConfig } from "../config/types.js";
import { openBoundaryFileSync } from "../infra/boundary-file-read.js";
import { resolveBundledPluginsDir } from "../plugins/bundled-dir.js";
import { listBundledPluginMetadata } from "../plugins/bundled-plugin-metadata.js";
import {
createPluginActivationSource,
normalizePluginsConfig,
@@ -42,6 +43,7 @@ const EMPTY_FACADE_BOUNDARY_CONFIG: OpenClawConfig = {};
const jitiLoaders = new Map<string, ReturnType<typeof createJiti>>();
const loadedFacadeModules = new Map<string, unknown>();
const loadedFacadePluginIds = new Set<string>();
const OPENCLAW_SOURCE_EXTENSIONS_ROOT = path.resolve(OPENCLAW_PACKAGE_ROOT, "extensions");
let cachedBoundaryRawConfig: OpenClawConfig | undefined;
let cachedBoundaryResolvedConfig:
| {
@@ -52,6 +54,40 @@ let cachedBoundaryResolvedConfig:
autoEnabledReasons: Record<string, string[]>;
}
| undefined;
let cachedManifestRegistry: readonly PluginManifestRecord[] | undefined;
const cachedFacadeModuleLocationsByKey = new Map<
string,
{
modulePath: string;
boundaryRoot: string;
} | null
>();
const cachedFacadeManifestRecordsByKey = new Map<string, FacadePluginManifestLike | null>();
const cachedFacadePublicSurfaceAccessByKey = new Map<
string,
{ allowed: boolean; pluginId?: string; reason?: string }
>();
type FacadePluginManifestLike = Pick<
PluginManifestRecord,
"id" | "origin" | "enabledByDefault" | "rootDir" | "channels"
>;
function createFacadeResolutionKey(params: { dirName: string; artifactBasename: string }): string {
const bundledPluginsDir = resolveBundledPluginsDir();
return `${params.dirName}::${params.artifactBasename}::${bundledPluginsDir ? path.resolve(bundledPluginsDir) : "<default>"}`;
}
function getFacadeManifestRegistry(): readonly PluginManifestRecord[] {
if (cachedManifestRegistry) {
return cachedManifestRegistry;
}
cachedManifestRegistry = loadPluginManifestRegistry({
config: getFacadeBoundaryResolvedConfig().config,
cache: true,
}).plugins;
return cachedManifestRegistry;
}
function resolveSourceFirstPublicSurfacePath(params: {
bundledPluginsDir?: string;
@@ -73,8 +109,7 @@ function resolveRegistryPluginModuleLocation(params: {
dirName: string;
artifactBasename: string;
}): { modulePath: string; boundaryRoot: string } | null {
const { config } = getFacadeBoundaryResolvedConfig();
const registry = loadPluginManifestRegistry({ config, cache: true }).plugins;
const registry = getFacadeManifestRegistry();
const tiers: Array<(plugin: (typeof registry)[number]) => boolean> = [
(plugin) => plugin.id === params.dirName,
(plugin) => path.basename(plugin.rootDir) === params.dirName,
@@ -100,7 +135,7 @@ function resolveRegistryPluginModuleLocation(params: {
return null;
}
function resolveFacadeModuleLocation(params: {
function resolveFacadeModuleLocationUncached(params: {
dirName: string;
artifactBasename: string;
}): { modulePath: string; boundaryRoot: string } | null {
@@ -148,6 +183,19 @@ function resolveFacadeModuleLocation(params: {
return resolveRegistryPluginModuleLocation(params);
}
function resolveFacadeModuleLocation(params: {
dirName: string;
artifactBasename: string;
}): { modulePath: string; boundaryRoot: string } | null {
const key = createFacadeResolutionKey(params);
if (cachedFacadeModuleLocationsByKey.has(key)) {
return cachedFacadeModuleLocationsByKey.get(key) ?? null;
}
const resolved = resolveFacadeModuleLocationUncached(params);
cachedFacadeModuleLocationsByKey.set(key, resolved);
return resolved;
}
function getJiti(modulePath: string) {
const tryNative =
shouldPreferNativeJiti(modulePath) || modulePath.includes(`${path.sep}dist${path.sep}`);
@@ -211,36 +259,80 @@ function getFacadeBoundaryResolvedConfig() {
return resolved;
}
function resolveBundledMetadataManifestRecord(params: {
dirName: string;
artifactBasename: string;
}): FacadePluginManifestLike | null {
if (resolveBundledPluginsDir()) {
return null;
}
const location = resolveFacadeModuleLocation(params);
if (!location) {
return null;
}
if (!location.modulePath.startsWith(`${OPENCLAW_SOURCE_EXTENSIONS_ROOT}${path.sep}`)) {
return null;
}
const relativeToExtensions = path.relative(OPENCLAW_SOURCE_EXTENSIONS_ROOT, location.modulePath);
const resolvedDirName = relativeToExtensions.split(path.sep)[0];
if (!resolvedDirName) {
return null;
}
const metadata = listBundledPluginMetadata({
includeChannelConfigs: false,
includeSyntheticChannelConfigs: false,
}).find(
(entry) =>
entry.dirName === resolvedDirName ||
entry.manifest.id === params.dirName ||
entry.manifest.channels?.includes(params.dirName),
);
if (!metadata) {
return null;
}
return {
id: metadata.manifest.id,
origin: "bundled",
enabledByDefault: metadata.manifest.enabledByDefault,
rootDir: path.resolve(OPENCLAW_SOURCE_EXTENSIONS_ROOT, metadata.dirName),
channels: [...(metadata.manifest.channels ?? [])],
};
}
function resolveBundledPluginManifestRecord(params: {
dirName: string;
artifactBasename: string;
}): PluginManifestRecord | null {
const { config } = getFacadeBoundaryResolvedConfig();
const registry = loadPluginManifestRegistry({
config,
cache: true,
}).plugins;
const location = resolveFacadeModuleLocation(params);
if (location) {
const normalizedModulePath = path.resolve(location.modulePath);
const matchedRecord = registry.find((plugin) => {
const normalizedRootDir = path.resolve(plugin.rootDir);
return (
normalizedModulePath === normalizedRootDir ||
normalizedModulePath.startsWith(`${normalizedRootDir}${path.sep}`)
);
});
if (matchedRecord) {
return matchedRecord;
}
}): FacadePluginManifestLike | null {
const key = createFacadeResolutionKey(params);
if (cachedFacadeManifestRecordsByKey.has(key)) {
return cachedFacadeManifestRecordsByKey.get(key) ?? null;
}
return (
const metadataRecord = resolveBundledMetadataManifestRecord(params);
if (metadataRecord) {
cachedFacadeManifestRecordsByKey.set(key, metadataRecord);
return metadataRecord;
}
const registry = getFacadeManifestRegistry();
const location = resolveFacadeModuleLocation(params);
const resolved =
(location
? registry.find((plugin) => {
const normalizedRootDir = path.resolve(plugin.rootDir);
const normalizedModulePath = path.resolve(location.modulePath);
return (
normalizedModulePath === normalizedRootDir ||
normalizedModulePath.startsWith(`${normalizedRootDir}${path.sep}`)
);
})
: null) ??
registry.find((plugin) => plugin.id === params.dirName) ??
registry.find((plugin) => path.basename(plugin.rootDir) === params.dirName) ??
registry.find((plugin) => plugin.channels.includes(params.dirName)) ??
null
);
null;
cachedFacadeManifestRecordsByKey.set(key, resolved);
return resolved;
}
function resolveTrackedFacadePluginId(params: {
@@ -254,22 +346,32 @@ function resolveBundledPluginPublicSurfaceAccess(params: {
dirName: string;
artifactBasename: string;
}): { allowed: boolean; pluginId?: string; reason?: string } {
const key = createFacadeResolutionKey(params);
const cached = cachedFacadePublicSurfaceAccessByKey.get(key);
if (cached) {
return cached;
}
if (
params.artifactBasename === "runtime-api.js" &&
ALWAYS_ALLOWED_RUNTIME_DIR_NAMES.has(params.dirName)
) {
return {
const resolved = {
allowed: true,
pluginId: params.dirName,
};
cachedFacadePublicSurfaceAccessByKey.set(key, resolved);
return resolved;
}
const manifestRecord = resolveBundledPluginManifestRecord(params);
if (!manifestRecord) {
return {
const resolved = {
allowed: false,
reason: `no bundled plugin manifest found for ${params.dirName}`,
};
cachedFacadePublicSurfaceAccessByKey.set(key, resolved);
return resolved;
}
const { config, normalizedPluginsConfig, activationSource, autoEnabledReasons } =
getFacadeBoundaryResolvedConfig();
@@ -283,17 +385,21 @@ function resolveBundledPluginPublicSurfaceAccess(params: {
autoEnabledReason: autoEnabledReasons[manifestRecord.id]?.[0],
});
if (activationState.enabled) {
return {
const resolved = {
allowed: true,
pluginId: manifestRecord.id,
};
cachedFacadePublicSurfaceAccessByKey.set(key, resolved);
return resolved;
}
return {
const resolved = {
allowed: false,
pluginId: manifestRecord.id,
reason: activationState.reason ?? "plugin runtime is not activated",
};
cachedFacadePublicSurfaceAccessByKey.set(key, resolved);
return resolved;
}
function createLazyFacadeValueLoader<T>(load: () => T): () => T {
@@ -464,4 +570,8 @@ export function resetFacadeRuntimeStateForTest(): void {
jitiLoaders.clear();
cachedBoundaryRawConfig = undefined;
cachedBoundaryResolvedConfig = undefined;
cachedManifestRegistry = undefined;
cachedFacadeModuleLocationsByKey.clear();
cachedFacadeManifestRecordsByKey.clear();
cachedFacadePublicSurfaceAccessByKey.clear();
}

View File

@@ -112,13 +112,17 @@ describe("scripts/test-projects changed-target routing", () => {
it("routes changed commands source allowlist files to sibling light tests", () => {
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
"src/commands/status-overview-values.ts",
"src/commands/gateway-status/helpers.ts",
]);
expect(plans).toEqual([
{
config: "vitest.commands-light.config.ts",
forwardedArgs: [],
includePatterns: ["src/commands/status-overview-values.test.ts"],
includePatterns: [
"src/commands/status-overview-values.test.ts",
"src/commands/gateway-status/helpers.test.ts",
],
watchMode: false,
},
]);

View File

@@ -34,6 +34,10 @@ describe("light vitest path routing", () => {
expect(resolveCommandsLightIncludePattern("src/commands/text-format.test.ts")).toBe(
"src/commands/text-format.test.ts",
);
expect(isCommandsLightTarget("src/commands/gateway-status/helpers.ts")).toBe(true);
expect(resolveCommandsLightIncludePattern("src/commands/gateway-status/helpers.ts")).toBe(
"src/commands/gateway-status/helpers.test.ts",
);
});
it("keeps non-allowlisted commands files off the light lane", () => {

View File

@@ -11,10 +11,26 @@ const commandsLightEntries = [
source: "src/commands/doctor-gateway-auth-token.ts",
test: "src/commands/doctor-gateway-auth-token.test.ts",
},
{
source: "src/commands/gateway-status/helpers.ts",
test: "src/commands/gateway-status/helpers.test.ts",
},
{
source: "src/commands/sandbox-formatters.ts",
test: "src/commands/sandbox-formatters.test.ts",
},
{
source: "src/commands/status-json-command.ts",
test: "src/commands/status-json-command.test.ts",
},
{
source: "src/commands/status-json-payload.ts",
test: "src/commands/status-json-payload.test.ts",
},
{
source: "src/commands/status-json-runtime.ts",
test: "src/commands/status-json-runtime.test.ts",
},
{
source: "src/commands/status-overview-rows.ts",
test: "src/commands/status-overview-rows.test.ts",