test(pairing): reduce fixture io overhead

This commit is contained in:
Peter Steinberger
2026-04-25 18:41:07 +01:00
parent 8c93745f0f
commit 39488dfd68
2 changed files with 37 additions and 33 deletions

View File

@@ -1,14 +1,15 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
import {
clearAllowFromStoreReadCacheForTest,
readChannelAllowFromStoreEntriesSync,
resolveChannelAllowFromPath,
} from "./allow-from-store-read.js";
const tempDirs: string[] = [];
let fixtureRoot = "";
let caseId = 0;
function makeEnv(homeDir: string): NodeJS.ProcessEnv {
return {
@@ -18,8 +19,8 @@ function makeEnv(homeDir: string): NodeJS.ProcessEnv {
}
function makeHomeDir(): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-allow-from-read-"));
tempDirs.push(dir);
const dir = path.join(fixtureRoot, `case-${caseId++}`);
fs.mkdirSync(dir, { recursive: true });
return dir;
}
@@ -38,11 +39,18 @@ function writeAllowFromFile(params: {
);
}
beforeAll(() => {
fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-allow-from-read-"));
});
afterAll(() => {
if (fixtureRoot) {
fs.rmSync(fixtureRoot, { recursive: true, force: true });
}
});
afterEach(() => {
clearAllowFromStoreReadCacheForTest();
for (const dir of tempDirs.splice(0)) {
fs.rmSync(dir, { recursive: true, force: true });
}
});
describe("allow-from-store-read", () => {

View File

@@ -1,6 +1,5 @@
import crypto from "node:crypto";
import fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import {
@@ -78,13 +77,13 @@ type RandomIntSync = (minOrMax: number, max?: number) => number;
let randomIntSpy: MockInstance<RandomIntSync>;
let nextRandomInt = 0;
beforeAll(async () => {
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-pairing-"));
beforeAll(() => {
fixtureRoot = fsSync.mkdtempSync(path.join(os.tmpdir(), "openclaw-pairing-"));
});
afterAll(async () => {
afterAll(() => {
if (fixtureRoot) {
await fs.rm(fixtureRoot, { recursive: true, force: true });
fsSync.rmSync(fixtureRoot, { recursive: true, force: true });
}
});
@@ -110,13 +109,13 @@ function setDefaultRandomIntMock() {
async function withTempStateDir<T>(fn: (stateDir: string) => Promise<T>) {
const dir = path.join(fixtureRoot, `case-${caseId++}`);
await fs.mkdir(dir, { recursive: true });
fsSync.mkdirSync(dir, { recursive: true });
return await withEnvAsync({ OPENCLAW_STATE_DIR: dir }, async () => await fn(dir));
}
async function writeJsonFixture(filePath: string, value: unknown) {
await fs.mkdir(path.dirname(filePath), { recursive: true });
await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
function writeJsonFixture(filePath: string, value: unknown) {
fsSync.mkdirSync(path.dirname(filePath), { recursive: true });
fsSync.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
function resolvePairingFilePath(stateDir: string, channel: string) {
@@ -128,9 +127,9 @@ function resolveAllowFromFilePath(stateDir: string, channel: string, accountId?:
return path.join(resolveOAuthDir(process.env, stateDir), `${channel}${suffix}-allowFrom.json`);
}
async function clearOAuthFixtures(stateDir: string) {
function clearOAuthFixtures(stateDir: string) {
clearPairingAllowFromReadCacheForTest();
await fs.rm(resolveOAuthDir(process.env, stateDir), { recursive: true, force: true });
fsSync.rmSync(resolveOAuthDir(process.env, stateDir), { recursive: true, force: true });
}
async function writeAllowFromFixture(params: {
@@ -139,13 +138,10 @@ async function writeAllowFromFixture(params: {
allowFrom: string[];
accountId?: string;
}) {
await writeJsonFixture(
resolveAllowFromFilePath(params.stateDir, params.channel, params.accountId),
{
version: 1,
allowFrom: params.allowFrom,
},
);
writeJsonFixture(resolveAllowFromFilePath(params.stateDir, params.channel, params.accountId), {
version: 1,
allowFrom: params.allowFrom,
});
}
async function createTelegramPairingRequest(accountId: string, id = "12345") {
@@ -338,7 +334,7 @@ describe("pairing store", () => {
});
expect(created.created).toBe(true);
const filePath = resolvePairingFilePath(stateDir, "demo-pairing-b");
const raw = await fs.readFile(filePath, "utf8");
const raw = fsSync.readFileSync(filePath, "utf8");
const parsed = JSON.parse(raw) as {
requests?: Array<Record<string, unknown>>;
};
@@ -346,7 +342,7 @@ describe("pairing store", () => {
const requests = (parsed.requests ?? []).map((entry) =>
Object.assign({}, entry, { createdAt: expiredAt, lastSeenAt: expiredAt }),
);
await writeJsonFixture(filePath, { version: 1, requests });
writeJsonFixture(filePath, { version: 1, requests });
expect(await listChannelPairingRequests("demo-pairing-b")).toHaveLength(0);
const next = await upsertChannelPairingRequest({
channel: "demo-pairing-b",
@@ -374,7 +370,7 @@ describe("pairing store", () => {
expect(listIds).toEqual(["+15550000001", "+15550000002", "+15550000003"]);
const createdAt = new Date().toISOString();
await writeJsonFixture(resolvePairingFilePath(stateDir, "demo-pairing-d"), {
writeJsonFixture(resolvePairingFilePath(stateDir, "demo-pairing-d"), {
version: 1,
requests: ids.map((id, index) => ({
id,
@@ -510,8 +506,8 @@ describe("pairing store", () => {
allowFrom: ["1001"],
});
const malformedScopedPath = resolveAllowFromFilePath(stateDir, "telegram", "yy");
await fs.mkdir(path.dirname(malformedScopedPath), { recursive: true });
await fs.writeFile(malformedScopedPath, "{ this is not json\n", "utf8");
fsSync.mkdirSync(path.dirname(malformedScopedPath), { recursive: true });
fsSync.writeFileSync(malformedScopedPath, "{ this is not json\n", "utf8");
},
accountId: "yy",
expected: [],
@@ -531,7 +527,7 @@ describe("pairing store", () => {
expected: ["1002", "1001"],
},
] as const) {
await clearOAuthFixtures(stateDir);
clearOAuthFixtures(stateDir);
await setup();
await expectAllowFromReadConsistencyCase({
...(accountId !== undefined ? { accountId } : {}),
@@ -550,7 +546,7 @@ describe("pairing store", () => {
secondAccountId: "beta",
});
await clearOAuthFixtures(stateDir);
clearOAuthFixtures(stateDir);
for (const accountId of ["alpha", "beta", "gamma"]) {
const created = await upsertChannelPairingRequest({
channel: "telegram",
@@ -591,7 +587,7 @@ describe("pairing store", () => {
readAllowFrom: async () => readChannelAllowFromStoreSync("telegram", process.env, "yy"),
},
]) {
await clearOAuthFixtures(stateDir);
clearOAuthFixtures(stateDir);
await withAllowFromCacheReadSpy({
stateDir,
createReadSpy: variant.createReadSpy,