Skip to content

Commit 4dcc39c

Browse files
committed
test: snapshot ci timeout investigation
1 parent 6e012d7 commit 4dcc39c

File tree

2 files changed

+106
-85
lines changed

2 files changed

+106
-85
lines changed

src/infra/provider-usage.auth.normalizes-keys.test.ts

Lines changed: 92 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import fs from "node:fs/promises";
22
import os from "node:os";
33
import path from "node:path";
4-
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
4+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
5+
import { clearRuntimeAuthProfileStoreSnapshots } from "../agents/auth-profiles.js";
56
import { NON_ENV_SECRETREF_MARKER } from "../agents/model-auth-markers.js";
7+
import { clearConfigCache, type OpenClawConfig } from "../config/config.js";
68

79
const resolveProviderUsageAuthWithPluginMock = vi.fn(async (..._args: unknown[]) => null);
810

911
vi.mock("../plugins/provider-runtime.js", () => ({
1012
resolveProviderUsageAuthWithPlugin: resolveProviderUsageAuthWithPluginMock,
1113
}));
1214

15+
vi.mock("../agents/cli-credentials.js", () => ({
16+
readCodexCliCredentialsCached: () => null,
17+
readMiniMaxCliCredentialsCached: () => null,
18+
readQwenCliCredentialsCached: () => null,
19+
}));
20+
1321
let resolveProviderAuths: typeof import("./provider-usage.auth.js").resolveProviderAuths;
1422
type ProviderAuth = import("./provider-usage.auth.js").ProviderAuth;
1523

@@ -36,65 +44,59 @@ describe("resolveProviderAuths key normalization", () => {
3644
});
3745

3846
beforeEach(() => {
47+
clearConfigCache();
48+
clearRuntimeAuthProfileStoreSnapshots();
3949
resolveProviderUsageAuthWithPluginMock.mockReset();
4050
resolveProviderUsageAuthWithPluginMock.mockResolvedValue(null);
4151
});
4252

43-
async function withSuiteHome<T>(
44-
fn: (home: string) => Promise<T>,
45-
env: Record<string, string | undefined>,
46-
): Promise<T> {
53+
afterEach(() => {
54+
clearConfigCache();
55+
clearRuntimeAuthProfileStoreSnapshots();
56+
});
57+
58+
async function withSuiteHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
4759
const base = path.join(suiteRoot, `case-${++suiteCase}`);
4860
await fs.mkdir(base, { recursive: true });
4961
await fs.mkdir(path.join(base, ".openclaw", "agents", "main", "sessions"), { recursive: true });
62+
return await fn(base);
63+
}
5064

51-
const keysToRestore = new Set<string>([
52-
"HOME",
53-
"USERPROFILE",
54-
"HOMEDRIVE",
55-
"HOMEPATH",
56-
"OPENCLAW_HOME",
57-
"OPENCLAW_STATE_DIR",
58-
...Object.keys(env),
59-
]);
60-
const snapshot: Record<string, string | undefined> = {};
61-
for (const key of keysToRestore) {
62-
snapshot[key] = process.env[key];
63-
}
65+
function agentDirForHome(home: string): string {
66+
return path.join(home, ".openclaw", "agents", "main", "agent");
67+
}
6468

65-
process.env.HOME = base;
66-
process.env.USERPROFILE = base;
67-
if (process.platform === "win32") {
68-
const match = base.match(/^([A-Za-z]:)(.*)$/);
69-
if (match) {
70-
process.env.HOMEDRIVE = match[1];
71-
process.env.HOMEPATH = match[2] || "\\";
72-
}
73-
}
74-
delete process.env.OPENCLAW_HOME;
75-
process.env.OPENCLAW_STATE_DIR = path.join(base, ".openclaw");
76-
for (const [key, value] of Object.entries(env)) {
77-
if (value === undefined) {
78-
delete process.env[key];
79-
} else {
80-
process.env[key] = value;
81-
}
69+
function buildSuiteEnv(
70+
home: string,
71+
env: Record<string, string | undefined> = {},
72+
): NodeJS.ProcessEnv {
73+
const suiteEnv: NodeJS.ProcessEnv = {
74+
...EMPTY_PROVIDER_ENV,
75+
HOME: home,
76+
USERPROFILE: home,
77+
OPENCLAW_STATE_DIR: path.join(home, ".openclaw"),
78+
...env,
79+
};
80+
const match = home.match(/^([A-Za-z]:)(.*)$/);
81+
if (match) {
82+
suiteEnv.HOMEDRIVE = match[1];
83+
suiteEnv.HOMEPATH = match[2] || "\\";
8284
}
85+
return suiteEnv;
86+
}
87+
88+
async function readConfigForHome(home: string): Promise<Record<string, unknown>> {
8389
try {
84-
return await fn(base);
85-
} finally {
86-
for (const [key, value] of Object.entries(snapshot)) {
87-
if (value === undefined) {
88-
delete process.env[key];
89-
} else {
90-
process.env[key] = value;
91-
}
92-
}
90+
return JSON.parse(
91+
await fs.readFile(path.join(home, ".openclaw", "openclaw.json"), "utf8"),
92+
) as Record<string, unknown>;
93+
} catch {
94+
return {};
9395
}
9496
}
9597

9698
async function writeAuthProfiles(home: string, profiles: Record<string, unknown>) {
97-
const agentDir = path.join(home, ".openclaw", "agents", "main", "agent");
99+
const agentDir = agentDirForHome(home);
98100
await fs.mkdir(agentDir, { recursive: true });
99101
await fs.writeFile(
100102
path.join(agentDir, "auth-profiles.json"),
@@ -114,7 +116,7 @@ describe("resolveProviderAuths key normalization", () => {
114116
}
115117

116118
async function writeProfileOrder(home: string, provider: string, profileIds: string[]) {
117-
const agentDir = path.join(home, ".openclaw", "agents", "main", "agent");
119+
const agentDir = agentDirForHome(home);
118120
const parsed = JSON.parse(
119121
await fs.readFile(path.join(agentDir, "auth-profiles.json"), "utf8"),
120122
) as Record<string, unknown>;
@@ -149,28 +151,26 @@ describe("resolveProviderAuths key normalization", () => {
149151
}
150152

151153
async function resolveMinimaxAuthFromConfiguredKey(apiKey: string) {
152-
return await withSuiteHome(
153-
async (home) => {
154-
await writeConfig(home, {
155-
models: {
156-
providers: {
157-
minimax: {
158-
baseUrl: "https://api.minimaxi.com",
159-
models: [createTestModelDefinition()],
160-
apiKey,
161-
},
154+
return await withSuiteHome(async (home) => {
155+
await writeConfig(home, {
156+
models: {
157+
providers: {
158+
minimax: {
159+
baseUrl: "https://api.minimaxi.com",
160+
models: [createTestModelDefinition()],
161+
apiKey,
162162
},
163163
},
164-
});
164+
},
165+
});
165166

166-
return await resolveProviderAuths({
167-
providers: ["minimax"],
168-
});
169-
},
170-
{
171-
...EMPTY_PROVIDER_ENV,
172-
},
173-
);
167+
return await resolveProviderAuths({
168+
providers: ["minimax"],
169+
agentDir: agentDirForHome(home),
170+
config: (await readConfigForHome(home)) as OpenClawConfig,
171+
env: buildSuiteEnv(home),
172+
});
173+
});
174174
}
175175

176176
async function expectResolvedAuthsFromSuiteHome(params: {
@@ -179,19 +179,16 @@ describe("resolveProviderAuths key normalization", () => {
179179
env?: Record<string, string | undefined>;
180180
setup?: (home: string) => Promise<void>;
181181
}) {
182-
await withSuiteHome(
183-
async (home) => {
184-
await params.setup?.(home);
185-
const auths = await resolveProviderAuths({
186-
providers: params.providers,
187-
});
188-
expect(auths).toEqual(params.expected);
189-
},
190-
{
191-
...EMPTY_PROVIDER_ENV,
192-
...params.env,
193-
},
194-
);
182+
await withSuiteHome(async (home) => {
183+
await params.setup?.(home);
184+
const auths = await resolveProviderAuths({
185+
providers: params.providers,
186+
agentDir: agentDirForHome(home),
187+
config: (await readConfigForHome(home)) as OpenClawConfig,
188+
env: buildSuiteEnv(home, params.env),
189+
});
190+
expect(auths).toEqual(params.expected);
191+
});
195192
}
196193

197194
it.each([
@@ -401,18 +398,24 @@ describe("resolveProviderAuths key normalization", () => {
401398

402399
const auths = await resolveProviderAuths({
403400
providers: ["anthropic"],
401+
agentDir: agentDirForHome(home),
402+
config: (await readConfigForHome(home)) as OpenClawConfig,
403+
env: buildSuiteEnv(home),
404404
});
405405
expect(auths).toEqual([]);
406-
}, {});
406+
});
407407
});
408408

409409
it("skips providers without oauth-compatible profiles", async () => {
410-
await withSuiteHome(async () => {
410+
await withSuiteHome(async (home) => {
411411
const auths = await resolveProviderAuths({
412412
providers: ["anthropic"],
413+
agentDir: agentDirForHome(home),
414+
config: (await readConfigForHome(home)) as OpenClawConfig,
415+
env: buildSuiteEnv(home),
413416
});
414417
expect(auths).toEqual([]);
415-
}, {});
418+
});
416419
});
417420

418421
it("skips oauth profiles that resolve without an api key and uses later profiles", async () => {
@@ -430,9 +433,12 @@ describe("resolveProviderAuths key normalization", () => {
430433

431434
const auths = await resolveProviderAuths({
432435
providers: ["anthropic"],
436+
agentDir: agentDirForHome(home),
437+
config: (await readConfigForHome(home)) as OpenClawConfig,
438+
env: buildSuiteEnv(home),
433439
});
434440
expect(auths).toEqual([{ provider: "anthropic", token: "anthropic-token" }]);
435-
}, {});
441+
});
436442
});
437443

438444
it("skips api_key entries in oauth token resolution order", async () => {
@@ -445,9 +451,12 @@ describe("resolveProviderAuths key normalization", () => {
445451

446452
const auths = await resolveProviderAuths({
447453
providers: ["anthropic"],
454+
agentDir: agentDirForHome(home),
455+
config: (await readConfigForHome(home)) as OpenClawConfig,
456+
env: buildSuiteEnv(home),
448457
});
449458
expect(auths).toEqual([{ provider: "anthropic", token: "token-1" }]);
450-
}, {});
459+
});
451460
});
452461

453462
it("ignores marker-backed config keys for provider usage auth resolution", async () => {

src/memory/manager.async-search.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,16 @@ describe("memory search async sync", () => {
6666
const cfg = buildConfig();
6767
manager = await createMemoryManagerOrThrow(cfg);
6868

69-
const pending = new Promise<void>(() => {});
70-
const syncMock = vi.fn(async () => pending);
69+
let releaseSync = () => {};
70+
const pending = new Promise<void>((resolve) => {
71+
releaseSync = () => resolve();
72+
}).finally(() => {
73+
(manager as unknown as { syncing: Promise<void> | null }).syncing = null;
74+
});
75+
const syncMock = vi.fn(async () => {
76+
(manager as unknown as { syncing: Promise<void> | null }).syncing = pending;
77+
return pending;
78+
});
7179
(manager as unknown as { sync: () => Promise<void> }).sync = syncMock;
7280

7381
const activeManager = manager;
@@ -76,6 +84,10 @@ describe("memory search async sync", () => {
7684
}
7785
await activeManager.search("hello");
7886
expect(syncMock).toHaveBeenCalledTimes(1);
87+
releaseSync();
88+
await vi.waitFor(() => {
89+
expect((manager as unknown as { syncing: Promise<void> | null }).syncing).toBeNull();
90+
});
7991
});
8092

8193
it("waits for in-flight search sync during close", async () => {

0 commit comments

Comments
 (0)