Tests: preserve isolated home across non-isolated files

This commit is contained in:
Peter Steinberger
2026-04-07 07:43:53 +01:00
parent fab7b2a4de
commit 59318d9ff8
4 changed files with 47 additions and 8 deletions

View File

@@ -1,4 +1,5 @@
import fs from "node:fs";
import path from "node:path";
import { TestRunner, type RunnerTestSuite, vi } from "vitest";
type EvaluatedModuleNode = {
@@ -12,6 +13,15 @@ type EvaluatedModules = {
idToModuleMap: Map<string, EvaluatedModuleNode>;
};
const SHARED_TEST_SETUP = Symbol.for("openclaw.sharedTestSetup");
function getSharedTestHome(): string | undefined {
const globalState = globalThis as typeof globalThis & {
[SHARED_TEST_SETUP]?: { tempHome?: string };
};
return globalState[SHARED_TEST_SETUP]?.tempHome ?? process.env.OPENCLAW_TEST_HOME;
}
function resetEvaluatedModules(modules: EvaluatedModules, resetMocks: boolean) {
const skipPaths = [
/\/vitest\/dist\//,
@@ -31,9 +41,29 @@ function resetEvaluatedModules(modules: EvaluatedModules, resetMocks: boolean) {
});
}
function restoreSharedTestHomeAfterEnvUnstub(testHomeRaw: string | undefined): void {
const testHome = testHomeRaw?.trim();
if (!testHome) {
return;
}
process.env.HOME = testHome;
process.env.USERPROFILE = testHome;
process.env.OPENCLAW_TEST_HOME = testHome;
delete process.env.OPENCLAW_CONFIG_PATH;
delete process.env.OPENCLAW_STATE_DIR;
delete process.env.OPENCLAW_AGENT_DIR;
delete process.env.PI_CODING_AGENT_DIR;
process.env.XDG_CONFIG_HOME = path.join(testHome, ".config");
process.env.XDG_DATA_HOME = path.join(testHome, ".local", "share");
process.env.XDG_STATE_HOME = path.join(testHome, ".local", "state");
process.env.XDG_CACHE_HOME = path.join(testHome, ".cache");
}
export default class OpenClawNonIsolatedRunner extends TestRunner {
override onCollectStart(file: { filepath: string }) {
super.onCollectStart(file);
restoreSharedTestHomeAfterEnvUnstub(getSharedTestHome());
const orderLogPath = process.env.OPENCLAW_VITEST_FILE_ORDER_LOG?.trim();
if (orderLogPath) {
fs.appendFileSync(orderLogPath, `START ${file.filepath}\n`);
@@ -59,7 +89,9 @@ export default class OpenClawNonIsolatedRunner extends TestRunner {
}
vi.restoreAllMocks();
vi.unstubAllGlobals();
const testHome = getSharedTestHome();
vi.unstubAllEnvs();
restoreSharedTestHomeAfterEnvUnstub(testHome);
vi.clearAllMocks();
vi.resetModules();
this.moduleRunner?.mocker?.reset?.();

View File

@@ -15,11 +15,13 @@ import { clearSessionStoreCaches } from "../src/config/sessions/store-cache.js";
import { drainSessionStoreLockQueuesForTest } from "../src/config/sessions/store-lock-state.js";
import { drainFileLockStateForTest, resetFileLockStateForTest } from "../src/infra/file-lock.js";
import type { OutboundSendDeps } from "../src/infra/outbound/deliver.js";
import { clearPluginDiscoveryCache } from "../src/plugins/discovery.js";
import { clearPluginManifestRegistryCache } from "../src/plugins/manifest-registry.js";
import type { PluginRegistry } from "../src/plugins/registry.js";
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../src/plugins/runtime.js";
import { installSharedTestSetup } from "./setup.shared.js";
const testEnv = installSharedTestSetup();
installSharedTestSetup();
const WORKER_RUNTIME_STATE = Symbol.for("openclaw.testSetupRuntimeState");
type WorkerRuntimeState = {
@@ -332,6 +334,8 @@ afterEach(async () => {
resetContextWindowCacheForTest();
resetModelsJsonReadyCacheForTest();
resetSessionWriteLockStateForTest();
clearPluginDiscoveryCache();
clearPluginManifestRegistryCache();
installDefaultPluginRegistry();
});
@@ -339,5 +343,6 @@ afterAll(async () => {
clearSessionStoreCaches();
await drainFileLockStateForTest();
await drainSessionWriteLockStateForTest();
testEnv.cleanup();
clearPluginDiscoveryCache();
clearPluginManifestRegistryCache();
});

View File

@@ -11,6 +11,12 @@ vi.mock("@mariozechner/pi-ai", async () => {
};
});
vi.mock("@mariozechner/pi-ai/oauth", () => ({
getOAuthApiKey: () => undefined,
getOAuthProviders: () => [],
loginOpenAICodex: vi.fn(),
}));
vi.mock("@mariozechner/clipboard", () => ({
availableFormats: () => [],
getText: async () => "",
@@ -87,6 +93,7 @@ export function installSharedTestSetup(options?: SharedTestSetupOptions): {
delete globalState[SHARED_TEST_SETUP];
},
};
process.once("exit", handle.cleanup);
globalState[SHARED_TEST_SETUP] = handle;
return handle;
}

View File

@@ -1,8 +1,3 @@
import { afterAll } from "vitest";
import { installSharedTestSetup } from "./setup.shared.js";
const testEnv = installSharedTestSetup();
afterAll(() => {
testEnv.cleanup();
});
installSharedTestSetup();