import assert from "node:assert/strict" import { test } from "node:test" import { McpError } from "../modules/mcp/security.js" import type { ProbeStorageSql } from "../services/server-probe-journal-maintenance.js" import { captureDatabaseSourceObservation, assertDatabaseSourceObservationCurrent } from "./database-source-observation.js" const options = () => ({ deadlineAt: Date.now() + 2000 }) const row = (): Record => ({ system_identifier: "18446744073709551615", database_oid: "16384", database_name: "fixture", session_user: "operator", current_user: "operator", in_recovery: false, server_version_num: "180006", backend_pid: 1234, transaction_timestamp: "2026-10-25 12:34:56.123456+00", snapshot: "100:110:101,105,109", isolation: "repeatable read", read_only: "on", explicit_transaction: true }) function fixture(rows: Record[][] = [[row()]]) { const calls: { text: string; timeout: number; signal?: AbortSignal }[] = [] const sql: ProbeStorageSql = { async query(text, values, queryOptions) { assert.deepEqual(values, []); assert(queryOptions) calls.push({ text, timeout: queryOptions.timeoutMs, signal: queryOptions.signal }) return { rows: rows[Math.min(calls.length - 1, rows.length - 1)] } } } return { sql, calls } } const safe = (error: unknown) => error instanceof McpError && error.message === "Текущий источник и снимок БД не подтверждены" test("fixed genuine facts are immutable, exact and explicitly lack generation authority", async () => { const f = fixture(), observation = await captureDatabaseSourceObservation(f.sql, options()) assert.equal(observation.source.systemIdentifier, "18446744073709551615") assert.equal(observation.source.databaseOid, 16384) assert.equal(observation.snapshot.transactionTimestamp, "2026-10-25 12:34:56.123456+00") assert.equal(observation.ready, false); assert.equal(observation.generationAuthenticated, false); assert.equal(observation.requiresExternalSourceBinding, true) assert(Object.isFrozen(observation)); assert(Object.isFrozen(observation.source)); assert(Object.isFrozen(observation.snapshot)) assert.equal(f.calls.length, 2) assert(f.calls.every(call => call.timeout >= 1 && call.timeout <= 10000)) assert(f.calls[0].text.includes("pg_catalog.pg_control_system()")); assert(f.calls[0].text.includes("pg_catalog.pg_current_snapshot()")) assert(!/\b(BEGIN|COMMIT|ROLLBACK|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|pg_export_snapshot)\b/i.test(f.calls[0].text)) await assertDatabaseSourceObservationCurrent(f.sql, observation, options()); assert.equal(f.calls.length, 3) }) test("every source or transaction dimension drifting between reads is refused", async t => { const changes: Record = { system_identifier: "9223372036854775808", database_oid: "16385", database_name: "other", session_user: "another", current_user: "another", in_recovery: true, server_version_num: "180007", backend_pid: 1235, transaction_timestamp: "2026-10-25 12:34:56.123457+00", snapshot: "100:111:101,105,109" } for (const [key, value] of Object.entries(changes)) await t.test(key, async () => { const f = fixture([[row()], [{ ...row(), [key]: value }]]) await assert.rejects(captureDatabaseSourceObservation(f.sql, options()), safe) }) }) test("same-lease verifier rejects changed transaction after fixed data collection", async () => { const f = fixture([[row()], [row()], [{ ...row(), backend_pid: 44 }]]) const observation = await captureDatabaseSourceObservation(f.sql, options()) await assert.rejects(assertDatabaseSourceObservationCurrent(f.sql, observation, options()), safe) }) test("JSON/copies and cross-client source records never establish source binding", async () => { const first = fixture(), second = fixture(), observation = await captureDatabaseSourceObservation(first.sql, options()) await assert.rejects(assertDatabaseSourceObservationCurrent(first.sql, structuredClone(observation), options()), safe) await assert.rejects(assertDatabaseSourceObservationCurrent(first.sql, { ...observation }, options()), safe) await assert.rejects(assertDatabaseSourceObservationCurrent(second.sql, observation, options()), safe) assert.equal(first.calls.length, 2); assert.equal(second.calls.length, 0) }) test("expired or aborted requests perform no SQL", async () => { const f = fixture(), controller = new AbortController(); controller.abort() for (const value of [{ deadlineAt: Date.now() - 1 }, { deadlineAt: NaN }, { ...options(), signal: controller.signal }]) { await assert.rejects(captureDatabaseSourceObservation(f.sql, value), safe) } assert.equal(f.calls.length, 0) }) test("original deadline and signal remain authoritative during later pairing", async () => { const f = fixture(), controller = new AbortController(), original = { deadlineAt: Date.now() + 40, signal: controller.signal } const observation = await captureDatabaseSourceObservation(f.sql, original) controller.abort() await assert.rejects(assertDatabaseSourceObservationCurrent(f.sql, observation, options()), safe) const other = fixture(), deadline = { deadlineAt: Date.now() + 40 } const timed = await captureDatabaseSourceObservation(other.sql, deadline) deadline.deadlineAt += 100000 await new Promise(resolve => setTimeout(resolve, 50)) await assert.rejects(assertDatabaseSourceObservationCurrent(other.sql, timed, options()), safe) assert.equal(f.calls.length, 2); assert.equal(other.calls.length, 2) }) test("strict singleton/schema and explicit RR read-only transaction required", async () => { const missing = row(); delete missing.current_user const variants = [[], [row(), row()], [missing], [{ ...row(), extra: "private" }], [{ ...row(), read_only: "off" }], [{ ...row(), isolation: "read committed" }], [{ ...row(), explicit_transaction: false }], [{ ...row(), backend_pid: 1.5 }], [{ ...row(), in_recovery: "false" }], [{ ...row(), transaction_timestamp: "not a timestamp" }], [{ ...row(), transaction_timestamp: "2026-99-99 12:34:56.123456+00" }], [{ ...row(), server_version_num: "120000" }]] for (const rows of variants) await assert.rejects(captureDatabaseSourceObservation(fixture([rows]).sql, options()), safe) }) test("uint64, OID and snapshot range/order/size validation is fail closed", async () => { const variants = [{ system_identifier: "18446744073709551616" }, { system_identifier: "0" }, { system_identifier: "01" }, { database_oid: "4294967296" }, { database_oid: "0" }, { database_oid: "01" }, { database_oid: "1.1" }, { snapshot: "110:100:" }, { snapshot: "100:110:105,105" }, { snapshot: "100:110:109,105" }, { snapshot: "100:110:99" }, { snapshot: "100:110:110" }, { snapshot: "100:110:0105" }, { snapshot: "100:18446744073709551616:" }, { snapshot: "100:110" }, { snapshot: "100:110::" }, { snapshot: "0:5000:" + Array.from({ length: 4097 }, (_, index) => index).join(",") }, { snapshot: "0:1:" + "1".repeat(65536) }] for (const change of variants) await assert.rejects(captureDatabaseSourceObservation(fixture([[{ ...row(), ...change }]]).sql, options()), safe) const empty = fixture([[{ ...row(), snapshot: "100:100:" }]]) assert.equal((await captureDatabaseSourceObservation(empty.sql, options())).snapshot.snapshot, "100:100:") }) test("provider errors never leak", async () => { const privateSql: ProbeStorageSql = { query: async () => { throw new Error("private-provider password db-url") } } await assert.rejects(captureDatabaseSourceObservation(privateSql, options()), safe) }) test("abort fences after caller-owned SQL settles and prevents a second read", async () => { let resolve!: (value: { rows: Record[] }) => void, queries = 0 const controller = new AbortController() const sql: ProbeStorageSql = { query: () => { queries++; return new Promise(done => { resolve = done }) } } const pending = captureDatabaseSourceObservation(sql, { ...options(), signal: controller.signal }) controller.abort() // Foreign SQL remains caller-owned until it settles; this helper must not // race it and allow a caller to reuse its backend while work is in flight. resolve({ rows: [row()] }); await assert.rejects(pending, safe); assert.equal(queries, 1) })