Skip to content

Commit a9723f3

Browse files
Kasper JungeRalphify
authored andcommitted
test: cover SIGKILL failure fallback in _try_graceful_group_kill
When SIGTERM times out and the subsequent SIGKILL also fails (process vanished between attempts), the code falls back to proc.kill(). This edge case was the only uncovered path — test suite now reaches 100%. Co-authored-by: Ralphify <noreply@ralphify.co>
1 parent 4270873 commit a9723f3

1 file changed

Lines changed: 16 additions & 0 deletions

File tree

tests/test_agent.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,22 @@ def test_escalates_to_sigkill_on_timeout(self, mock_getpgid, mock_killpg):
467467
mock_killpg.assert_any_call(42, signal.SIGTERM)
468468
mock_killpg.assert_any_call(42, signal.SIGKILL)
469469

470+
@patch("ralphify._agent.os.killpg")
471+
@patch("ralphify._agent.os.getpgid")
472+
def test_sigkill_failure_falls_back_to_proc_kill(self, mock_getpgid, mock_killpg):
473+
"""When SIGTERM times out and SIGKILL also fails, fall back to proc.kill()."""
474+
proc = MagicMock(pid=42, poll=MagicMock(return_value=None))
475+
proc.wait.side_effect = subprocess.TimeoutExpired(cmd="agent", timeout=3)
476+
mock_getpgid.return_value = 42
477+
# SIGTERM succeeds but SIGKILL fails (process vanished between attempts)
478+
mock_killpg.side_effect = [None, ProcessLookupError("No such process")]
479+
480+
_kill_process_group(proc)
481+
482+
mock_killpg.assert_any_call(42, signal.SIGTERM)
483+
mock_killpg.assert_any_call(42, signal.SIGKILL)
484+
proc.kill.assert_called_once()
485+
470486
@patch("ralphify._agent.os.killpg")
471487
@patch("ralphify._agent.os.getpgid")
472488
def test_not_session_leader_falls_back_to_kill(self, mock_getpgid, mock_killpg):

0 commit comments

Comments
 (0)