test(gateway): cover single and simultaneous daemon crashes
tracker-policy-pr / check-pr (pull_request) Successful in 12s
test / integration-docker (pull_request) Successful in 34s
test / unit (pull_request) Successful in 45s
lint / lint (push) Successful in 53s
test / integration-firecracker (pull_request) Successful in 3m13s
test / coverage (pull_request) Successful in 17s
test / publish-infra (pull_request) Has been skipped

This commit is contained in:
2026-07-23 18:55:29 -04:00
committed by didericis
parent 5ded28896d
commit 2879dc34cc
+33 -10
View File
@@ -162,16 +162,17 @@ class TestSupervisor(unittest.TestCase):
return sup.exit_code() return sup.exit_code()
def test_all_children_succeed_returns_zero(self): def test_all_children_succeed_returns_zero(self):
# `sh -c :` exits 0 immediately. With the new failure # `sh -c :` exits 0 immediately. Start shutdown before driving
# policy a child dying doesn't trigger shutdown, so the # the loop so the intentionally short-lived fixtures are not
# loop only converges once BOTH have exited on their own. # treated as unexpected deaths and restarted.
# Both exit 0 → max(0, 0) = 0.
specs = [ specs = [
_DaemonSpec("a", ("/bin/sh", "-c", ":")), _DaemonSpec("a", ("/bin/sh", "-c", ":")),
_DaemonSpec("b", ("/bin/sh", "-c", ":")), _DaemonSpec("b", ("/bin/sh", "-c", ":")),
] ]
sup = _Supervisor(specs) sup = _Supervisor(specs)
sup.start_all() sup.start_all()
time.sleep(0.1)
sup.request_shutdown(reason="test")
rc = self._drive(sup) rc = self._drive(sup)
self.assertEqual(0, rc) self.assertEqual(0, rc)
@@ -208,6 +209,23 @@ class TestSupervisor(unittest.TestCase):
sup.request_shutdown(reason="test-teardown") sup.request_shutdown(reason="test-teardown")
self._drive(sup) self._drive(sup)
def test_single_daemon_crash_is_restarted_before_tick_completes(self):
specs = [_DaemonSpec("crasher", ("/bin/sh", "-c", "exit 1"))]
sup = _Supervisor(specs)
sup.start_all()
original_pid = sup.procs[0][1].pid
time.sleep(0.1)
done = sup.tick()
self.assertFalse(done)
self.assertNotEqual(original_pid, sup.procs[0][1].pid)
self.assertEqual(set(), sup._restart_requested)
self.assertIsNone(sup.shutdown_at)
sup.request_shutdown(reason="test-teardown")
self._drive(sup)
def test_crash_then_signal_surfaces_nonzero_exit_code(self): def test_crash_then_signal_surfaces_nonzero_exit_code(self):
# The crasher's exit code is what reaches the container # The crasher's exit code is what reaches the container
# exit even though shutdown was triggered by SIGTERM. # exit even though shutdown was triggered by SIGTERM.
@@ -224,20 +242,25 @@ class TestSupervisor(unittest.TestCase):
rc = self._drive(sup) rc = self._drive(sup)
self.assertEqual(1, rc) self.assertEqual(1, rc)
def test_all_children_die_unattended_loop_converges(self): def test_all_children_die_unattended_are_restarted(self):
# If nobody sends a signal but every child eventually
# dies on its own, the supervisor still exits — nothing
# left to supervise.
specs = [ specs = [
_DaemonSpec("a", ("/bin/sh", "-c", "exit 0")), _DaemonSpec("a", ("/bin/sh", "-c", "exit 0")),
_DaemonSpec("b", ("/bin/sh", "-c", "exit 2")), _DaemonSpec("b", ("/bin/sh", "-c", "exit 2")),
] ]
sup = _Supervisor(specs) sup = _Supervisor(specs)
sup.start_all() sup.start_all()
rc = self._drive(sup) original_pids = [p.pid for _, p in sup.procs]
self.assertEqual(2, rc) time.sleep(0.1)
done = sup.tick()
self.assertFalse(done)
self.assertNotEqual(original_pids, [p.pid for _, p in sup.procs])
self.assertIsNone(sup.shutdown_at) self.assertIsNone(sup.shutdown_at)
sup.request_shutdown(reason="test-teardown")
self._drive(sup)
def test_forward_signal_to_named_child(self): def test_forward_signal_to_named_child(self):
# SIGHUP needs to reach mitmdump inside the bundle so # SIGHUP needs to reach mitmdump inside the bundle so
# routes.yaml reloads (egress_apply.py issues `docker kill # routes.yaml reloads (egress_apply.py issues `docker kill