Unify trunk on main: initialization → main #3
@@ -1017,3 +1017,62 @@ test("model access is answered by a record, and the key the mesh took is one it
|
||||
assert.equal(held.out.trim(), "0", `the key is in the open in ${where}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("a new commit reaches a machine that is already running the old one", {
|
||||
skip: skip || (!builder ? "set MESH_LAB_BUILDER to a built mesh-builder" : false),
|
||||
timeout: 900_000,
|
||||
}, async () => {
|
||||
// novox/hq ADR 0010 names the real risk of replacing a pipeline with a comparison: losing the
|
||||
// question "did my change go out?". This is that question, end to end — a commit, a build, a
|
||||
// catalogue, and a machine that ends up running what the source says.
|
||||
const repo = "/var/lib/mesh/builder/repositories/delivered";
|
||||
const write = async (what: string) =>
|
||||
await must("anchor", `mkdir -p ${repo} && printf %s '{"module":"delivered","version":"1",` +
|
||||
`"resources":[{"id":"marker","type":"file","path":"/etc/delivered",` +
|
||||
`"content":"${what}","mode":"0644"}]}' > ${repo}/module.json`);
|
||||
|
||||
await write("first");
|
||||
await must("anchor", `cd ${repo} && git init -q . && git add -A && ` +
|
||||
`git -c user.email=lab -c user.name=lab commit -qm first`);
|
||||
await mesh(`build ${repo} --wait 300s`, 420_000);
|
||||
await mesh("assign laptop delivered");
|
||||
await mesh("push laptop");
|
||||
await new Promise((r) => setTimeout(r, 15_000));
|
||||
assert.equal((await must("laptop", `cat /etc/delivered`)).trim(), "first");
|
||||
|
||||
// Nothing has moved, so nothing is behind — and it says so rather than doing nothing quietly.
|
||||
assert.match(await mesh("build --behind"), /every module the mesh holds is what its source last had/);
|
||||
|
||||
// Now the source moves.
|
||||
await write("second");
|
||||
await must("anchor", `cd ${repo} && git add -A && ` +
|
||||
`git -c user.email=lab -c user.name=lab commit -qm second`);
|
||||
const moved = (await must("anchor", `cd ${repo} && git rev-parse HEAD`)).trim();
|
||||
await mesh(`module moved delivered ${moved}`);
|
||||
|
||||
// The mesh says which module is behind, and by how much, before anything is built.
|
||||
const behind = await mesh("status");
|
||||
assert.match(behind, /delivered/, `status does not name the module that moved:\n${behind}`);
|
||||
assert.match(behind, /build --behind/, `status does not say how to catch up:\n${behind}`);
|
||||
|
||||
// The loop, in one command: everything behind its source is built and recorded.
|
||||
const built = await mesh("build --behind --wait 300s", 420_000);
|
||||
assert.match(built, /delivered/, built);
|
||||
|
||||
// The machine is still running the old one until it is told — the mesh changing its mind is
|
||||
// not the same as a machine acting on it, and collapsing the two is how a mesh reports success
|
||||
// for something that has not happened.
|
||||
assert.equal((await must("laptop", `cat /etc/delivered`)).trim(), "first",
|
||||
"the machine changed before anything was sent to it");
|
||||
|
||||
await mesh("push laptop");
|
||||
await new Promise((r) => setTimeout(r, 15_000));
|
||||
assert.equal((await must("laptop", `cat /etc/delivered`)).trim(), "second",
|
||||
"the machine is still running what the source no longer says");
|
||||
|
||||
// And it is no longer out of date, which is the half that makes the answer trustworthy: a
|
||||
// status that says "behind" for ever is one nobody reads.
|
||||
const after = await mesh("status");
|
||||
assert.doesNotMatch(after, /delivered.*<.*[0-9a-f]{8}/,
|
||||
`the module is still reported as behind after catching up:\n${after}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user