test(audit): consolidate worker lifecycle coverage (#122369)

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-11 18:51:12 -07:00
committed by GitHub
parent 8876528f7c
commit b529217878
+116 -186
View File
@@ -78,16 +78,34 @@ afterEach(() => {
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
describe("audit event worker", () => {
it("keeps first-use identity storage absent during maintenance without admission", async () => {
it("keeps fresh storage identity-free when recovery evidence is missing", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
await writer.ready;
expect(
openOpenClawStateDatabase(database)
.db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?")
.get("execution_identity_contexts"),
).toBeUndefined();
expect(writer.record(input())).toBe(true);
const token = createExecutionIdentityAdmissionToken("raw-run-not-a-secret", {
contextId: "context-missing",
executionId: "execution-missing",
now: 100,
});
const startedAt = performance.now();
expect(writer.recordExecutionIdentity({ kind: "retry-reference", token })).toBe(true);
expect(performance.now() - startedAt).toBeLessThan(250);
await writer.stop();
expect(errors).toEqual([]);
expect(errors).toEqual(["audit execution identity recovery evidence unavailable"]);
expect(JSON.stringify(errors)).not.toContain(token.contextId);
expect(JSON.stringify(errors)).not.toContain(token.executionId);
expect(JSON.stringify(errors)).not.toContain(token.runId);
expect(listAuditEvents({ database, limit: 10 }).events).toHaveLength(1);
expect(
openOpenClawStateDatabase(database)
.db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?")
@@ -95,95 +113,90 @@ describe("audit event worker", () => {
).toBeUndefined();
});
it("keeps an established current store identity-free during maintenance", async () => {
it("keeps the shared queue nonblocking under a held write lock and flushes before stop", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
recordAuditEvent(input(), database);
closeOpenClawStateDatabaseForTest();
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
const writer = createAuditEventWriter({
stateDir,
maxPending: 2,
onError: (error) => errors.push(error),
});
await writer.ready;
await writer.stop();
expect(errors).toEqual([]);
expect(listAuditEvents({ database, limit: 10 }).events).toHaveLength(1);
const { db } = openOpenClawStateDatabase(database);
expect(
openOpenClawStateDatabase(database)
.db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?")
db
.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?")
.get("execution_identity_contexts"),
).toBeUndefined();
});
it("returns immediately under SQLite contention and flushes before stop", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
await writer.ready;
const { db } = openOpenClawStateDatabase(database);
db.exec("BEGIN IMMEDIATE");
const startedAt = performance.now();
expect(writer.record(input())).toBe(true);
expect(performance.now() - startedAt).toBeLessThan(250);
db.exec("ROLLBACK");
await writer.stop();
expect(errors).toEqual([]);
expect(listAuditEvents({ database, limit: 10 }).events).toHaveLength(1);
});
it("keeps first-use identity admission prompt under a held write lock", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const { db } = openOpenClawStateDatabase(database);
db.exec("DELETE FROM audit_identity_keys;");
db.exec("BEGIN IMMEDIATE");
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
const clearSink = configureExecutionIdentityAdmissionSink(writer.recordExecutionIdentity);
const admittedAt = Date.now();
const startedAt = performance.now();
expect(
enqueueExecutionIdentityContextAtAdmission(
{
runId: "held-lock-run",
agentId: "main",
ingress: {
kind: "local-cli",
boundary: "agent-command.local",
state: "present",
rawSourceRef: "raw-ingress-secret",
try {
const startedAt = performance.now();
expect(writer.record({ ...input(), sourceId: "run-2:1:started", runId: "run-2" })).toBe(true);
expect(
enqueueExecutionIdentityContextAtAdmission(
{
runId: "held-lock-run",
agentId: "main",
ingress: {
kind: "local-cli",
boundary: "agent-command.local",
state: "present",
rawSourceRef: "raw-ingress-secret",
},
runtime: { kind: "embedded" },
invoker: { kind: "local-account", rawPrincipalRef: "raw-principal-secret" },
},
runtime: { kind: "embedded" },
invoker: { kind: "local-account", rawPrincipalRef: "raw-principal-secret" },
},
{
enabled: true,
contextId: "held-lock-context",
executionId: "held-lock-execution",
now: admittedAt,
runtimeInstanceId: "raw-runtime-secret",
},
),
).toEqual({
candidateContextId: "held-lock-context",
candidateExecutionId: "held-lock-execution",
accepted: true,
});
expect(performance.now() - startedAt).toBeLessThan(250);
expect(
db.prepare("SELECT name FROM sqlite_schema WHERE name = 'execution_identity_contexts'").get(),
).toBeUndefined();
expect(db.prepare("SELECT COUNT(*) AS count FROM audit_identity_keys").get()).toEqual({
count: 0,
});
{
enabled: true,
contextId: "held-lock-context",
executionId: "held-lock-execution",
now: admittedAt,
runtimeInstanceId: "raw-runtime-secret",
},
),
).toEqual({
candidateContextId: "held-lock-context",
candidateExecutionId: "held-lock-execution",
accepted: true,
});
expect(performance.now() - startedAt).toBeLessThan(250);
expect(
writer.recordExecutionIdentity({
kind: "retry-reference",
token: createExecutionIdentityAdmissionToken("queue-full-run", {
contextId: "queue-full-context",
executionId: "queue-full-execution",
now: admittedAt,
}),
}),
).toBe(false);
expect(errors).toEqual(["audit event queue is full (2); dropping metadata"]);
expect(
db
.prepare("SELECT name FROM sqlite_schema WHERE name = 'execution_identity_contexts'")
.get(),
).toBeUndefined();
expect(db.prepare("SELECT COUNT(*) AS count FROM audit_identity_keys").get()).toEqual({
count: 0,
});
} finally {
try {
db.exec("ROLLBACK");
} finally {
clearSink();
await writer.stop();
}
}
db.exec("ROLLBACK");
clearSink();
await writer.stop();
expect(errors).toEqual([]);
expect(errors).toEqual(["audit event queue is full (2); dropping metadata"]);
expect(listAuditEvents({ database, limit: 10 }).events).toHaveLength(2);
expect(
inspectExecutionIdentityRun({ runId: "held-lock-run" }, { ...database, now: admittedAt }),
).toMatchObject({
@@ -212,7 +225,7 @@ describe("audit event worker", () => {
}
});
it("prunes expired identity contexts at startup without a new run", async () => {
it("prunes expired identity contexts before preserving exact-envelope conflicts", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
persistExecutionIdentityAdmissionEnvelope(
@@ -232,54 +245,11 @@ describe("audit event worker", () => {
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
await writer.ready;
expect(
openOpenClawStateDatabase(database)
.db.prepare("SELECT COUNT(*) AS count FROM execution_identity_contexts")
.get(),
).toEqual({ count: 0 });
await writer.stop();
expect(errors).toEqual([]);
});
it("uses one pending limit across audit events and identity envelopes", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const { db } = openOpenClawStateDatabase(database);
db.exec("BEGIN IMMEDIATE");
const errors: string[] = [];
const writer = createAuditEventWriter({
stateDir,
maxPending: 1,
onError: (error) => errors.push(error),
});
expect(writer.record(input())).toBe(true);
expect(
writer.recordExecutionIdentity(
captureWork(
captureExecutionIdentityAdmissionEnvelope(
{
runId: "queue-full-run",
agentId: "main",
ingress: { kind: "local-cli", boundary: "agent-command.local" },
runtime: { kind: "embedded" },
},
{ runtimeInstanceId: "runtime-1" },
),
),
),
).toBe(false);
expect(errors).toContain("audit event queue is full (1); dropping metadata");
db.exec("ROLLBACK");
await writer.stop();
expect(listAuditEvents({ database, limit: 10 }).events).toHaveLength(1);
});
it("preserves exact-envelope idempotency and safely reports every canonical conflict", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
const admittedAt = Date.now();
const original = captureExecutionIdentityAdmissionEnvelope(
{
@@ -363,32 +333,6 @@ describe("audit event worker", () => {
}
});
it("reports a lost durable recovery reference safely without blocking the caller", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
const token = createExecutionIdentityAdmissionToken("raw-run-not-a-secret", {
contextId: "context-missing",
executionId: "execution-missing",
now: 100,
});
const startedAt = performance.now();
expect(writer.recordExecutionIdentity({ kind: "retry-reference", token })).toBe(true);
expect(performance.now() - startedAt).toBeLessThan(250);
await writer.stop();
expect(errors).toContain("audit execution identity recovery evidence unavailable");
expect(JSON.stringify(errors)).not.toContain(token.contextId);
expect(JSON.stringify(errors)).not.toContain(token.executionId);
expect(JSON.stringify(errors)).not.toContain(token.runId);
expect(
openOpenClawStateDatabase({ env: { OPENCLAW_STATE_DIR: stateDir } })
.db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?")
.get("execution_identity_contexts"),
).toBeUndefined();
});
it("keeps unavailable worker, schema, and insert failures off the admission path", async () => {
const envelope = captureExecutionIdentityAdmissionEnvelope(
{
@@ -470,12 +414,29 @@ describe("audit event worker", () => {
).toMatchObject({ state: "unknown", reasonCode: "run_not_found" });
});
it("keeps malformed, serialization, key, and persistence failures nonblocking and redaction-safe", async () => {
it("keeps malformed, serialization, and key failures nonblocking and redaction-safe", async () => {
const stateDir = tempDirs.make("openclaw-audit-writer-");
const database = { env: { OPENCLAW_STATE_DIR: stateDir } };
const errors: string[] = [];
const writer = createAuditEventWriter({ stateDir, onError: (error) => errors.push(error) });
const rawSecret = "raw-worker-message-secret";
persistExecutionIdentityAdmissionEnvelope(
captureExecutionIdentityAdmissionEnvelope(
{
runId: "before-key-loss",
agentId: "main",
ingress: { kind: "local-cli", boundary: "agent-command.local" },
runtime: { kind: "embedded" },
},
{ runtimeInstanceId: "runtime-1" },
),
database,
);
openOpenClawStateDatabase(database).db.exec("DELETE FROM audit_identity_keys;");
closeOpenClawStateDatabaseForTest();
const errors: string[] = [];
const writer = createAuditEventWriter({
stateDir,
onError: (error) => errors.push(error),
});
const unserializable = {
...captureExecutionIdentityAdmissionEnvelope(
{
@@ -494,42 +455,9 @@ describe("audit event worker", () => {
},
};
expect(writer.recordExecutionIdentity(captureWork(unserializable as never))).toBe(false);
await writer.stop();
expect(errors).toContain("audit execution identity envelope could not be queued");
expect(JSON.stringify(errors)).not.toContain(rawSecret);
const malformedErrors: string[] = [];
const malformedWriter = createAuditEventWriter({
stateDir,
onError: (error) => malformedErrors.push(error),
});
expect(malformedWriter.recordExecutionIdentity({ rawSecret } as never)).toBe(true);
await malformedWriter.stop();
expect(malformedErrors).toContain("audit execution identity envelope rejected");
expect(JSON.stringify(malformedErrors)).not.toContain(rawSecret);
closeOpenClawStateDatabaseForTest();
persistExecutionIdentityAdmissionEnvelope(
captureExecutionIdentityAdmissionEnvelope(
{
runId: "before-key-loss",
agentId: "main",
ingress: { kind: "local-cli", boundary: "agent-command.local" },
runtime: { kind: "embedded" },
},
{ runtimeInstanceId: "runtime-1" },
),
database,
);
openOpenClawStateDatabase(database).db.exec("DELETE FROM audit_identity_keys;");
closeOpenClawStateDatabaseForTest();
const keyErrors: string[] = [];
const keyWriter = createAuditEventWriter({
stateDir,
onError: (error) => keyErrors.push(error),
});
expect(writer.recordExecutionIdentity({ rawSecret } as never)).toBe(true);
expect(
keyWriter.recordExecutionIdentity(
writer.recordExecutionIdentity(
captureWork(
captureExecutionIdentityAdmissionEnvelope(
{
@@ -543,9 +471,11 @@ describe("audit event worker", () => {
),
),
).toBe(true);
await keyWriter.stop();
expect(keyErrors).toContain("audit execution identity key unavailable");
expect(JSON.stringify(keyErrors)).not.toContain(rawSecret);
await writer.stop();
expect(errors).toContain("audit execution identity envelope could not be queued");
expect(errors).toContain("audit execution identity envelope rejected");
expect(errors).toContain("audit execution identity key unavailable");
expect(JSON.stringify(errors)).not.toContain(rawSecret);
expect(
inspectExecutionIdentityRun({ runId: "after-key-loss" }, database).identity,
).toMatchObject({ state: "unknown", reasonCode: "run_not_found" });