From 85d9f98f3eef705490c36200e190811da2e23dc3 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:41:03 -0700 Subject: [PATCH] test(update): a retried owed restart now relaunches a paused manual gateway The post-commit cell assumed a manual `gateway run` that died at boot leaves the retry nothing to relaunch. The pre-swap pause records its argv, so the retry relaunches it on HEAD; the cell now asserts that, keeping the invariant that the obligation discharges only once a gateway serves HEAD (observed: PID 6 -> 1210, code_sha == HEAD). The operator-restart leg is gone: it would start a twin. --- .../e2e/core/upgrade/git/test_hostile_post.py | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/tests/e2e/core/upgrade/git/test_hostile_post.py b/tests/e2e/core/upgrade/git/test_hostile_post.py index ccaa2cdb19..42fb2d13e6 100644 --- a/tests/e2e/core/upgrade/git/test_hostile_post.py +++ b/tests/e2e/core/upgrade/git/test_hostile_post.py @@ -431,31 +431,21 @@ def test_gateway_that_cannot_reboot_is_an_owed_restart_not_a_failed_update(w): assert OWED_RESTART in G.output(status), \ f"a later command does not warn that a gateway restart is still owed:\n{diag}" - # The fault clears; the next plain update retries the owed restart. This gateway is a - # manual `gateway run` that died at boot: no supervisor and no live process, so the - # retry has nothing it can relaunch. It must still exit 0 and must NOT silently discharge - # the obligation (no gateway serves HEAD yet). + # The fault clears; the next plain update retries the owed restart. The gateway was a + # manual `gateway run` with no supervisor, but the pre-swap pause recorded its argv, so the + # retry relaunches it on HEAD. The obligation may discharge only because a gateway now + # serves HEAD, never while none does. _toggle(w, BREAK_GATEWAY, False) cp = _ns_update(host, w) + served = None + with contextlib.suppress(AssertionError): + served = H.wait_for(lambda: _serving(w, target), timeout=240, interval=1.0, what="a gateway on HEAD") status = _ns_cli(host, w, "status", timeout=300) diag = (_facts(w, cp, identify_after=_identify(w)) + w.diag(cp) + "\n--- gateway logs ---\n" + _gateway_logs(w)[-6000:] + "\n--- sandbox ---\n" + host.ps_text() + "\n--- hermes status ---\n" + G.output(status)[-3000:]) assert cp.returncode == 0, f"the retrying update failed:\n{diag}" - assert OWED_RESTART in G.output(status), \ - f"the retry discharged the owed restart while no gateway serves HEAD:\n{diag}" - - # The operator restarts it (the remedy the warning names); once a gateway serves HEAD the - # obligation discharges and the warning goes away. - host.spawn([w.sb.hermes, "gateway", "run"], log=w.sb.root / "gateway-b2.log") - served = None - with contextlib.suppress(AssertionError): - served = H.wait_for(lambda: _serving(w, target), timeout=240, interval=1.0, what="a gateway on HEAD") - status = _ns_cli(host, w, "status", timeout=300) - diag = (_facts(w, cp, identify_after=_identify(w)) + "\n--- gateway logs ---\n" - + _gateway_logs(w)[-6000:] + "\n--- sandbox ---\n" + host.ps_text() - + "\n--- hermes status ---\n" + G.output(status)[-3000:]) - assert served, f"premise: the restarted gateway never served {target[:12]}:\n{diag}" + assert served, f"the retry did not relaunch the paused gateway on {target[:12]}:\n{diag}" assert OWED_RESTART not in G.output(status), \ f"the owed-restart warning survived a gateway serving HEAD:\n{diag}" finally: