perf(test): speed up setup and config path resolution

This commit is contained in:
Peter Steinberger
2026-03-02 18:41:19 +00:00
parent 842087319b
commit bcb1eb2f03
4 changed files with 27 additions and 18 deletions

View File

@@ -9,15 +9,11 @@ import {
import { fetchTelegramChatId } from "../channels/telegram/api.js"; import { fetchTelegramChatId } from "../channels/telegram/api.js";
import { formatCliCommand } from "../cli/command-format.js"; import { formatCliCommand } from "../cli/command-format.js";
import type { OpenClawConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/config.js";
import { import { CONFIG_PATH, migrateLegacyConfig, readConfigFileSnapshot } from "../config/config.js";
OpenClawSchema,
CONFIG_PATH,
migrateLegacyConfig,
readConfigFileSnapshot,
} from "../config/config.js";
import { collectProviderDangerousNameMatchingScopes } from "../config/dangerous-name-matching.js"; import { collectProviderDangerousNameMatchingScopes } from "../config/dangerous-name-matching.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js"; import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
import { parseToolsBySenderTypedKey } from "../config/types.tools.js"; import { parseToolsBySenderTypedKey } from "../config/types.tools.js";
import { OpenClawSchema } from "../config/zod-schema.js";
import { resolveCommandResolutionFromArgv } from "../infra/exec-command-resolution.js"; import { resolveCommandResolutionFromArgv } from "../infra/exec-command-resolution.js";
import { import {
listInterpreterLikeSafeBins, listInterpreterLikeSafeBins,

View File

@@ -21,4 +21,3 @@ export {
validateConfigObjectRawWithPlugins, validateConfigObjectRawWithPlugins,
validateConfigObjectWithPlugins, validateConfigObjectWithPlugins,
} from "./validation.js"; } from "./validation.js";
export { OpenClawSchema } from "./zod-schema.js";

View File

@@ -67,6 +67,9 @@ export function resolveStateDir(
return resolveUserPath(override, env, effectiveHomedir); return resolveUserPath(override, env, effectiveHomedir);
} }
const newDir = newStateDir(effectiveHomedir); const newDir = newStateDir(effectiveHomedir);
if (env.OPENCLAW_TEST_FAST === "1") {
return newDir;
}
const legacyDirs = legacyStateDirs(effectiveHomedir); const legacyDirs = legacyStateDirs(effectiveHomedir);
const hasNew = fs.existsSync(newDir); const hasNew = fs.existsSync(newDir);
if (hasNew) { if (hasNew) {
@@ -131,6 +134,9 @@ export function resolveConfigPathCandidate(
env: NodeJS.ProcessEnv = process.env, env: NodeJS.ProcessEnv = process.env,
homedir: () => string = envHomedir(env), homedir: () => string = envHomedir(env),
): string { ): string {
if (env.OPENCLAW_TEST_FAST === "1") {
return resolveCanonicalConfigPath(env, resolveStateDir(env, homedir));
}
const candidates = resolveDefaultConfigCandidates(env, homedir); const candidates = resolveDefaultConfigCandidates(env, homedir);
const existing = candidates.find((candidate) => { const existing = candidates.find((candidate) => {
try { try {
@@ -157,6 +163,9 @@ export function resolveConfigPath(
if (override) { if (override) {
return resolveUserPath(override, env, homedir); return resolveUserPath(override, env, homedir);
} }
if (env.OPENCLAW_TEST_FAST === "1") {
return path.join(stateDir, CONFIG_FILENAME);
}
const stateOverride = env.OPENCLAW_STATE_DIR?.trim(); const stateOverride = env.OPENCLAW_STATE_DIR?.trim();
const candidates = [ const candidates = [
path.join(stateDir, CONFIG_FILENAME), path.join(stateDir, CONFIG_FILENAME),

View File

@@ -1,4 +1,4 @@
import { afterAll, afterEach, beforeEach, vi } from "vitest"; import { afterAll, afterEach, beforeAll, vi } from "vitest";
// Ensure Vitest environment is properly set // Ensure Vitest environment is properly set
process.env.VITEST = "true"; process.env.VITEST = "true";
@@ -25,12 +25,15 @@ import { withIsolatedTestHome } from "./test-env.js";
const testEnv = withIsolatedTestHome(); const testEnv = withIsolatedTestHome();
afterAll(() => testEnv.cleanup()); afterAll(() => testEnv.cleanup());
const [{ installProcessWarningFilter }, { setActivePluginRegistry }, { createTestRegistry }] = const [
await Promise.all([ { installProcessWarningFilter },
import("../src/infra/warning-filter.js"), { getActivePluginRegistry, setActivePluginRegistry },
import("../src/plugins/runtime.js"), { createTestRegistry },
import("../src/test-utils/channel-plugins.js"), ] = await Promise.all([
]); import("../src/infra/warning-filter.js"),
import("../src/plugins/runtime.js"),
import("../src/test-utils/channel-plugins.js"),
]);
installProcessWarningFilter(); installProcessWarningFilter();
@@ -172,16 +175,18 @@ const createDefaultRegistry = () =>
}, },
]); ]);
// Creating a fresh registry before every single test was measurable overhead. // Creating a fresh registry before every test is measurable overhead.
// The registry is treated as immutable by production code; tests that need a // The registry is immutable by default; tests that override it are restored in afterEach.
// custom registry set it explicitly.
const DEFAULT_PLUGIN_REGISTRY = createDefaultRegistry(); const DEFAULT_PLUGIN_REGISTRY = createDefaultRegistry();
beforeEach(() => { beforeAll(() => {
setActivePluginRegistry(DEFAULT_PLUGIN_REGISTRY); setActivePluginRegistry(DEFAULT_PLUGIN_REGISTRY);
}); });
afterEach(() => { afterEach(() => {
if (getActivePluginRegistry() !== DEFAULT_PLUGIN_REGISTRY) {
setActivePluginRegistry(DEFAULT_PLUGIN_REGISTRY);
}
// Guard against leaked fake timers across test files/workers. // Guard against leaked fake timers across test files/workers.
if (vi.isFakeTimers()) { if (vi.isFakeTimers()) {
vi.useRealTimers(); vi.useRealTimers();