Files
MikrotikManager/backend/src/services/ospf-cost-optimization.test.ts
T

43 lines
3.4 KiB
TypeScript

import assert from "node:assert/strict"
import { captureOspfOptimizationSnapshot } from "./ospf-cost-optimization.js"
import { configurationRows, resourceById, ROS_SNAPSHOT_VERSION, type RosSnapshot } from "../modules/mcp/resources.js"
import { fingerprint, McpError } from "../modules/mcp/security.js"
const catalog = [{ ".id": "*A", name: "v2", "router-id": "192.0.2.1", version: "2", vrf: "main", disabled: "false", opaque: "ranking-native-extra" }]
const projected = configurationRows(resourceById("ospf_instance"), catalog)
const fresh: RosSnapshot = { serverId: 1, resource: "ospf_instance", rows: projected, fingerprint: fingerprint(projected), projectionVersion: ROS_SNAPSHOT_VERSION, sourceProof: "a".repeat(64) }
let fences = 0, reads = 0
const authorize = async () => { fences++ }
const read = async (serverId: number, resource: string, beforeRead: () => Promise<unknown> = async () => {}) => {
assert.equal(serverId, 1); assert.equal(resource, "ospf_instance")
assert.equal(beforeRead, authorize, "Live ranking/source fence must reach the real snapshot reader")
await beforeRead(); reads++; await beforeRead()
return fresh
}
const sealed = await captureOspfOptimizationSnapshot(1, "ospf_instance", catalog, authorize, read)
assert.equal(sealed, fresh, "Return the freshly attested snapshot rather than adding metadata to stale ranking rows")
assert.equal(sealed.projectionVersion, ROS_SNAPSHOT_VERSION)
assert.equal(sealed.sourceProof, "a".repeat(64))
assert.equal(fences, 2); assert.equal(reads, 1)
assert.equal(Object.hasOwn(sealed.rows[0], "opaque"), false)
assert.equal(catalog[0].opaque, "ranking-native-extra")
for (const changed of [{ ...catalog[0], "router-id": "192.0.2.2" }, { ...catalog[0], disabled: "true" }, { ...catalog[0], vrf: "other" }, { ...catalog[0], ".id": "*B" }]) {
await assert.rejects(captureOspfOptimizationSnapshot(1, "ospf_instance", [changed], authorize, read), error => error instanceof McpError && error.code === "STATE_CONFLICT")
}
const revoked = async () => { throw new McpError("PERMISSION_DENIED", "Revoked after ranking") }
let nativeReads = 0
await assert.rejects(captureOspfOptimizationSnapshot(1, "ospf_instance", catalog, revoked, async (_serverId, _resource, beforeRead = async () => {}) => {
await beforeRead(); nativeReads++; return fresh
}), error => error instanceof McpError && error.code === "PERMISSION_DENIED")
assert.equal(nativeReads, 0)
for (const resource of ["ospf_neighbor", "ospf_area", "bfd_session"] as const) {
const old = [{ ".id": "*A", ...(resource === "ospf_neighbor" ? { state: "Full", interface: "gre-owned" } : resource === "ospf_area" ? { name: "backbone", instance: "v2", disabled: "false" } : { state: "up", interface: "gre-owned" }) }]
const rows = configurationRows(resourceById(resource), old)
const attested: RosSnapshot = { ...fresh, resource, rows, fingerprint: fingerprint(rows) }
assert.equal(await captureOspfOptimizationSnapshot(1, resource, old, authorize, async () => attested), attested)
const driftedRows = [{ ...rows[0], interface: "foreign" }]
await assert.rejects(captureOspfOptimizationSnapshot(1, resource, old, authorize, async () => ({ ...attested, rows: driftedRows, fingerprint: fingerprint(driftedRows) })), error => error instanceof McpError && error.code === "STATE_CONFLICT")
}
console.log("OSPF evidence capture: fresh v2 source-bound snapshots, exact ranking/identity/dependency projection retained, drift and late revocation rejected without re-attesting old state")