fix: ManagedService terminates unresponsive drivers; stop_service reaps children

This commit is contained in:
Mathew Sir Guest the best
2026-07-07 22:23:09 -06:00
parent f82b77ae62
commit 65d31e8821
3 changed files with 161 additions and 26 deletions
+35 -3
View File
@@ -154,6 +154,21 @@ def stub_driver(tmp_path):
return path
SILENT_DRIVER = """\
#!{python}
import sys, time
time.sleep(300) # accepts --port=N like a real driver but never serves /status
"""
@pytest.fixture
def silent_driver(tmp_path):
path = tmp_path / "chromedriver"
path.write_text(SILENT_DRIVER.format(python=sys.executable))
path.chmod(path.stat().st_mode | stat.S_IEXEC)
return path
class TestFindDriverBinary:
def test_env_var_override_wins(self, monkeypatch):
monkeypatch.setenv("WABOT_CHROMEDRIVER", "/custom/chromedriver")
@@ -180,13 +195,30 @@ class TestManagedService:
finally:
stop_service(svc.pid)
def test_startup_timeout_raises(self, tmp_path):
# /bin/true exits immediately and never serves /status
def test_early_exit_raises_with_returncode(self, tmp_path):
# /bin/true exits immediately: distinct from a slow timeout
svc = ManagedService(
"chromium", log_dir=tmp_path, driver_binary="/bin/true", startup_timeout=1.0
"chromium", log_dir=tmp_path, driver_binary="/bin/true", startup_timeout=5.0
)
with pytest.raises(RuntimeError, match="exited early"):
svc.ensure_running()
def test_startup_timeout_terminates_and_does_not_leak(self, silent_driver, tmp_path):
svc = ManagedService(
"chromium", log_dir=tmp_path, driver_binary=str(silent_driver), startup_timeout=1.0
)
with pytest.raises(TimeoutError, match="did not answer /status"):
svc.ensure_running()
# the unresponsive driver must have been terminated + reaped, not leaked
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
try:
os.kill(svc.pid, 0)
except ProcessLookupError:
break
time.sleep(0.05)
with pytest.raises(ProcessLookupError):
os.kill(svc.pid, 0)
class TestStopService: