Files
MikrotikManager/backend/src/services/bandwidth-operator-peer-source-composition.test.ts
T

100 lines
8.1 KiB
TypeScript

/** Real signed original/window/guard/coordinator + localhost license GET.
* Registry and SQL session are explicit inert models; no PG/Docker/Q proof. */
import assert from "node:assert/strict"
import { createHash, generateKeyPairSync, randomUUID, sign } from "node:crypto"
import { once } from "node:events"
import { createServer } from "node:http"
import { mkdtemp, realpath, rm, writeFile } from "node:fs/promises"
import { tmpdir } from "node:os"
import { dirname, join } from "node:path"
import { mock, test } from "node:test"
import type { createBandwidthOperatorRegistry } from "./bandwidth-operator-registry.js"
import { assertBandwidthOperatorPeerSourceGuard, type BandwidthOperatorPeerSourceGuard } from "./bandwidth-operator-writer-window.js"
import { bandwidthOperatorEnrollmentGrantSchema } from "./bandwidth-operator-enrollment.js"
import { canonicalBandwidthNodeValue } from "./bandwidth-node-bootstrap.js"
import type { BandwidthPeerSourceSnapshot } from "./bandwidth-peer-observation.js"
import type { BandwidthOperatorWriterCompositionDependencies } from "./bandwidth-operator-writer-composition.js"
type RegistryDependencies = Parameters<typeof createBandwidthOperatorRegistry>[0]
let counters = () => ({ q: 0, sql: 0 })
mock.module("./bandwidth-operator-registry.js", { namedExports: {
createBandwidthOperatorRegistry(deps: RegistryDependencies) {
return { async register(token: unknown, scope: { deadlineAt: number }) {
const check = async () => { await deps.coordinator.inspect(token, scope) }
const borrowed = await deps.source.open(scope, check)
const before = counters(), metadata = await deps.coordinator.inspectMetadata(token, scope)
assert.equal(metadata.format, "mmapp-bandwidth-operator-enrollment-metadata-v1"); assert.deepEqual(counters(), before)
await borrowed.connection.query("BEGIN"); await borrowed.connection.query("COMMIT"); borrowed.connection.release(true)
return { enrollmentId: "synthetic", canonicalNodeId: randomUUID(), incarnation: randomUUID(), status: "active", outcome: "new" }
} }
},
} })
test("constructor factory gets genuine guard only inside held registry window", async () => {
const root = await realpath(tmpdir()), folder = await mkdtemp(join(root, "bw-peer-source-compose-")), keys = generateKeyPairSync("ed25519")
let nativeGets = 0, factoryCalls = 0, sourceCloses = 0, q = 0, sql = 0, held = false, physicalCloses = 0
const events: string[] = []
const server = createServer((request, response) => {
nativeGets++; assert.equal(request.url, "/rest/system/license"); assert.equal(request.method, "GET")
assert.equal(request.headers.authorization, "Basic " + Buffer.from("synthetic-compose:synthetic-private").toString("base64"))
response.writeHead(200, { "content-type": "application/json" }); response.end('{"system-id":"SYNTHETIC-COMPOSE"}')
})
server.listen(0, "127.0.0.1"); await once(server, "listening")
const address = server.address(); assert(address && typeof address !== "string")
const trustKeyFile = join(folder, "operator.pub"), grantFile = join(folder, "grant.json"), peerRef = { kind: "external" as const, enrollmentId: randomUUID() }
const rootFields = { installationId: randomUUID(), issuerKeySha256: "a".repeat(64), quiescenceProof: "b".repeat(64) }
const expected: BandwidthPeerSourceSnapshot = { peerRef, enabled: true, sourceProof: "c".repeat(64), authorityGeneration: "original-compose-source", endpoint: {
host: "127.0.0.1", port: address.port, useSsl: false, verifySsl: true, username: "synthetic-compose", password: "synthetic-private", routingEndpointEpoch: randomUUID() } }
const grant = bandwidthOperatorEnrollmentGrantSchema.parse({ format: "mmapp-bandwidth-operator-enrollment-v1", ...rootFields, grantId: randomUUID(), operatorId: "synthetic-compose",
executorInventorySha256: "d".repeat(64), executorsStoppedAt: Date.now() - 2000, issuedAt: Date.now() - 1000, expiresAt: Date.now() + 60000,
peerRef, sourceProof: expected.sourceProof, authorityGeneration: expected.authorityGeneration, routingEndpointEpoch: expected.endpoint.routingEndpointEpoch,
claims: [{ kind: "system-id", value: "SYNTHETIC-COMPOSE" }] })
const binding = { peerRef, sourceProof: expected.sourceProof, authorityGeneration: expected.authorityGeneration, routingEndpointEpoch: expected.endpoint.routingEndpointEpoch }
const payload = Buffer.from(canonicalBandwidthNodeValue(grant)); await writeFile(trustKeyFile, keys.publicKey.export({ type: "spki", format: "pem" }))
await writeFile(grantFile, JSON.stringify({ format: "mmapp-bandwidth-operator-enrollment-envelope-v1", payload: payload.toString("base64url"), signature: sign(null, payload, keys.privateKey).toString("base64url") }))
const config = { ...rootFields, trustKeyFile, grantFile, trustKeySha256: createHash("sha256").update(keys.publicKey.export({ type: "spki", format: "der" })).digest("hex") }
let retained: BandwidthOperatorPeerSourceGuard | undefined
const sourceOpen = async (_scope: unknown, guard: () => Promise<void>) => {
events.push("open"); await guard()
let closed = false
const lifetime = new AbortController()
return { async binding() { await guard(); return rootFields }, async keyedProof() { throw Error("No key in composition fixture") },
close() { if (!closed) { closed = true; lifetime.abort(); held = false; physicalCloses++ } }, connection: {
lifetimeSignal: lifetime.signal,
release() { throw Error("Owner closes physical session") }, async query(text: string) {
await guard(); sql++; events.push(text)
if (text.includes("pg_try_advisory_lock")) { held = true; return { rows: [{ acquired: true }] } }
if (text.includes("pg_locks")) return { rows: [{ held, backend_pid: 777 }] }
if (text.includes("pg_backend_pid()")) return { rows: [{ backend_pid: 777 }] }
return { rows: [], command: text }
},
} }
}
const dependencies: BandwidthOperatorWriterCompositionDependencies = { config, nodeSource: { open: sourceOpen, openWithOwnershipFence: sourceOpen } as never,
externalStop: { async acquire() { return { async assertCurrent() { q++ }, close() {} } } },
createObservationSource(guard) {
factoryCalls++; events.push("factory"); assert(held); assertBandwidthOperatorPeerSourceGuard(guard); retained = guard
assert(events.some(event => event.includes("pg_backend_pid()")))
return { async read(_peer, requested) { await guard.verifyRead(binding, requested); return expected },
async assertMetadataCurrent(privateExpected, scope) { await guard.verifyMetadata(binding, scope); assert.deepEqual(privateExpected, expected) }, close() { sourceCloses++ } }
} }
const { createBandwidthOperatorWriterComposition } = await import("./bandwidth-operator-writer-composition.js")
const composition = createBandwidthOperatorWriterComposition(dependencies)
counters = () => ({ q, sql })
try {
assert.equal(factoryCalls + nativeGets + sql + q, 0)
assert.throws(() => createBandwidthOperatorWriterComposition({ ...dependencies, observationSource: { async read() { return expected } } }))
assert.throws(() => createBandwidthOperatorWriterComposition({ config, nodeSource: dependencies.nodeSource, externalStop: dependencies.externalStop }))
dependencies.createObservationSource = () => { throw Error("Replacement callback must not run") }
await assert.rejects(composition.register({ deadlineAt: Date.now() + 4000, createObservationSource: () => expected } as never)); assert.equal(factoryCalls, 0)
await composition.register({ deadlineAt: Date.now() + 4000 })
assert.equal(factoryCalls, 1); assert.equal(sourceCloses, 1); assert.equal(nativeGets, 1); assert.equal(physicalCloses, 1)
assert(events.indexOf("factory") > events.findIndex(event => event.includes("pg_try_advisory_lock")))
assert(retained); assert.throws(() => assertBandwidthOperatorPeerSourceGuard(retained))
} finally {
composition.close(); server.closeAllConnections(); server.close(); await once(server, "close")
const { closePool } = await import("../db/index.js"); await closePool()
assert.equal(dirname(await realpath(folder)), root); await rm(folder, { recursive: true, force: true })
}
})