mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 00:34:33 +00:00
refactor(test): centralize temporary state-dir env setup
This commit is contained in:
@@ -1,45 +1,28 @@
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import os from "node:os";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { defaultRuntime } from "../runtime.js";
|
import { defaultRuntime } from "../runtime.js";
|
||||||
import {
|
import { withStateDirEnv } from "../test-helpers/state-dir-env.js";
|
||||||
restoreStateDirEnv,
|
|
||||||
setStateDirEnv,
|
|
||||||
snapshotStateDirEnv,
|
|
||||||
} from "../test-helpers/state-dir-env.js";
|
|
||||||
import { createCanvasHostHandler } from "./server.js";
|
import { createCanvasHostHandler } from "./server.js";
|
||||||
|
|
||||||
describe("canvas host state dir defaults", () => {
|
describe("canvas host state dir defaults", () => {
|
||||||
let envSnapshot: ReturnType<typeof snapshotStateDirEnv>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
envSnapshot = snapshotStateDirEnv();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
restoreStateDirEnv(envSnapshot);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("uses OPENCLAW_STATE_DIR for the default canvas root", async () => {
|
it("uses OPENCLAW_STATE_DIR for the default canvas root", async () => {
|
||||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-canvas-state-"));
|
await withStateDirEnv("openclaw-canvas-state-", async ({ stateDir }) => {
|
||||||
const stateDir = path.join(tempRoot, "state");
|
const handler = await createCanvasHostHandler({
|
||||||
setStateDirEnv(stateDir);
|
runtime: defaultRuntime,
|
||||||
const handler = await createCanvasHostHandler({
|
allowInTests: true,
|
||||||
runtime: defaultRuntime,
|
});
|
||||||
allowInTests: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const expectedRoot = await fs.realpath(path.join(stateDir, "canvas"));
|
const expectedRoot = await fs.realpath(path.join(stateDir, "canvas"));
|
||||||
const actualRoot = await fs.realpath(handler.rootDir);
|
const actualRoot = await fs.realpath(handler.rootDir);
|
||||||
expect(actualRoot).toBe(expectedRoot);
|
expect(actualRoot).toBe(expectedRoot);
|
||||||
const indexPath = path.join(expectedRoot, "index.html");
|
const indexPath = path.join(expectedRoot, "index.html");
|
||||||
const indexContents = await fs.readFile(indexPath, "utf8");
|
const indexContents = await fs.readFile(indexPath, "utf8");
|
||||||
expect(indexContents).toContain("OpenClaw Canvas");
|
expect(indexContents).toContain("OpenClaw Canvas");
|
||||||
} finally {
|
} finally {
|
||||||
await handler.close();
|
await handler.close();
|
||||||
await fs.rm(tempRoot, { recursive: true, force: true });
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,37 +1,16 @@
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import os from "node:os";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import {
|
import { withStateDirEnv } from "../test-helpers/state-dir-env.js";
|
||||||
restoreStateDirEnv,
|
|
||||||
setStateDirEnv,
|
|
||||||
snapshotStateDirEnv,
|
|
||||||
} from "../test-helpers/state-dir-env.js";
|
|
||||||
import { loadOrCreateDeviceIdentity } from "./device-identity.js";
|
import { loadOrCreateDeviceIdentity } from "./device-identity.js";
|
||||||
|
|
||||||
describe("device identity state dir defaults", () => {
|
describe("device identity state dir defaults", () => {
|
||||||
let envSnapshot: ReturnType<typeof snapshotStateDirEnv>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
envSnapshot = snapshotStateDirEnv();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
restoreStateDirEnv(envSnapshot);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("writes the default identity file under OPENCLAW_STATE_DIR", async () => {
|
it("writes the default identity file under OPENCLAW_STATE_DIR", async () => {
|
||||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-identity-state-"));
|
await withStateDirEnv("openclaw-identity-state-", async ({ stateDir }) => {
|
||||||
const stateDir = path.join(tempRoot, "state");
|
const identity = loadOrCreateDeviceIdentity();
|
||||||
setStateDirEnv(stateDir);
|
|
||||||
const identity = loadOrCreateDeviceIdentity();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const identityPath = path.join(stateDir, "identity", "device.json");
|
const identityPath = path.join(stateDir, "identity", "device.json");
|
||||||
const raw = JSON.parse(await fs.readFile(identityPath, "utf8")) as { deviceId?: string };
|
const raw = JSON.parse(await fs.readFile(identityPath, "utf8")) as { deviceId?: string };
|
||||||
expect(raw.deviceId).toBe(identity.deviceId);
|
expect(raw.deviceId).toBe(identity.deviceId);
|
||||||
} finally {
|
});
|
||||||
await fs.rm(tempRoot, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
45
src/test-helpers/state-dir-env.test.ts
Normal file
45
src/test-helpers/state-dir-env.test.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
|
restoreStateDirEnv,
|
||||||
|
setStateDirEnv,
|
||||||
|
snapshotStateDirEnv,
|
||||||
|
withStateDirEnv,
|
||||||
|
} from "./state-dir-env.js";
|
||||||
|
|
||||||
|
describe("state-dir-env helpers", () => {
|
||||||
|
it("set/snapshot/restore round-trips OPENCLAW_STATE_DIR", () => {
|
||||||
|
const prevOpenClaw = process.env.OPENCLAW_STATE_DIR;
|
||||||
|
const prevLegacy = process.env.CLAWDBOT_STATE_DIR;
|
||||||
|
const snapshot = snapshotStateDirEnv();
|
||||||
|
|
||||||
|
setStateDirEnv("/tmp/openclaw-state-dir-test");
|
||||||
|
expect(process.env.OPENCLAW_STATE_DIR).toBe("/tmp/openclaw-state-dir-test");
|
||||||
|
expect(process.env.CLAWDBOT_STATE_DIR).toBeUndefined();
|
||||||
|
|
||||||
|
restoreStateDirEnv(snapshot);
|
||||||
|
expect(process.env.OPENCLAW_STATE_DIR).toBe(prevOpenClaw);
|
||||||
|
expect(process.env.CLAWDBOT_STATE_DIR).toBe(prevLegacy);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("withStateDirEnv sets env for callback and cleans up temp root", async () => {
|
||||||
|
const prevOpenClaw = process.env.OPENCLAW_STATE_DIR;
|
||||||
|
const prevLegacy = process.env.CLAWDBOT_STATE_DIR;
|
||||||
|
|
||||||
|
let capturedTempRoot = "";
|
||||||
|
let capturedStateDir = "";
|
||||||
|
await withStateDirEnv("openclaw-state-dir-env-", async ({ tempRoot, stateDir }) => {
|
||||||
|
capturedTempRoot = tempRoot;
|
||||||
|
capturedStateDir = stateDir;
|
||||||
|
expect(process.env.OPENCLAW_STATE_DIR).toBe(stateDir);
|
||||||
|
expect(process.env.CLAWDBOT_STATE_DIR).toBeUndefined();
|
||||||
|
await fs.writeFile(path.join(stateDir, "probe.txt"), "ok", "utf8");
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(process.env.OPENCLAW_STATE_DIR).toBe(prevOpenClaw);
|
||||||
|
expect(process.env.CLAWDBOT_STATE_DIR).toBe(prevLegacy);
|
||||||
|
await expect(fs.stat(capturedStateDir)).rejects.toThrow();
|
||||||
|
await expect(fs.stat(capturedTempRoot)).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
|
import os from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
import { captureEnv } from "../test-utils/env.js";
|
import { captureEnv } from "../test-utils/env.js";
|
||||||
|
|
||||||
export function snapshotStateDirEnv() {
|
export function snapshotStateDirEnv() {
|
||||||
@@ -12,3 +15,20 @@ export function setStateDirEnv(stateDir: string): void {
|
|||||||
process.env.OPENCLAW_STATE_DIR = stateDir;
|
process.env.OPENCLAW_STATE_DIR = stateDir;
|
||||||
delete process.env.CLAWDBOT_STATE_DIR;
|
delete process.env.CLAWDBOT_STATE_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function withStateDirEnv<T>(
|
||||||
|
prefix: string,
|
||||||
|
fn: (ctx: { tempRoot: string; stateDir: string }) => Promise<T>,
|
||||||
|
): Promise<T> {
|
||||||
|
const snapshot = snapshotStateDirEnv();
|
||||||
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||||
|
const stateDir = path.join(tempRoot, "state");
|
||||||
|
await fs.mkdir(stateDir, { recursive: true });
|
||||||
|
setStateDirEnv(stateDir);
|
||||||
|
try {
|
||||||
|
return await fn({ tempRoot, stateDir });
|
||||||
|
} finally {
|
||||||
|
restoreStateDirEnv(snapshot);
|
||||||
|
await fs.rm(tempRoot, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user