Files
reverse-engineering-anything/src/application/sqlite/SqliteDatabaseService.test.ts
T
gensokyo-dev f801b2fbfd feat(sqlite): make worker deadlines adjustable with recovery guidance (#5818)
Expose a per-call SQLite worker deadline with exact CLI/MCP recovery controls,
parent-owned execution metadata and historical unknown preservation. Keep fixed
resource limits and cleanup admission intact. Share typed cleanup composition
with one captured-output owner and preserve the timeout after cleanup resolves.

Fixes #5812. Follow-up tracking: #5808. Existing CLI test-oracle failure: #5845.

Verified 155 SQLite tests (3 skipped), static/docs/discovery checks, six real
CLI/MCP pairs and 13 actual Codex sessions including four corrected deadline
recoveries. Three pre-dispatch discovery failures remain explicit, not passes.
Review findings include real retained-cleanup and fixture ownership regressions.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 16:45:46 +08:00

240 lines
7.4 KiB
TypeScript

import { expect, it } from "vitest";
import { SqliteDatabaseService } from "./SqliteDatabaseService.js";
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
import { err } from "../../domain/result.js";
import { ok } from "../../domain/result.js";
import { createAnalysisExecution } from "../AnalysisProvider.js";
import { sqliteDatabaseSchema } from "../../domain/sqlite/sqliteDatabase.js";
const fixture = () => ({
artifact: { path: "/selected.db", sha256: "a".repeat(64), bytes: 4096 },
wal: null,
engine: { name: "SQLite", version: "3.50.2" },
worker_timeout_ms: 30_000,
database_encoding: "UTF-8",
schema: {
scope: "inventory",
completeness: "complete",
tables: [],
indexes: [],
views: [],
triggers: [],
},
rows: null,
limitations: [],
});
const execution = (value: unknown) =>
createAnalysisExecution(
value,
{ id: "sqlite", name: "SQLite", version: "3.50.2" },
{
subject: { path: "/selected.db", sha256: "a".repeat(64), format: "file" },
locations: [{ kind: "artifact-path", path: "/selected.db" }],
},
);
it.each([
{ path: "relative.db" },
{ path: "/selected.db", approval: true },
{ path: "/selected.db", row_limit: 1 },
{ path: "/selected.db", table: 1 },
{ path: "/selected.db", table: "data", row_limit: 0 },
{
path: "/selected.db",
table: "data",
row_limit: Number.MAX_SAFE_INTEGER + 1,
},
...[0, -1, 1.5, 2_147_483_648, "1000", null].map((worker_timeout_ms) => ({
path: "/selected.db",
worker_timeout_ms,
})),
])(
"rejects invalid SQLite selection before provider effects: %j",
async (input) => {
const service = new SqliteDatabaseService({
inspect: () => {
throw new Error("Invalid selection must not read a database");
},
});
expect(await service.inspect(input)).toMatchObject({
ok: false,
error: { _tag: "AnalysisInputError" },
});
},
);
it("preserves the selected worker budget in provider input and Evidence", async () => {
const report = { ...fixture(), worker_timeout_ms: 1234 };
const service = new SqliteDatabaseService({
inspect: async (input) => {
expect(input.worker_timeout_ms).toBe(1234);
return ok(execution(report));
},
});
const result = await service.inspect({
path: "/selected.db",
worker_timeout_ms: 1234,
});
if (!result.ok) throw result.error;
expect(result.value.parameters).toMatchObject({ worker_timeout_ms: 1234 });
expect(result.value.normalized_result).toMatchObject({
worker_timeout_ms: 1234,
});
});
it.each([
{ selected: undefined, reported: undefined },
{ selected: undefined, reported: 1234 },
{ selected: 1234, reported: undefined },
{ selected: 1234, reported: 30_000 },
])(
"rejects a missing or changed fresh producer budget: %j",
async ({ selected, reported }) => {
const { worker_timeout_ms: _default, ...report } = fixture();
const service = new SqliteDatabaseService({
inspect: async () =>
ok(
execution({
...report,
...(reported === undefined ? {} : { worker_timeout_ms: reported }),
}),
),
});
expect(
await service.inspect({
path: "/selected.db",
...(selected === undefined ? {} : { worker_timeout_ms: selected }),
}),
).toMatchObject({ ok: false, error: { _tag: "AnalysisOutputError" } });
},
);
it("retains the actual default without inventing an explicit caller selection", async () => {
const service = new SqliteDatabaseService({
inspect: async () => ok(execution(fixture())),
});
const result = await service.inspect({ path: "/selected.db" });
if (!result.ok) throw result.error;
expect(result.value.normalized_result).toMatchObject({
worker_timeout_ms: 30_000,
});
expect(result.value.parameters).not.toHaveProperty("worker_timeout_ms");
});
it("parses historical report omissions as unknown without supplying a default", () => {
const { worker_timeout_ms: _default, ...historical } = fixture();
const parsed = sqliteDatabaseSchema.parse(historical);
expect(parsed).not.toHaveProperty("worker_timeout_ms");
});
it("preserves producer failures and rejects pre-cancelled requests before effects", async () => {
const failure = new AnalysisCapabilityUnavailableError(
"rea-sqlite",
"inspect_sqlite_database",
"Selected worker could not start",
);
const service = new SqliteDatabaseService({
inspect: () => Promise.resolve(err(failure)),
});
expect(await service.inspect({ path: "/selected.db" })).toEqual(err(failure));
const signal = AbortSignal.abort();
const untouched = new SqliteDatabaseService({
inspect: () => {
throw new Error("Cancelled selection must not read a database");
},
});
expect(
await untouched.inspect({ path: "/selected.db" }, { signal }),
).toMatchObject({
ok: false,
error: { _tag: "AnalysisCancelledError" },
});
});
it.each(["path", "digest", "subject", "wal", "table"])(
"rejects producer results with changed caller binding: %s",
async (problem) => {
const value = fixture();
if (problem === "path") value.artifact.path = "/other.db";
if (problem === "digest") value.artifact.sha256 = "b".repeat(64);
const observed = execution({
...value,
...(problem === "wal"
? { wal: { path: "/other.db-wal", sha256: "b".repeat(64), bytes: 32 } }
: {}),
});
const service = new SqliteDatabaseService({
inspect: () =>
Promise.resolve(
ok({
...observed,
...(problem === "subject" ? { subject: null } : {}),
}),
),
});
expect(
await service.inspect({
path: "/selected.db",
...(problem === "table" ? { table: "selected" } : {}),
}),
).toMatchObject({ ok: false, error: { _tag: "AnalysisOutputError" } });
},
);
it("preserves completed observed evidence when cancellation arrives after provider completion", async () => {
const value = fixture();
const service = new SqliteDatabaseService({
inspect: () => Promise.resolve(ok(execution(value))),
});
expect(await service.inspect({ path: "/selected.db" })).toMatchObject({
ok: true,
value: {
confidence: "observed",
subject: {
local_path: "/selected.db",
digest: { sha256: "a".repeat(64) },
},
normalized_result: value,
},
});
const controller = new AbortController();
const cancelled = new SqliteDatabaseService({
inspect: () => {
controller.abort();
return Promise.resolve(ok(execution(value)));
},
});
expect(
await cancelled.inspect(
{ path: "/selected.db" },
{ signal: controller.signal },
),
).toMatchObject({
ok: true,
value: { normalized_result: value },
});
});
it("preserves the exact caller reason when inspection is already aborted", async () => {
const reason = Object.freeze({ requested: "stop" });
const controller = new AbortController();
controller.abort(reason);
let calls = 0;
const service = new SqliteDatabaseService({
inspect: () => {
calls += 1;
return Promise.reject(new Error("provider must not run"));
},
});
const result = await service.inspect(
{ path: "/selected.db" },
{ signal: controller.signal },
);
expect(result.ok).toBe(false);
if (result.ok) return;
expect(result.error._tag).toBe("AnalysisCancelledError");
expect(result.error.cause).toBe(reason);
expect(calls).toBe(0);
});