实现 v0.1 Postgres durable store 骨架

This commit is contained in:
Codex
2026-05-29 11:41:20 +08:00
parent a240122039
commit 2288cb1558
11 changed files with 601 additions and 44 deletions
+30 -5
View File
@@ -4,9 +4,12 @@ import path from "node:path";
import { fileURLToPath } from "node:url";
import assert from "node:assert/strict";
import { startManagerServer } from "../mgr/server.js";
import { MemoryAgentRunStore, openAgentRunStoreFromEnv } from "../mgr/store.js";
import { postgresMigrationContract } from "../mgr/postgres-store.js";
import { ManagerClient } from "../mgr/client.js";
import { runOnce } from "../runner/run-once.js";
import { redactText } from "../common/redaction.js";
import { AgentRunError } from "../common/errors.js";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const tmp = await mkdtemp(path.join(os.tmpdir(), "agentrun-selftest-"));
@@ -21,12 +24,26 @@ try {
await writeFile(path.join(workspace, "README.md"), "self-test workspace\n");
assert.equal(redactText("Authorization: Bearer abc123"), "Authorization: Bearer REDACTED");
await assert.rejects(
() => openAgentRunStoreFromEnv({}),
(error) => error instanceof AgentRunError && error.failureKind === "infra-failed" && error.message.includes("DATABASE_URL is required"),
);
const postgresContract = postgresMigrationContract();
assert.equal(postgresContract.latestMigrationId, "001_v01_initial_durable_store");
assert.ok(Array.isArray(postgresContract.requiredTables));
assert.ok(postgresContract.requiredTables.includes("agentrun_schema_migrations"));
assert.ok(postgresContract.requiredTables.includes("agentrun_runs"));
assert.ok(postgresContract.requiredTables.includes("agentrun_events"));
const server = await startManagerServer({ port: 0, host: "127.0.0.1", sourceCommit: "self-test" });
const server = await startManagerServer({ port: 0, host: "127.0.0.1", sourceCommit: "self-test", store: new MemoryAgentRunStore() });
try {
const client = new ManagerClient(server.baseUrl);
const health = await client.get("/health/readiness") as { database?: { adapter?: string } };
const health = await client.get("/health/readiness") as { database?: { adapter?: string; reachable?: boolean; migrationReady?: boolean; failureKind?: string | null }; secretRefs?: { valuesPrinted?: boolean } };
assert.equal(health.database?.adapter, "memory-self-test");
assert.equal(health.database?.reachable, true);
assert.equal(health.database?.migrationReady, true);
assert.equal(health.database?.failureKind, null);
assert.equal(health.secretRefs?.valuesPrinted, false);
const run = await client.post("/api/v1/runs", {
tenantId: "unidesk",
projectId: "pikasTech/unidesk",
@@ -46,8 +63,8 @@ try {
const duplicate = await client.post(`/api/v1/runs/${run.id}/commands`, { type: "turn", payload: { prompt: "hello" }, idempotencyKey: "selftest-turn" }) as { id: string };
assert.equal(duplicate.id, command.id);
const fakePath = path.join(root, "src/selftest/fake-codex-app-server.ts");
const fakeCommand = process.env.AGENTRUN_SELFTEST_CODEX_COMMAND ?? process.execPath;
const fakeArgs = process.env.AGENTRUN_SELFTEST_CODEX_ARGS ? JSON.parse(process.env.AGENTRUN_SELFTEST_CODEX_ARGS) as string[] : [fakePath];
const fakeCommand = process.env.AGENTRUN_SELFTEST_CODEX_COMMAND ?? defaultFakeCommand();
const fakeArgs = process.env.AGENTRUN_SELFTEST_CODEX_ARGS ? JSON.parse(process.env.AGENTRUN_SELFTEST_CODEX_ARGS) as string[] : defaultFakeArgs(fakePath);
const result = await runOnce({ managerUrl: server.baseUrl, runId: run.id, codexCommand: fakeCommand, codexArgs: fakeArgs, codexHome, env: { CODEX_HOME: codexHome } });
assert.equal(result.terminalStatus, "completed");
const events = await client.get(`/api/v1/runs/${run.id}/events?afterSeq=0&limit=100`) as { items?: Array<{ type: string; payload: unknown }> };
@@ -56,10 +73,18 @@ try {
assert.equal(JSON.stringify(events).includes("Bearer test-token"), false);
const finalRun = await client.get(`/api/v1/runs/${run.id}`) as { terminalStatus?: string };
assert.equal(finalRun.terminalStatus, "completed");
console.log(JSON.stringify({ ok: true, tests: ["manager-memory-lifecycle", "codex-stdio-fake-turn", "redaction"], runId: run.id }));
console.log(JSON.stringify({ ok: true, tests: ["manager-memory-lifecycle", "codex-stdio-fake-turn", "postgres-store-contract", "redaction"], runId: run.id }));
} finally {
await new Promise<void>((resolve) => server.server.close(() => resolve()));
}
} finally {
await rm(tmp, { recursive: true, force: true });
}
function defaultFakeCommand(): string {
return process.versions.bun ? process.execPath : "npx";
}
function defaultFakeArgs(fakePath: string): string[] {
return process.versions.bun ? [fakePath] : ["tsx", fakePath];
}