60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""Browser cleanup fallback contracts, retained after retiring the npx warmer."""
|
|
|
|
import os
|
|
import signal
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from tools.browser_tool_lifecycle import _legacy_kill_process_tree
|
|
|
|
|
|
@pytest.mark.platforms("posix")
|
|
def test_posix_kills_process_group_term_then_kill(monkeypatch):
|
|
proc = MagicMock(pid=999)
|
|
monkeypatch.setattr(os, "getpgid", lambda pid: 999)
|
|
calls = []
|
|
monkeypatch.setattr(os, "killpg", lambda pgid, sig: calls.append((pgid, sig)))
|
|
_legacy_kill_process_tree(proc)
|
|
assert calls == [(999, signal.SIGTERM), (999, signal.SIGKILL)]
|
|
|
|
|
|
@pytest.mark.platforms("posix")
|
|
def test_posix_missing_process_returns_silently(monkeypatch):
|
|
def missing(pid):
|
|
raise ProcessLookupError()
|
|
|
|
monkeypatch.setattr(os, "getpgid", missing)
|
|
_legacy_kill_process_tree(MagicMock(pid=999))
|
|
|
|
|
|
@pytest.mark.platforms("posix")
|
|
@pytest.mark.parametrize("kill_error", [None, OSError("already reaped")])
|
|
def test_missing_killpg_falls_back_to_proc_kill(monkeypatch, kill_error):
|
|
proc = MagicMock(pid=999)
|
|
proc.kill.side_effect = kill_error
|
|
monkeypatch.delattr(os, "killpg", raising=False)
|
|
_legacy_kill_process_tree(proc)
|
|
proc.kill.assert_called_once()
|
|
|
|
|
|
@pytest.mark.platforms("posix")
|
|
def test_permission_denied_does_not_attempt_sigkill(monkeypatch):
|
|
monkeypatch.setattr(os, "getpgid", lambda pid: 999)
|
|
calls = []
|
|
|
|
def denied(pgid, sig):
|
|
calls.append((pgid, sig))
|
|
raise PermissionError()
|
|
|
|
monkeypatch.setattr(os, "killpg", denied)
|
|
_legacy_kill_process_tree(MagicMock(pid=999))
|
|
assert calls == [(999, signal.SIGTERM)]
|
|
|
|
|
|
@pytest.mark.platforms("windows")
|
|
@pytest.mark.parametrize("error", [None, OSError("taskkill missing")])
|
|
def test_windows_taskkill_targets_tree_and_is_best_effort(error):
|
|
with patch("subprocess.run", side_effect=error) as run:
|
|
_legacy_kill_process_tree(MagicMock(pid=4321))
|
|
assert run.call_args.args[0] == ["taskkill", "/PID", "4321", "/T", "/F"] |