feat(mcp): подготовить сервер и доступ к приёмке
This commit is contained in:
commit
bf3d50e1ff
3835 files changed
+537122
No files matched your search
@@ -0,0 +1,119 @@
|
||||
/** Permanent owned PostgreSQL regression candidate. No source-capture TMP
|
||||
* module, app config, application pool or dotenv import is needed. */
|
||||
import assert from "node:assert/strict"
|
||||
import { randomUUID } from "node:crypto"
|
||||
import { basename, resolve } from "node:path"
|
||||
import { pathToFileURL } from "node:url"
|
||||
import { Pool, type PoolClient } from "pg"
|
||||
assert.equal(process.env.MMAPP_OWN_IMPORT_CONTROL, "true")
|
||||
assert(process.env.MMAPP_OWN_IMPORT_DIRECTORY && basename(process.env.MMAPP_OWN_IMPORT_DIRECTORY).startsWith("mm-import-control-"))
|
||||
const adminUrl = new URL(process.env.MMAPP_OWN_IMPORT_ADMIN_URL ?? "")
|
||||
assert.equal(adminUrl.hostname, "127.0.0.1"); assert.equal(adminUrl.pathname, "/postgres")
|
||||
assert.equal(process.env.DATABASE_URL, undefined)
|
||||
// The candidate runner can point at the real repository while this test stays
|
||||
// in TMP. Once integrated, relative production source is the default.
|
||||
const sourceRoot = process.env.MMAPP_OWN_IMPORT_SOURCE_ROOT
|
||||
const source = (relative: string, ownRelative: string) => sourceRoot ? pathToFileURL(resolve(sourceRoot, "backend/src", relative)).href : new URL(ownRelative, import.meta.url).href
|
||||
const { withPartitionWrite, PARTITION_WRITER_ADVISORY_KEY, isPartitionWriteOutcomeUnknown } = await import(source("services/partition-write-transaction.ts", "../services/partition-write-transaction.js"))
|
||||
const { writeSqliteImportMarker, resetSqliteImportSequence } = await import(source("db/sqlite-import-control-writes.ts", "./sqlite-import-control-writes.js"))
|
||||
const admin = new Pool({ connectionString: adminUrl.toString(), max: 2 })
|
||||
const name = "import_control_" + randomUUID().replaceAll("-", "")
|
||||
assert(/^import_control_[a-f0-9]{32}$/.test(name))
|
||||
await admin.query('CREATE DATABASE "' + name + '" TEMPLATE template0')
|
||||
const target = new URL(adminUrl); target.pathname = "/" + name
|
||||
const pool = new Pool({ connectionString: target.toString(), max: 8, connectionTimeoutMillis: 3000 })
|
||||
const held: PoolClient[] = [], releases: (() => void)[] = [], cases: string[] = []
|
||||
async function until(check: () => Promise<boolean>) {
|
||||
const end = performance.now() + 4000
|
||||
while (!await check()) { if (performance.now() >= end) throw Error("Owned lock state not observed"); await new Promise(r => setTimeout(r, 10)) }
|
||||
}
|
||||
function fault(mode: "lost-commit" | "aborted-commit" | "rollback-after-setval") {
|
||||
const commands: string[] = [], destroyed: boolean[] = []
|
||||
let commitTag: string | undefined
|
||||
const adapted = { async connect() { const client = await pool.connect(); return {
|
||||
release(destroy = false) { destroyed.push(destroy); client.release(destroy) }, async query(text: string, values?: unknown[]) {
|
||||
commands.push(text)
|
||||
if (text === "COMMIT" && mode === "aborted-commit") await assert.rejects(client.query("SELECT 1/0"), (e: unknown) => !!e && typeof e === "object" && "code" in e && e.code === "22012")
|
||||
const result = await client.query(text, values)
|
||||
if (text === "COMMIT") commitTag = result.command
|
||||
if (text === "COMMIT" && mode === "lost-commit") throw Error("Owned fixture loses actual COMMIT ACK")
|
||||
if (text.startsWith("SELECT pg_catalog.setval") && mode === "rollback-after-setval") {
|
||||
assert.equal((await client.query("ROLLBACK")).command, "ROLLBACK")
|
||||
throw Error("Owned fixture reports failure after actual setval and acknowledged ROLLBACK")
|
||||
}
|
||||
return result
|
||||
},
|
||||
} } } as unknown as Pool
|
||||
return { pool: adapted, commands, destroyed, tag: () => commitTag }
|
||||
}
|
||||
async function lastSequence() { return (await pool.query("SELECT last_value::text AS value FROM public.import_rows_id_seq")).rows[0].value }
|
||||
async function markerPath() { return (await pool.query("SELECT sqlite_path FROM public.data_migration WHERE id=1")).rows[0].sqlite_path }
|
||||
try {
|
||||
await pool.query("CREATE TABLE public.data_migration(id integer PRIMARY KEY,sqlite_imported_at timestamptz,sqlite_path text,sqlite_sha256 text,report_json jsonb); INSERT INTO public.data_migration(id) VALUES(1); CREATE TABLE public.import_rows(id bigserial PRIMARY KEY); INSERT INTO public.import_rows(id) VALUES(42); CREATE TABLE public.no_sequence(id integer PRIMARY KEY)")
|
||||
const exclusive = await pool.connect(); held.push(exclusive)
|
||||
await exclusive.query("SELECT pg_advisory_lock($1::bigint)", [PARTITION_WRITER_ADVISORY_KEY])
|
||||
const marker = writeSqliteImportMarker(pool, "owned.sqlite", "a".repeat(64), JSON.stringify({ import_rows: { copied: 1 } }))
|
||||
const sequence = resetSqliteImportSequence(pool, "import_rows")
|
||||
await until(async () => (await pool.query("SELECT count(*)::int AS n FROM pg_locks WHERE locktype='advisory' AND objid=$1::oid AND NOT granted", [PARTITION_WRITER_ADVISORY_KEY])).rows[0].n === 2)
|
||||
assert.equal(await markerPath(), null); assert.equal(await lastSequence(), "1")
|
||||
assert.equal((await exclusive.query("SELECT pg_advisory_unlock($1::bigint) AS unlocked", [PARTITION_WRITER_ADVISORY_KEY])).rows[0].unlocked, true)
|
||||
await marker; assert.equal(await sequence, "sequence-set"); assert.equal(await lastSequence(), "42")
|
||||
const saved = (await pool.query("SELECT sqlite_path,sqlite_sha256,report_json FROM public.data_migration WHERE id=1")).rows[0]
|
||||
assert.equal(saved.sqlite_path, "owned.sqlite"); assert.equal(saved.sqlite_sha256, "a".repeat(64)); assert.deepEqual(saved.report_json, { import_rows: { copied: 1 } })
|
||||
cases.push("marker and setval use same real shared admission before SQL, wait for exclusive drain and preserve values")
|
||||
assert.equal(await resetSqliteImportSequence(pool, "no_sequence"), "sequence-absent")
|
||||
cases.push("absent serial identity is explicit compatibility no-op")
|
||||
|
||||
let entered!: () => void, release!: () => void
|
||||
const ready = new Promise<void>(r => { entered = r }), waiting = new Promise<void>(r => { release = r }); releases.push(release)
|
||||
const writer = withPartitionWrite(async ({ client }: { client: PoolClient }) => { await client.query("UPDATE public.data_migration SET sqlite_path='already-admitted' WHERE id=1"); entered(); await waiting }, { connect: () => pool.connect() })
|
||||
await ready
|
||||
const drain = exclusive.query("SELECT pg_advisory_lock($1::bigint)", [PARTITION_WRITER_ADVISORY_KEY])
|
||||
await until(async () => (await pool.query("SELECT EXISTS(SELECT 1 FROM pg_locks WHERE locktype='advisory' AND objid=$1::oid AND NOT granted) AS waiting", [PARTITION_WRITER_ADVISORY_KEY])).rows[0].waiting === true)
|
||||
release(); await writer; await drain; assert.equal(await markerPath(), "already-admitted")
|
||||
await exclusive.query("SELECT pg_advisory_unlock($1::bigint)", [PARTITION_WRITER_ADVISORY_KEY])
|
||||
cases.push("exclusive drain waits for already-admitted writer COMMIT")
|
||||
|
||||
const lostMarker = fault("lost-commit")
|
||||
await assert.rejects(writeSqliteImportMarker(lostMarker.pool, "lost-ack.sqlite", "b".repeat(64), "{}"), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(lostMarker.tag(), "COMMIT"); assert.equal(await markerPath(), "lost-ack.sqlite")
|
||||
assert.equal(lostMarker.commands.filter(q => q.startsWith("UPDATE data_migration")).length, 1); assert.equal(lostMarker.commands.filter(q => q === "COMMIT").length, 1)
|
||||
assert(!lostMarker.commands.includes("ROLLBACK")); assert.deepEqual(lostMarker.destroyed, [true])
|
||||
cases.push("lost actual marker COMMIT ACK is UNKNOWN, one update and no second transition/replay")
|
||||
|
||||
await pool.query("INSERT INTO public.import_rows(id) VALUES(77)")
|
||||
const lostSequence = fault("lost-commit")
|
||||
await assert.rejects(resetSqliteImportSequence(lostSequence.pool, "import_rows"), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(await lastSequence(), "77"); assert.equal(lostSequence.commands.filter(q => q.startsWith("SELECT pg_catalog.setval")).length, 1)
|
||||
cases.push("lost actual sequence COMMIT ACK propagates UNKNOWN with setval already visible and no replay")
|
||||
|
||||
await pool.query("INSERT INTO public.import_rows(id) VALUES(88)")
|
||||
const rolledSequence = fault("rollback-after-setval")
|
||||
await assert.rejects(resetSqliteImportSequence(rolledSequence.pool, "import_rows"), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(await lastSequence(), "88"); assert.equal(rolledSequence.commands.filter(q => q.startsWith("SELECT pg_catalog.setval")).length, 1)
|
||||
cases.push("acknowledged actual ROLLBACK does not undo setval; post-sequence failure remains UNKNOWN")
|
||||
|
||||
const abortedDml = fault("aborted-commit")
|
||||
await assert.rejects(withPartitionWrite(async ({ client }: { client: PoolClient }) => { await client.query("INSERT INTO public.no_sequence VALUES(999)") }, { connect: () => abortedDml.pool.connect() }), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(abortedDml.tag(), "ROLLBACK"); assert.equal((await pool.query("SELECT count(*)::int AS n FROM public.no_sequence")).rows[0].n, 0)
|
||||
assert.equal(abortedDml.commands.filter(q => q === "COMMIT").length, 1); assert(!abortedDml.commands.includes("ROLLBACK")); assert.deepEqual(abortedDml.destroyed, [true])
|
||||
cases.push("real aborted DML COMMIT resolves ROLLBACK and is refused without success/retry/second transition")
|
||||
const abortedMarker = fault("aborted-commit")
|
||||
await assert.rejects(writeSqliteImportMarker(abortedMarker.pool, "must-not-publish.sqlite", "c".repeat(64), "{}"), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(abortedMarker.tag(), "ROLLBACK"); assert.equal(await markerPath(), "lost-ack.sqlite")
|
||||
cases.push("real aborted marker COMMIT=>ROLLBACK cannot publish success")
|
||||
await pool.query("INSERT INTO public.import_rows(id) VALUES(99)")
|
||||
const abortedSequence = fault("aborted-commit")
|
||||
await assert.rejects(resetSqliteImportSequence(abortedSequence.pool, "import_rows"), isPartitionWriteOutcomeUnknown)
|
||||
assert.equal(abortedSequence.tag(), "ROLLBACK"); assert.equal(await lastSequence(), "99")
|
||||
cases.push("real aborted setval COMMIT=>ROLLBACK refuses success while sequence effect honestly remains")
|
||||
await assert.rejects(resetSqliteImportSequence(pool, "missing_import_table"))
|
||||
cases.push("non-compatibility SQL errors propagate; blanket catch and replay absent")
|
||||
console.log(JSON.stringify({ cases: cases.length, names: cases, actualSql: true, genuineCommitRollbackCases: 3,
|
||||
actualCurrentProductionPartitionWriter: true, actualCurrentProductionImporterHelpers: true, sourceCaptureTmpDependency: false,
|
||||
allWriterDrainAuthenticated: false, readyAuthorized: false, productionDatabaseTouched: false, hostUsersGroupsServicesChanged: false }, null, 2))
|
||||
} finally {
|
||||
for (const release of releases) release()
|
||||
for (const c of held) c.release(true)
|
||||
await pool.end(); await admin.query('DROP DATABASE "' + name + '" WITH (FORCE)'); await admin.end()
|
||||
}
|
||||
Reference in new issue
Block a user