Files
MikrotikManager/backend/src/services/bandwidth-native-dispatch-source.test.ts
T

71 lines
6.9 KiB
TypeScript

import assert from "node:assert/strict"
import { createHmac, randomUUID } from "node:crypto"
import { test } from "node:test"
import { createBandwidthNativeDispatchSqlGate } from "./bandwidth-native-dispatch-source.js"
import type { BandwidthBinding } from "./bandwidth-admission.js"
import type { BandwidthControlDispatchFence } from "./bandwidth-control-source.js"
test("fixed native SQL producer uses one authenticated lease; no DML, replay or released continuation (fake SQL only)", async () => {
const binding: BandwidthBinding = { attemptId: randomUUID(), callerKind: "mcp-speed", operationId: "original", source: { canonicalNodeId: randomUUID(), endpointProof: "a".repeat(64) }, destination: { canonicalNodeId: randomUUID(), endpointProof: "b".repeat(64) },
authorityProof: "c".repeat(64), authorityGeneration: "actor", controlGeneration: "source", expiresAt: Date.now() + 60000, durationSec: 3, requestProof: "d".repeat(64), commandProof: "e".repeat(64), bindingProof: "f".repeat(64) }
const mac = (value: unknown) => createHmac("sha256", "synthetic-unit-only").update(JSON.stringify(value)).digest("hex")
for (const corruption of ["none", "longer-original", "row", "owner", "extra-owner", "missing-event", "event-mac", "event-shape", "registry-lock", "owner-lock", "authority", "abort", "begin-rows-only", "smaller-scope", "concurrent-verify"]) {
let checkouts = 0, destroys = 0, checks = 0, macReads = 0, transaction = false, revoked = false, released = false
const sql: string[] = [], controller = new AbortController(), scope = { deadlineAt: Date.now() + (corruption === "longer-original" ? 10000 : 3000), signal: controller.signal }
const row = { attempt_id: binding.attemptId, binding, caller_kind: binding.callerKind, operation_id: binding.operationId, state: "armed", source_node: binding.source.canonicalNodeId, destination_node: binding.destination.canonicalNodeId,
binding_proof: binding.bindingProof, control_generation: binding.controlGeneration, resolution: null, terminal_proof: null }
const owners = [binding.source.canonicalNodeId, binding.destination.canonicalNodeId].sort().map(node_id => ({ node_id, attempt_id: binding.attemptId, binding_proof: binding.bindingProof, control_generation: binding.controlGeneration }))
const events = ["reserve", "arm"].map(transition => {
const ack_id = randomUUID(), old_state = transition === "reserve" ? null : "reserved", new_state = transition === "reserve" ? "reserved" : "armed"
return { ack_id, attempt_id: binding.attemptId, binding_proof: binding.bindingProof, control_generation: binding.controlGeneration, transition, old_state, new_state,
evidence_proof: mac({ ackId: ack_id, attemptId: binding.attemptId.toLowerCase(), transition, oldState: old_state, newState: new_state, bindingProof: binding.bindingProof, controlGeneration: binding.controlGeneration, terminalProof: null }) }
})
let guard: ((fence: BandwidthControlDispatchFence) => Promise<void>) | undefined
const fence = {} as BandwidthControlDispatchFence
const physical = { async query(text: string) {
assert(!released); sql.push(text)
assert(!/\b(?:INSERT|UPDATE|DELETE|COMMIT|ROLLBACK)\b/.test(text), "fixed producer never writes or commits")
await guard?.(fence)
let rows: Record<string, unknown>[] = []
if (text === "BEGIN") transaction = true
else if (text.includes("AS locked")) { assert(transaction); rows = [{ locked: !(text.includes("8723116") && corruption === "registry-lock" || text.includes("764301") && corruption === "owner-lock") }] }
else if(text.includes("/* bandwidth-native:armed-snapshot */"))rows=[{
attempt:{...row,...(corruption==="row"?{state:"unknown_busy"}:{})},
owners:corruption==="extra-owner"?[...owners,owners[0]]:corruption==="owner"?[{...owners[0],binding_proof:"0".repeat(64)},owners[1]]:owners,
events:corruption==="missing-event"?events.slice(0,1):events.map((event,index)=>({...event,...(index===0&&corruption==="event-mac"?{evidence_proof:"0".repeat(64)}:{}),...(index===0&&corruption==="event-shape"?{old_state:"armed"}:{})})),
}]
else if (text.includes("FROM mmapp_control.bandwidth_attempts")) rows = [{ ...row, ...(corruption === "row" ? { state: "unknown_busy" } : {}) }]
else if (text.includes("FROM mmapp_control.bandwidth_node_occupancy")) rows = corruption === "extra-owner" ? [...owners, owners[0]] : corruption === "owner" ? [{ ...owners[0], binding_proof: "0".repeat(64) }, owners[1]] : owners
else if (text.includes("FROM mmapp_control.bandwidth_attempt_events")) rows = corruption === "missing-event" ? events.slice(0, 1) : events.map((event, index) => ({ ...event, ...(index === 0 && corruption === "event-mac" ? { evidence_proof: "0".repeat(64) } : {}), ...(index === 0 && corruption === "event-shape" ? { old_state: "armed" } : {}) }))
await guard?.(fence)
return { rows, ...(corruption === "begin-rows-only" ? {} : { command: text === "BEGIN" ? "BEGIN" : "SELECT" }) }
}, release(unsafe?: boolean) { assert.equal(unsafe, true); assert(!released); released = true; destroys++ } }
const core = {
async connect(_scope: unknown, supplied?: (fence: BandwidthControlDispatchFence) => Promise<void>) { checkouts++; assert.equal(checkouts, 1); guard = supplied; return physical },
async eventProofOnConnection(value: unknown, connection: unknown) { assert.equal(connection, physical); macReads++; await physical.query("SELECT 1"); return mac(value) },
}
const gate = createBandwidthNativeDispatchSqlGate(core as never, binding, async () => { assert(transaction); checks++; if (revoked) throw Error("revoked original authority") })
let lease: Awaited<ReturnType<typeof gate.acquire>> | undefined
try {
if (["registry-lock", "owner-lock", "begin-rows-only"].includes(corruption)) { await assert.rejects(gate.acquire(scope)); continue }
lease = await gate.acquire(scope)
if (corruption === "authority") revoked = true
if (corruption === "abort") controller.abort()
if (corruption === "none" || corruption === "longer-original") {
await lease.verify(scope); await lease.verify(scope)
assert.equal(macReads, 4); assert(checks > 0); assert(!released)
assert(sql.some(text => text.includes("/* bandwidth-native:armed-snapshot */")&&text.includes("FOR SHARE NOWAIT")))
const locks = sql.filter(text => text.includes("764301")); assert.equal(locks.length, 2)
} else if (corruption === "smaller-scope") await assert.rejects(lease.verify({ ...scope, deadlineAt: scope.deadlineAt - 1 }))
else if (corruption === "concurrent-verify") {
const first = lease.verify(scope)
await Promise.all([assert.rejects(first), assert.rejects(lease.verify(scope))])
} else await assert.rejects(lease.verify(scope))
} finally {
lease?.close(); assert.equal(destroys, 1); assert.equal(checkouts, 1)
if (lease) await assert.rejects(lease.verify(scope))
await assert.rejects(gate.acquire(scope))
}
}
})