Run the forge, on a database the mesh gave it
Everything up to now stopped at composing a declaration. That proves the control plane and the host agree, and proves nothing about whether the thing described works — which is how five modules sat pinned to images that did not exist while parsing and resolving perfectly. The forge is the right one to run first. It needs a database from another module, a password it did not choose, and a connection string it could not have written itself: the address and port come from what the database serves, the user name from what the mesh decided both ends would call it. If any of that is wrong it cannot start, and nothing else in this suite would notice. The test checks the chain in the order it has to happen — the login exists, the database it owns exists, the forge answers, and its log does not say authentication failed. That last one matters: a forge that started and could not reach its database would still answer on its port. Rewriting image references is now shared rather than copied from the bundle, which had the same problem first. A digest is not knowable until something is built, and when it is, it belongs to whichever registry served it — so the text says which image and the scenario says which copy. Matching is on the repository, with a test that a repository ending in another one is not half-replaced. Also makes the planning test put the machine back. Tests here share one mesh, so the five modules it assigned were inherited by whatever ran next; harmless while nothing pushed, and not harmless now.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import { pinnedInto, repositoryOf, stillUnpinned } from "../src/pinning.ts";
|
||||
|
||||
const SERVED = [
|
||||
"192.0.2.250:5000/postgres@sha256:" + "a".repeat(64),
|
||||
"192.0.2.250:5000/mesh-provision-postgres@sha256:" + "b".repeat(64),
|
||||
"192.0.2.250:5000/gitea/gitea@sha256:" + "c".repeat(64),
|
||||
"192.0.2.250:5000/ghcr.io/mailu/admin@sha256:" + "d".repeat(64),
|
||||
];
|
||||
|
||||
test("the repository is what survives being served somewhere else", () => {
|
||||
assert.equal(repositoryOf(SERVED[0]!), "postgres");
|
||||
assert.equal(repositoryOf(SERVED[2]!), "gitea/gitea");
|
||||
assert.equal(repositoryOf(SERVED[3]!), "ghcr.io/mailu/admin");
|
||||
assert.equal(repositoryOf("alpine"), "alpine");
|
||||
});
|
||||
|
||||
// The case this exists for: an image the mesh builds has no digest until it is built, so a
|
||||
// manifest ships sixty-four zeros and would stop on the machine (novox/hq 04-ISSUES/025).
|
||||
test("a placeholder for one of our own images becomes the one this scenario serves", () => {
|
||||
const before = `"image": "mesh-provision-postgres@sha256:${"0".repeat(64)}"`;
|
||||
const after = pinnedInto(before, SERVED);
|
||||
assert.match(after, /192\.0\.2\.250:5000\/mesh-provision-postgres@sha256:b{64}/);
|
||||
assert.deepEqual(stillUnpinned(after), []);
|
||||
});
|
||||
|
||||
// And a real third-party digest is replaced too — the text says which image, the scenario says
|
||||
// which copy of it.
|
||||
test("a real digest is redirected to this scenario's copy", () => {
|
||||
const before = `"image": "gitea/gitea@sha256:${"f".repeat(64)}"`;
|
||||
assert.match(pinnedInto(before, SERVED), /192\.0\.2\.250:5000\/gitea\/gitea@sha256:c{64}/);
|
||||
});
|
||||
|
||||
test("a reference that already carries a registry is still redirected", () => {
|
||||
const before = `"image": "docker.io/postgres@sha256:${"e".repeat(64)}"`;
|
||||
assert.match(pinnedInto(before, SERVED), /192\.0\.2\.250:5000\/postgres@sha256:a{64}/);
|
||||
});
|
||||
|
||||
// **Left alone, not blanked.** A repository this scenario did not stock may be reachable some
|
||||
// other way, and emptying the reference would produce the exact failure this prevents.
|
||||
test("something the scenario does not serve is untouched", () => {
|
||||
const before = `"image": "redis@sha256:${"9".repeat(64)}"`;
|
||||
assert.equal(pinnedInto(before, SERVED), before);
|
||||
});
|
||||
|
||||
// A longer repository ending in a shorter one must not be half-replaced.
|
||||
test("a repository that ends in another one is not partly rewritten", () => {
|
||||
const before = `"image": "my-postgres@sha256:${"7".repeat(64)}"`;
|
||||
assert.equal(pinnedInto(before, SERVED), before,
|
||||
"'my-postgres' was rewritten because it ends in 'postgres'");
|
||||
});
|
||||
|
||||
test("every image in a whole manifest is redirected at once", () => {
|
||||
const manifest = JSON.stringify({
|
||||
resources: [
|
||||
{ id: "db", image: `postgres@sha256:${"1".repeat(64)}` },
|
||||
{ id: "prov", image: `mesh-provision-postgres@sha256:${"0".repeat(64)}` },
|
||||
{ id: "app", image: `gitea/gitea@sha256:${"2".repeat(64)}` },
|
||||
],
|
||||
});
|
||||
const after = pinnedInto(manifest, SERVED);
|
||||
assert.deepEqual(stillUnpinned(after), []);
|
||||
for (const want of ["a".repeat(64), "b".repeat(64), "c".repeat(64)]) {
|
||||
assert.ok(after.includes(want), `missing ${want.slice(0, 6)}… in ${after}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("what is still a placeholder can be named", () => {
|
||||
const text = `"image": "something-of-ours@sha256:${"0".repeat(64)}"`;
|
||||
assert.deepEqual(stillUnpinned(text), ["something-of-ours"]);
|
||||
});
|
||||
Reference in New Issue
Block a user