diff --git a/test/integration/one-node-mesh.test.ts b/test/integration/one-node-mesh.test.ts index 503845a..83c1855 100644 --- a/test/integration/one-node-mesh.test.ts +++ b/test/integration/one-node-mesh.test.ts @@ -231,6 +231,11 @@ async function mesh(command: string, timeoutMs?: number): Promise { for (;;) { const { out, ok } = await on(CONTROL, `docker exec mesh-controller /mesh-controller ${command}`, timeoutMs); if (ok) return out; + // A push that has said "N node(s) told" has done its work: the declaration is on the bus. The + // exec carrying it can still die afterwards with no message when the controller itself is + // recreated under it — which is exactly what an in-place broker upgrade does, since the + // controller reconnects to the bus that returns (S2). The send is what the push is for. + if (/^push\b/.test(command) && /\d+ node\(s\) told/.test(out)) return out; // "No such exec instance" and a daemon that cannot be reached are the same race one layer down: // applying the packet filter restarts the container runtime itself, and every container with // it, a few seconds after the installer's last push returns.