Files
mesh-lab/test/integration/genesis-single.test.ts
T
jschoubben e427e41389 Raise a mesh of one by the installer, in a bed of its own
The four-node bed proves genesis entangled with three machines joining across a
gateway, so the cheapest check of the install path costs a four-machine raise.
This is genesis alone: one machine, the installer, and the question asked of the
machine rather than inferred from an exit code.

Genesis moves into a shared routine both beds call, rather than being described a
second time here — a second description kept in step with the first is what put
the whole procedure inside a fixture to begin with.

The scenario needs two things the first draft missed, and both cost a full raise
to discover: a way out to the internet, because the installer's first act is to
pull the substrate; and a container runtime, because the installer's first refusal
is a machine that has none.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-12 16:46:05 +02:00

104 lines
4.1 KiB
TypeScript

/**
* A MESH OF ONE, raised by the installer and nothing else.
*
* The four-node bed proves genesis too, but it proves it entangled with three machines joining
* afterwards across a gateway. This bed is genesis alone: one machine, the installer, and the
* question "is this a working mesh?" asked of the machine.
*
* It shares its genesis with the four-node bed (`./genesis.ts`) rather than describing installing
* a second time — a second description kept in step with the first is the arrangement that put
* the whole procedure inside a fixture in the first place (novox/hq ADR 0067).
*
* MESH_LAB_INCUS='sudo -n incus'
* MESH_LAB_HOST_BINARY=.../mesh-host/mesh-host
* MESH_LAB_BOOTSTRAP_BINARY=.../mesh-host/mesh-bootstrap
* MESH_LAB_BUNDLE=.../mesh-host/examples/substrate-first-node.lock
* MESH_LAB_CATALOG=.../mesh-catalog/modules
* MESH_LAB_KEEP=1 to leave it standing afterwards
*/
import { test, before, after } from "node:test";
import assert from "node:assert/strict";
import { existsSync } from "node:fs";
import { loadScenario } from "../../src/declaration/parse.ts";
import { raise } from "../../src/lifecycle/raise.ts";
import { destroy } from "../../src/lifecycle/operate.ts";
import { bootstrapBinaryPath, hostBinaryPath } from "../../src/lifecycle/place.ts";
import { labIsUsable, destroyAll, substrateBundle } from "./harness.ts";
import { genesis, type GenesisResult } from "./genesis.ts";
const SCENARIO = "genesis-single";
const NODE = "anchor";
const capability = await labIsUsable();
const binary = hostBinaryPath();
const installer = bootstrapBinaryPath();
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
const catalogDir = process.env["MESH_LAB_CATALOG"] ?? "";
const KEEP = !!process.env["MESH_LAB_KEEP"];
const FIXED_ID = process.env["MESH_LAB_INSTANCE_ID"] ?? (KEEP ? "genesis-single-live" : undefined);
const skip =
!capability.usable ? capability.why :
!binary ? "MESH_LAB_HOST_BINARY is not set to a built mesh-host" :
!installer ? "MESH_LAB_BOOTSTRAP_BINARY is not set to a built mesh-bootstrap (mesh-host `make " +
"bootstrap IMAGE=mesh-control:development`)" :
!bundle || !existsSync(bundle) ? "MESH_LAB_BUNDLE is not set to a substrate template" :
!catalogDir || !existsSync(catalogDir) ? "MESH_LAB_CATALOG is not set to mesh-catalog/modules" :
false;
let instanceId = "";
let result: GenesisResult;
before(async () => {
if (skip) return;
const raised = await raise(loadScenario(`scenarios/${SCENARIO}.yml`), {
onProgress: (m) => console.log(`raise: ${m}`),
...(FIXED_ID ? { instanceId: FIXED_ID } : {}),
});
instanceId = raised.instanceId;
console.log(`INSTANCE ${instanceId}${KEEP ? " (KEEP — will be left standing)" : ""}`);
// Caught rather than allowed to propagate, so a failure BEFORE the installer ran is reported in
// the same shape as one the installer itself named, instead of a bare stack trace.
try {
result = await genesis({
instanceId,
node: NODE,
installer: installer as string,
catalogDir,
// The template, not a bundle. The store and broker become the references mesh-catalog pins,
// and the machine pulls them over its uplink like any first node. mesh-control is left
// naming a registry that does not exist — the installer overwrites it, and leaving it proves
// that it does.
bundleTemplate: substrateBundle(bundle, []),
log: (m) => console.log(m),
});
} catch (err) {
result = {
ok: false,
step: "getting the machine ready to be bootstrapped — the installer never ran",
why: (err as Error).message,
report: [],
};
}
console.log(result.report.join("\n"));
}, { timeout: 3_600_000 });
after(async () => {
if (KEEP) {
console.log(`\nLEFT STANDING: ${instanceId} — not destroyed (MESH_LAB_KEEP).`);
return;
}
if (instanceId) await destroy(instanceId);
await destroyAll(`${SCENARIO}-`);
}, { timeout: 900_000 });
test("one machine becomes a working mesh of one, raised by the installer", {
skip, timeout: 3_600_000,
}, () => {
assert.ok(result.ok,
`GENESIS FAILED — ${result.step || "no step named"}.\n\n${result.why}\n\n` +
result.report.join("\n"));
});