diff --git a/test/integration/mesh.test.ts b/test/integration/mesh.test.ts index 80b6660..82539a9 100644 --- a/test/integration/mesh.test.ts +++ b/test/integration/mesh.test.ts @@ -124,7 +124,17 @@ async function settled(node: string, withinMs = 240_000): Promise { const until = Date.now() + withinMs; let last = ""; while (Date.now() < until) { - const said = await mesh("status --json"); + // **Could not ask** and **asked, and the answer was bad** are different facts, and only the + // second is this machine's fault. The control plane is a container on the node being polled: + // while it applies a declaration, an exec into it can lose its fifo to containerd, and a poll + // loop that treats that as a verdict reports the mesh broken because the question missed. + const { out: said, ok } = await on("anchor", + `docker exec mesh-control /mesh-control status --json`); + if (!ok) { + last = said; + await new Promise((r) => setTimeout(r, 5000)); + continue; + } const state = JSON.parse(said) as { wrong: { node: string; outcome: string; refused?: string; failed?: { id: string; error: string }[] }[]; @@ -138,9 +148,13 @@ async function settled(node: string, withinMs = 240_000): Promise { } if (!state.waiting.some((w) => w.node === node)) return; last = said; - await new Promise((r) => setTimeout(r, 2000)); + // Unhurried on purpose: each poll is an exec into a container on the machine that is busy + // applying, and asking four times a minute rather than thirty is the difference between + // observing the apply and competing with it. + await new Promise((r) => setTimeout(r, 5000)); } - throw new Error(`${node} never caught up with what it was sent:\n${last}`); + throw new Error(`${node} never caught up with what it was sent within ` + + `${Math.round(withinMs / 1000)}s. Last answer, or the reason there was none:\n${last}`); } /**