test(e2e): read shared auth store after onboarding

This commit is contained in:
Amp
2026-08-21 02:59:41 +00:00
committed by Peter Steinberger
parent cfe7b088ec
commit da11e64c0e
6 changed files with 73 additions and 96 deletions
@@ -1,6 +1,28 @@
// Shared auth profile store assertions for install/onboard E2E proof.
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import { isRecord } from "../../lib/record-shared.mjs";
export function readSharedAuthProfileStoreText(stateDir) {
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
if (!fs.existsSync(dbPath)) {
return "";
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const row = db
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
.get("shared");
return typeof row?.store_json === "string" ? row.store_json : "";
} catch {
return "";
} finally {
db?.close();
}
}
function hasExpectedOpenAiEnvRef(profile) {
if (!isRecord(profile)) {
return false;
+5 -20
View File
@@ -2,8 +2,10 @@
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
import {
assertOpenAiEnvAuthProfileStore,
readSharedAuthProfileStoreText,
} from "../auth-profile-store-assertions.mjs";
import {
assertPathInside,
configPath,
@@ -125,24 +127,7 @@ if (providerRuntime && providerRuntime !== "codex") {
throw new Error(`unexpected OpenAI provider runtime: ${providerRuntime}`);
}
function readAuthProfileStoreText(agentDir) {
const dbPath = path.join(agentDir, "openclaw-agent.sqlite");
if (!fs.existsSync(dbPath)) {
throw new Error("auth profile SQLite store was not persisted");
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const row = db
.prepare("SELECT store_json FROM auth_profile_store WHERE store_key = ?")
.get("primary");
return typeof row?.store_json === "string" ? row.store_json : "";
} finally {
db?.close();
}
}
const authRaw = readAuthProfileStoreText(path.join(stateDir(), "agents", "main", "agent"));
const authRaw = readSharedAuthProfileStoreText(stateDir());
if (!authRaw) {
throw new Error("auth profile SQLite store row was not persisted");
}
@@ -1,12 +1,14 @@
// Assertions for npm onboard channel-agent E2E scenarios.
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import {
assertAgentReplyContainsMarker,
assertOpenAiRequestLogUsed,
} from "../agent-turn-output.mjs";
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
import {
assertOpenAiEnvAuthProfileStore,
readSharedAuthProfileStoreText,
} from "../auth-profile-store-assertions.mjs";
import { readPositiveIntEnv } from "../env-limits.mjs";
import {
applyMockOpenAiModelConfig,
@@ -77,25 +79,6 @@ function extractStatusSection(text, title) {
return stripAnsi(section.join("\n"));
}
function readSharedAuthProfileStoreText(stateDir) {
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
if (!fs.existsSync(dbPath)) {
return "";
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const row = db
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
.get("shared");
return typeof row?.store_json === "string" ? row.store_json : "";
} catch {
return "";
} finally {
db?.close();
}
}
function assertOnboardState() {
const home = process.argv[3];
const stateDir = path.join(home, ".openclaw");
@@ -1,12 +1,14 @@
// Assertions for release scenario E2E packages and plugin state.
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import {
assertAgentReplyContainsMarker,
assertOpenAiRequestLogUsed,
} from "../agent-turn-output.mjs";
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
import {
assertOpenAiEnvAuthProfileStore,
readSharedAuthProfileStoreText,
} from "../auth-profile-store-assertions.mjs";
import {
applyMockOpenAiModelConfig,
parseMockOpenAiPort,
@@ -49,39 +51,16 @@ function authProfilesPath() {
);
}
function authProfilesDatabasePath() {
return path.join(
process.env.HOME ?? "",
".openclaw",
"agents",
"main",
"agent",
"openclaw-agent.sqlite",
);
}
function readAuthProfileStoreSqliteText() {
const dbPath = authProfilesDatabasePath();
if (!fs.existsSync(dbPath)) {
return "";
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const row = db
.prepare("SELECT store_json FROM auth_profile_store WHERE store_key = ?")
.get("primary");
return typeof row?.store_json === "string" ? row.store_json : "";
} catch {
return "";
} finally {
db?.close();
}
function stateDir() {
return process.env.OPENCLAW_STATE_DIR ?? path.dirname(configPath());
}
function readStateText() {
const paths = [configPath(), authProfilesPath()].filter((file) => fs.existsSync(file));
return [...paths.map((file) => fs.readFileSync(file, "utf8")), readAuthProfileStoreSqliteText()]
return [
...paths.map((file) => fs.readFileSync(file, "utf8")),
readSharedAuthProfileStoreText(stateDir()),
]
.filter(Boolean)
.join("\n");
}
@@ -96,7 +75,7 @@ function configureMockOpenAi() {
function assertOpenAiEnvRef() {
const rawKey = process.argv[3];
assert(fs.existsSync(configPath()), "openclaw.json missing");
assertOpenAiEnvAuthProfileStore(readAuthProfileStoreSqliteText(), {
assertOpenAiEnvAuthProfileStore(readSharedAuthProfileStoreText(stateDir()), {
missingMessage: "OpenAI env ref was not persisted",
envRefMessage: "OpenAI env ref was not persisted",
rawKeyMessage: "raw OpenAI key was persisted",
+12 -8
View File
@@ -1,7 +1,7 @@
// Codex Install Assertions tests cover Codex plugin install E2E helpers.
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
@@ -50,12 +50,13 @@ function writeJson(filePath: string, value: unknown) {
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
function writeAuthProfileStoreSqlite(agentDir: string) {
mkdirSync(agentDir, { recursive: true });
const db = new DatabaseSync(path.join(agentDir, "openclaw-agent.sqlite"));
function writeAuthProfileStoreSqlite(stateDir: string) {
const databasePath = path.join(stateDir, "state", "openclaw.sqlite");
mkdirSync(path.dirname(databasePath), { recursive: true });
const db = new DatabaseSync(databasePath);
try {
db.exec(`
CREATE TABLE IF NOT EXISTS auth_profile_store (
CREATE TABLE IF NOT EXISTS auth_profile_stores (
store_key TEXT NOT NULL PRIMARY KEY,
store_json TEXT NOT NULL,
updated_at INTEGER NOT NULL
@@ -63,11 +64,11 @@ function writeAuthProfileStoreSqlite(agentDir: string) {
`);
db.prepare(
`
INSERT INTO auth_profile_store (store_key, store_json, updated_at)
INSERT INTO auth_profile_stores (store_key, store_json, updated_at)
VALUES (?, ?, ?)
`,
).run(
"primary",
"shared",
JSON.stringify({
version: 1,
profiles: {
@@ -574,7 +575,7 @@ function createCodexInstallFixture(root: string) {
writeJson("/tmp/openclaw-plugins-list.json", {
plugins: [{ id: "codex", enabled: true, status: "loaded" }],
});
writeAuthProfileStoreSqlite(path.join(stateDir, "agents", "main", "agent"));
writeAuthProfileStoreSqlite(stateDir);
}
describe("Codex install helpers", () => {
@@ -692,6 +693,9 @@ describe("Codex install helpers", () => {
expect(result.status).toBe(0);
expect(result.stderr).toBe("");
expect(
existsSync(path.join(root, "state", "agents", "main", "agent", "openclaw-agent.sqlite")),
).toBe(false);
});
it("rejects on-demand fixtures without the canonical SQLite install record", () => {
@@ -1,6 +1,6 @@
// Release Scenarios Assertions tests cover release scenarios assertions script behavior.
import { spawnSync } from "node:child_process";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
@@ -32,12 +32,13 @@ function runAssertion(args: string[], env?: NodeJS.ProcessEnv) {
});
}
function writeAuthProfileStoreSqlite(agentDir: string, store: unknown) {
mkdirSync(agentDir, { recursive: true });
const db = new DatabaseSync(path.join(agentDir, "openclaw-agent.sqlite"));
function writeAuthProfileStoreSqlite(stateDir: string, store: unknown) {
const databasePath = path.join(stateDir, "state", "openclaw.sqlite");
mkdirSync(path.dirname(databasePath), { recursive: true });
const db = new DatabaseSync(databasePath);
try {
db.exec(`
CREATE TABLE IF NOT EXISTS auth_profile_store (
CREATE TABLE IF NOT EXISTS auth_profile_stores (
store_key TEXT NOT NULL PRIMARY KEY,
store_json TEXT NOT NULL,
updated_at INTEGER NOT NULL
@@ -45,10 +46,10 @@ function writeAuthProfileStoreSqlite(agentDir: string, store: unknown) {
`);
db.prepare(
`
INSERT INTO auth_profile_store (store_key, store_json, updated_at)
INSERT INTO auth_profile_stores (store_key, store_json, updated_at)
VALUES (?, ?, ?)
`,
).run("primary", JSON.stringify(store), Date.now());
).run("shared", JSON.stringify(store), Date.now());
} finally {
db.close();
}
@@ -196,7 +197,6 @@ describe("release scenario assertions", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
const home = path.join(root, "home");
const stateDir = path.join(home, ".openclaw");
const agentDir = path.join(stateDir, "agents", "main", "agent");
const configPath = path.join(stateDir, "openclaw.json");
try {
@@ -207,7 +207,7 @@ describe("release scenario assertions", () => {
},
},
});
writeAuthProfileStoreSqlite(agentDir, {
writeAuthProfileStoreSqlite(stateDir, {
version: 1,
profiles: {
"openai:api-key": {
@@ -221,10 +221,14 @@ describe("release scenario assertions", () => {
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
HOME: home,
OPENCLAW_CONFIG_PATH: configPath,
OPENCLAW_STATE_DIR: stateDir,
});
expect(result.status).toBe(0);
expect(result.stderr).toBe("");
expect(
existsSync(path.join(stateDir, "agents", "main", "agent", "openclaw-agent.sqlite")),
).toBe(false);
} finally {
rmSync(root, { force: true, recursive: true });
}
@@ -234,7 +238,6 @@ describe("release scenario assertions", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
const home = path.join(root, "home");
const stateDir = path.join(home, ".openclaw");
const agentDir = path.join(stateDir, "agents", "main", "agent");
const configPath = path.join(stateDir, "openclaw.json");
try {
@@ -245,7 +248,7 @@ describe("release scenario assertions", () => {
},
},
});
writeAuthProfileStoreSqlite(agentDir, {
writeAuthProfileStoreSqlite(stateDir, {
version: 1,
profiles: {
"openai:api-key": { note: "OPENAI_API_KEY" },
@@ -255,6 +258,7 @@ describe("release scenario assertions", () => {
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
HOME: home,
OPENCLAW_CONFIG_PATH: configPath,
OPENCLAW_STATE_DIR: stateDir,
});
expect(result.status).not.toBe(0);
@@ -268,7 +272,6 @@ describe("release scenario assertions", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
const home = path.join(root, "home");
const stateDir = path.join(home, ".openclaw");
const agentDir = path.join(stateDir, "agents", "main", "agent");
const configPath = path.join(stateDir, "openclaw.json");
try {
@@ -279,7 +282,7 @@ describe("release scenario assertions", () => {
},
},
});
writeAuthProfileStoreSqlite(agentDir, {
writeAuthProfileStoreSqlite(stateDir, {
version: 1,
profiles: {
"openai:api-key": {
@@ -293,6 +296,7 @@ describe("release scenario assertions", () => {
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
HOME: home,
OPENCLAW_CONFIG_PATH: configPath,
OPENCLAW_STATE_DIR: stateDir,
});
expect(result.status).not.toBe(0);
@@ -306,7 +310,6 @@ describe("release scenario assertions", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
const home = path.join(root, "home");
const stateDir = path.join(home, ".openclaw");
const agentDir = path.join(stateDir, "agents", "main", "agent");
const configPath = path.join(stateDir, "openclaw.json");
try {
@@ -322,7 +325,7 @@ describe("release scenario assertions", () => {
},
},
});
writeAuthProfileStoreSqlite(agentDir, {
writeAuthProfileStoreSqlite(stateDir, {
version: 1,
profiles: {
"openai:api-key": {
@@ -336,6 +339,7 @@ describe("release scenario assertions", () => {
const result = runAssertion(["assert-openai-env-ref", "sk-test-raw-key"], {
HOME: home,
OPENCLAW_CONFIG_PATH: configPath,
OPENCLAW_STATE_DIR: stateDir,
});
expect(result.status).not.toBe(0);