Files
mesh-lab/test/place.test.ts
T
jschoubben 4097ff92c1 Repoint ADR references after HQ consolidated 65 records to 23
Comments naming records that no longer exist now point at the consolidated
record holding their reasoning -- the four lab records are 0016, a test defends
a decision is 0017.
2026-08-28 23:33:46 +02:00

132 lines
5.3 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import { parseScenario } from "../src/declaration/parse.ts";
import { planPlacements, PLACEABLE, isPlaceable } from "../src/lifecycle/place.ts";
import { assertSupported, UnsupportedError } from "../src/lifecycle/supported.ts";
/**
* `place:` is the seam where the lab stops being infrastructure with no consumer. Each test
* names what it defends, per novox/hq ADR 0017.
*/
function scenario(place: string): ReturnType<typeof parseScenario> {
return parseScenario(`
scenario: placing
segments:
hosting:
kind: public
cidr: [192.0.2.0/24]
machines:
anchor:
at: { segment: hosting, address: [192.0.2.10] }
peer:
at: { segment: hosting, address: [192.0.2.20] }
${place}
`);
}
test("`all:` reaches every machine", () => {
const placements = planPlacements(scenario("place:\n all: [host]"));
assert.deepEqual(
placements.map((p) => p.machine).sort(),
["anchor", "peer"],
);
for (const p of placements) assert.deepEqual(p.artifacts, ["host"]);
});
test("a per-machine entry OVERRIDES `all:`, it does not add to it", () => {
// Worth being exact about: a scenario naming one artifact for one machine gets that
// artifact, not that artifact plus everything in `all:`. The opposite reading would place
// things nobody asked for, which is the shape of fault this lab exists to catch.
const placements = planPlacements(scenario("place:\n all: [host]\n anchor: [substrate]"));
const byMachine = new Map(placements.map((p) => [p.machine, p.artifacts]));
assert.deepEqual(byMachine.get("anchor"), ["substrate"], "anchor should have ONLY substrate");
assert.deepEqual(byMachine.get("peer"), ["host"]);
});
test("a machine placed with nothing is not a placement", () => {
const placements = planPlacements(scenario("place:\n all: [host]\n anchor: []"));
assert.deepEqual(placements.map((p) => p.machine), ["peer"]);
});
test("no `place:` at all is no placements, not an error", () => {
assert.deepEqual(planPlacements(scenario("")), []);
});
test("placing the host is supported", () => {
// The whole point of stage 1: this used to be refused.
assert.doesNotThrow(() => assertSupported(scenario("place:\n all: [host]")));
});
test("a tier that does not exist is refused BY NAME", () => {
// Named individually rather than refused as a whole, so a scenario placing a host and a
// substrate is told exactly which half the lab cannot do — rather than being told `place:`
// is unsupported when half of it now works.
try {
assertSupported(scenario("place:\n all: [host, substrate]\n peer: [control]"));
assert.fail("expected a refusal");
} catch (err) {
assert.ok(err instanceof UnsupportedError);
const missing = err.missing.join("\n");
assert.match(missing, /substrate/, "the substrate was not named");
assert.match(missing, /control/, "the control plane was not named");
assert.doesNotMatch(missing, /place: host/, "the host is placeable and was refused anyway");
}
});
test("the refusal says what CAN be placed", () => {
// A refusal that does not say what is possible sends someone to the source to find out.
try {
assertSupported(scenario("place:\n all: [forge]"));
assert.fail("expected a refusal");
} catch (err) {
assert.ok(err instanceof UnsupportedError);
for (const placeable of PLACEABLE) {
assert.match(err.missing.join("\n"), new RegExp(placeable));
}
}
});
// --- runtime and image placement (novox/hq ADR 0006: the lab places what a sealed scenario
// cannot fetch) ---
test("an image reference is placeable, and a bare 'image:' is not", () => {
assert.ok(isPlaceable("image:alpine@sha256:abc"), "a reference should be placeable");
assert.ok(isPlaceable("image:postgres:17"), "a tag is the scenario's business, not the lab's");
assert.ok(!isPlaceable("image:"), "there is nothing to place");
assert.ok(!isPlaceable("image: "), "whitespace is not a reference");
});
test("the placeables are host, runtime and an image", () => {
assert.ok(isPlaceable("host"));
assert.ok(isPlaceable("runtime"));
assert.ok(!isPlaceable("substrate"), "the tiers above tier 0 do not exist yet");
assert.ok(!isPlaceable("control-plane"));
});
test("an unplaceable artifact is named, not refused as a whole", () => {
// A scenario placing a host and a substrate is told which half the lab cannot do — refusing
// wholesale would send somebody looking for the wrong problem.
const scenario = {
name: "s",
segments: {},
machines: { a: {} as never },
place: { a: ["host", "runtime", "image:alpine@sha256:x", "substrate"] },
} as unknown as Parameters<typeof assertSupported>[0];
assert.throws(
() => assertSupported(scenario),
(err: Error) => {
// Checked as `place: <artifact> —`, which is how an artifact is REPORTED as
// unplaceable. Searching for the bare word matched the message's own list of what CAN
// be placed, which mentions runtime — so the test failed on a correct message.
assert.ok(err.message.includes("place: substrate —"), "the unplaceable one is named");
assert.ok(!err.message.includes("place: image:alpine"), "a placeable one is not");
assert.ok(!err.message.includes("place: runtime —"), "nor is runtime");
assert.ok(!err.message.includes("place: host —"), "nor is host");
return true;
},
);
});