One-node bed: SDK-by-version, rename, and the store/broker upgrade proofs #27
@@ -103,6 +103,12 @@ const MUST_RUN = ["mesh-control", "mesh-registry", "mesh-broker", "mesh-store",
|
||||
/** Named once, because the step title is also how later steps say what they waited on. */
|
||||
const NEEDS = "the mesh runs a broker for that module to talk to";
|
||||
const GENESIS = "a bare machine becomes a mesh of one, raised by the installer";
|
||||
const SUBSTRATE = "the substrate is up — a store and a broker of the mesh's own";
|
||||
const BUILT_CP = "the control plane is one this mesh built, not one it was handed";
|
||||
const PIVOTED = "the pivot finished — what raised the mesh is gone";
|
||||
const HAS_REGISTRY = "the registry serves this mesh its own images";
|
||||
const ENROLLED = "the machine is enrolled, and an agent is running on it";
|
||||
const HAS_BUILDER = "the builder is installed as a module, with an account";
|
||||
const BASE_BUILT = "the mesh builds the shared base from source";
|
||||
const STORE_RUNS = "the mesh builds and runs a store of its own";
|
||||
const CATALOGUE_RUNS = "the mesh builds and runs its own catalogue";
|
||||
@@ -365,6 +371,69 @@ before(async () => {
|
||||
return raised.report.join("\n");
|
||||
});
|
||||
|
||||
// ---- WHAT GENESIS CLAIMED, ASKED OF THE MACHINE ----------------------------------------------
|
||||
//
|
||||
// **Genesis is twelve steps and was reported as one line.** All the work of raising a mesh
|
||||
// happens inside it, so "genesis failed" said nothing about which of its claims broke, and
|
||||
// "genesis passed" was one tick standing in for six separate things being true.
|
||||
//
|
||||
// Each is asked of the machine rather than read from the installer's own output — the installer
|
||||
// saying it published an image and the registry serving one are different facts, and it is the
|
||||
// second that matters.
|
||||
|
||||
await step(SUBSTRATE, GENESIS, async () => {
|
||||
await waitForContainer(CONTROL, "mesh-store", 120);
|
||||
await waitForContainer(CONTROL, "mesh-broker", 120);
|
||||
return (await on(CONTROL, `docker ps --format '{{.Names}}\t{{.Status}}'`)).out;
|
||||
});
|
||||
|
||||
// **The whole reason the installer carries a builder.** A carried control-plane image would
|
||||
// satisfy "a control plane is running" equally well, which is what makes this worth asserting:
|
||||
// the image has to be one this mesh's own registry serves.
|
||||
await step(BUILT_CP, GENESIS, async () => {
|
||||
const image = (await on(CONTROL,
|
||||
`docker inspect -f '{{.Config.Image}}' mesh-control 2>&1`)).out.trim();
|
||||
assert.match(image, /@sha256:[0-9a-f]{64}/,
|
||||
`the control plane names its image by tag, not by digest: ${image}`);
|
||||
assert.ok(image.includes(":5000/"),
|
||||
`the control plane runs an image no registry of this mesh served: ${image}`);
|
||||
return image;
|
||||
});
|
||||
|
||||
await step(PIVOTED, BUILT_CP, async () => {
|
||||
const ps = (await on(CONTROL, `docker ps -a --format '{{.Names}}'`)).out;
|
||||
assert.doesNotMatch(ps, /^temp-mesh-control$/m,
|
||||
`the temporary control plane is still here, so the pivot did not finish:\n${ps}`);
|
||||
return ps;
|
||||
});
|
||||
|
||||
await step(HAS_REGISTRY, SUBSTRATE, async () => {
|
||||
await waitForContainer(CONTROL, "mesh-registry", 120);
|
||||
const held = (await on(CONTROL,
|
||||
`curl -sS --max-time 15 http://127.0.0.1:5000/v2/_catalog`)).out;
|
||||
assert.match(held, /mesh-control/,
|
||||
`the registry serves no mesh-control, so nothing was published into it:\n${held}`);
|
||||
return held.trim();
|
||||
});
|
||||
|
||||
await step(ENROLLED, GENESIS, async () => {
|
||||
const nodes = await mesh("node list");
|
||||
assert.match(nodes, new RegExp(`^${CONTROL}\\b`, "m"),
|
||||
`the mesh has not heard from the machine it is running on:\n${nodes}`);
|
||||
// Heard from once is not an agent running, and the difference is the whole of joining.
|
||||
const agent = (await on(CONTROL, `pgrep -af '[m]esh-host run' | head -3`)).out.trim();
|
||||
assert.ok(agent, `no host agent is running, so nothing would apply what the mesh sends`);
|
||||
return `${nodes.trim()}\n${agent}`;
|
||||
});
|
||||
|
||||
await step(HAS_BUILDER, HAS_REGISTRY, async () => {
|
||||
await waitForContainer(CONTROL, "mesh-builder", 120);
|
||||
const modules = await mesh("module list");
|
||||
assert.match(modules, /^builder\b/m,
|
||||
`the builder is running but the mesh holds no record of it as a module:\n${modules}`);
|
||||
return modules;
|
||||
});
|
||||
|
||||
// ---- 2..6. THE MESH BECOMES ONE --------------------------------------------------------------
|
||||
//
|
||||
// **Joining used to be here, second, and that was the wrong order.** Three machines were enrolled
|
||||
@@ -380,7 +449,7 @@ before(async () => {
|
||||
// The toolchain and runtime every module with code of its own stands on. It is a module, and it
|
||||
// is built like one — cloned from the forge by the builder installing put here, compiled on the
|
||||
// machine, published into the mesh's own registry.
|
||||
await step(BASE_BUILT, GENESIS, async () => {
|
||||
await step(BASE_BUILT, HAS_BUILDER, async () => {
|
||||
// Registered from the manifest the builder will also read, so what the mesh holds and what it
|
||||
// builds are the same description of the same module.
|
||||
//
|
||||
@@ -507,7 +576,8 @@ before(async () => {
|
||||
|
||||
// And the catalogue, ASKED rather than observed. These five questions are what it exists for.
|
||||
const ask = async (tool: string, args = "{}") =>
|
||||
must(CONTROL, `docker exec mesh-catalog mesh-tools invoke mesh-catalog ${tool} ${quote(args)}`,
|
||||
must(CONTROL, `docker exec mesh-catalog node /app/dist/main.js invoke mesh-catalog ` +
|
||||
`${tool} ${quote(args)}`,
|
||||
120_000);
|
||||
|
||||
const held = await ask("catalog_modules");
|
||||
@@ -631,6 +701,12 @@ after(async () => {
|
||||
|
||||
for (const name of [
|
||||
GENESIS,
|
||||
SUBSTRATE,
|
||||
BUILT_CP,
|
||||
PIVOTED,
|
||||
HAS_REGISTRY,
|
||||
ENROLLED,
|
||||
HAS_BUILDER,
|
||||
BASE_BUILT,
|
||||
STORE_RUNS,
|
||||
CATALOGUE_RUNS,
|
||||
|
||||
Reference in New Issue
Block a user