Files
openclaw/src/secrets/runtime-state.test.ts
Peter Steinberger 0177a4b6c9 fix(gateway): speed up secrets startup
Summary:
- Split the lightweight secrets runtime state and auth-store cache from the full secrets runtime.
- Use the startup fast path whenever gateway startup has no SecretRef values, while preserving cleanup and refresh semantics.
- Add regression coverage for startup-only empty auth-store snapshots and update affected gateway/tool tests.

Verification:
- pnpm test src/secrets/runtime.fast-path.test.ts src/secrets/runtime-state.test.ts src/gateway/server-startup-config.secrets.test.ts src/gateway/server-import-boundary.test.ts src/gateway/server-aux-handlers.test.ts src/gateway/server-methods/config.shared-auth.test.ts src/agents/tools/web-tools.enabled-defaults.test.ts src/agents/tools/web-tool-runtime-context.test.ts -- --reporter=verbose
- pnpm build
- pnpm format:check -- src/agents/tools/web-tools.enabled-defaults.test.ts src/secrets/runtime-command-secrets.ts src/secrets/runtime-fast-path.ts src/secrets/runtime.fast-path.test.ts src/agents/auth-profiles/store.ts src/agents/auth-profiles/store-cache.ts src/secrets/runtime-state.ts src/secrets/runtime-state.test.ts src/gateway/server-startup-config.ts
- codex-review --mode branch
- isolated gateway token-auth smoke: openclaw gateway run + openclaw gateway health returned ok: true
- GitHub CI on PR #83031 green; newer Real behavior proof run passed on current SHA f27ed3f7ce.

Co-authored-by: samzong <samzong.lu@gmail.com>
2026-05-17 10:55:41 +01:00

72 lines
2.3 KiB
TypeScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { resolveAuthStatePath, resolveAuthStorePath } from "../agents/auth-profiles/paths.js";
import { writeCachedAuthProfileStore } from "../agents/auth-profiles/store-cache.js";
import { loadAuthProfileStoreForRuntime } from "../agents/auth-profiles/store.js";
import type { AuthProfileStore } from "../agents/auth-profiles/types.js";
import { clearSecretsRuntimeSnapshot } from "./runtime-state.js";
function authStore(key: string): AuthProfileStore {
return {
version: 1,
profiles: {
"openai:default": {
type: "api_key",
provider: "openai",
key,
},
},
};
}
describe("secrets runtime state", () => {
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
afterEach(() => {
clearSecretsRuntimeSnapshot();
if (previousStateDir === undefined) {
delete process.env.OPENCLAW_STATE_DIR;
} else {
process.env.OPENCLAW_STATE_DIR = previousStateDir;
}
});
it("clears loaded auth-profile cache without importing the full secrets runtime", () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-runtime-state-cache-"));
process.env.OPENCLAW_STATE_DIR = root;
const agentDir = path.join(root, "agents", "default", "agent");
try {
fs.mkdirSync(agentDir, { recursive: true });
const authPath = resolveAuthStorePath(agentDir);
const statePath = resolveAuthStatePath(agentDir);
fs.writeFileSync(authPath, `${JSON.stringify(authStore("sk-new"))}\n`);
const stat = fs.statSync(authPath);
writeCachedAuthProfileStore({
authPath,
authMtimeMs: stat.mtimeMs,
stateMtimeMs: fs.existsSync(statePath) ? fs.statSync(statePath).mtimeMs : null,
store: authStore("sk-old"),
});
expect(
loadAuthProfileStoreForRuntime(agentDir, { syncExternalCli: false }).profiles[
"openai:default"
],
).toMatchObject({ key: "sk-old" });
clearSecretsRuntimeSnapshot();
expect(
loadAuthProfileStoreForRuntime(agentDir, { syncExternalCli: false }).profiles[
"openai:default"
],
).toMatchObject({ key: "sk-new" });
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
});