It gained a Makefile target today; a target the rebuild does not run is the stale image this file was just fixed for.
68 lines
3.3 KiB
TypeScript
68 lines
3.3 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { planned } from "../src/rebuild.ts";
|
|
import { repositories } from "../src/repos.ts";
|
|
|
|
// The control plane's image and the builder are one step, not two.
|
|
//
|
|
// Both parse manifests. On 2026-08-30 a rename was built into the image and not the binary, and
|
|
// the run that found out was a full lab raise. novox/hq 04-ISSUES/005.
|
|
test("the control plane's image and builder are always built together", () => {
|
|
const builds = planned({
|
|
MESH_LAB_MODULES: "/repo/control/examples/modules",
|
|
MESH_LAB_BUILDER: "/repo/control/build/mesh-builder",
|
|
});
|
|
const what = builds.map((b) => b.what);
|
|
assert.ok(what.includes("images"), "the images were not built");
|
|
assert.ok(what.includes("builder"), "the builder was not built");
|
|
for (const build of builds) assert.equal(build.in, "/repo/control");
|
|
});
|
|
|
|
// Every image the lab runs, not only the control plane's.
|
|
//
|
|
// On 2026-09-01 a run had a control-plane image built that minute and a provisioner image built
|
|
// the day before. A test against a real database failed, and it looked exactly like the change
|
|
// under test being wrong: the provisioner was creating logins by a naming rule that had been
|
|
// replaced hours earlier. novox/hq 04-ISSUES/005 again, one target along.
|
|
//
|
|
// Named individually rather than by counting, because the failure this guards is a target that
|
|
// exists and is not run — which a count would not notice.
|
|
test("every image the lab runs is rebuilt, not only the control plane's", () => {
|
|
const builds = planned({ MESH_LAB_MODULES: "/repo/control/examples/modules" });
|
|
const images = builds.find((b) => b.what === "images");
|
|
assert.ok(images, "no image build at all");
|
|
for (const target of [
|
|
"image", "builder-image", "provisioner-image", "objectstore-image", "proxy-image",
|
|
]) {
|
|
assert.ok(images.argv.includes(target), `${target} is never built, so the lab runs a stale one`);
|
|
}
|
|
});
|
|
|
|
// A repository this run was not pointed at is not built, and not claimed.
|
|
test("only what this run was pointed at is built", () => {
|
|
assert.deepEqual(planned({}), []);
|
|
const hostOnly = planned({ MESH_LAB_HOST_BINARY: "/repo/host/mesh-host" });
|
|
assert.deepEqual(hostOnly.map((b) => b.what), ["host"]);
|
|
assert.equal(hostOnly[0]!.in, "/repo/host");
|
|
});
|
|
|
|
// What the receipt claims and what the run built come from one derivation.
|
|
//
|
|
// They are separate concerns that must agree: a receipt naming a repository the run did not build
|
|
// is false coverage arriving by nobody's decision — just two derivations drifting apart.
|
|
// novox/hq 04-ISSUES/005.
|
|
test("every repository the receipt claims was built by the run", () => {
|
|
const env = {
|
|
MESH_LAB_HOST_BINARY: "/repo/host/mesh-host",
|
|
MESH_LAB_MODULES: "/repo/control/examples/modules",
|
|
MESH_LAB_BUILDER: "/repo/control/build/mesh-builder",
|
|
};
|
|
const built = new Set(planned(env).map((b) => b.in));
|
|
for (const [name, directory] of Object.entries(repositories(env))) {
|
|
// mesh-lab is the exception, and it is not an omission: it is TypeScript run from source, so
|
|
// the code under test *is* the code running. There is nothing to build and nothing to go stale.
|
|
if (name === "mesh-lab") continue;
|
|
assert.ok(built.has(directory), `${name} (${directory}) is claimed but never built`);
|
|
}
|
|
});
|