Files
daynivo-kiosk-os/tests/test_healthcheck.py
T
rothmanandClaude Opus 5.5 6733aacb6e
CI / test-bookworm (push) Successful in 29s
CI / test-latest (push) Successful in 33s
Rename the Python package to daynivo_kiosk
src/voxip_kiosk -> src/daynivo_kiosk, with every import, the launchers,
install.sh, the Makefile and the manager's gunicorn app path. An upgrade
replaces /usr/lib/voxip-kiosk/python as a whole, so the old package
disappears; tested by upgrading an installation of the previous commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 23:52:39 +01:00

86 lines
2.5 KiB
Python

import pytest
from daynivo_kiosk import services
from daynivo_kiosk.cdp import CDPError
from daynivo_kiosk.config import save_config
from daynivo_kiosk.healthcheck import CDP_FAILURES_BEFORE_RESTART, DISPLAY_RETRY_AFTER, HealthCheck
class World:
def __init__(self):
self.units = {u: {"ActiveState": "active"} for u in (services.X_UNIT, services.BROWSER_UNIT, services.AGENT_UNIT, services.MANAGER_UNIT)}
self.actions = []
self.now = 10_000.0
self.cdp_ok = True
def unit_status(self, unit):
return self.units[unit]
def systemctl(self, *args):
self.actions.append(args)
def version(self):
if not self.cdp_ok:
raise CDPError("timeout")
return {}
@pytest.fixture
def world(paths):
w = World()
hc = HealthCheck(paths, unit_status=w.unit_status, systemctl=w.systemctl, cdp=w, throttled=lambda: None,
disk=lambda p: {"percent": 40}, now=lambda: w.now)
return w, hc
def test_all_healthy_no_actions(world):
w, hc = world
report = hc.run()
assert report["actions"] == [] and w.actions == []
def test_failed_browser_waits_for_cooldown(world):
w, hc = world
w.units[services.BROWSER_UNIT] = {"ActiveState": "failed", "Result": "start-limit-hit"}
hc.run()
assert w.actions == []
w.now += DISPLAY_RETRY_AFTER
hc.run()
assert ("reset-failed", services.BROWSER_UNIT) in w.actions
assert ("start", "--no-block", services.BROWSER_UNIT) in w.actions
def test_failed_manager_restarts_immediately(world):
w, hc = world
w.units[services.MANAGER_UNIT] = {"ActiveState": "failed"}
hc.run()
assert ("start", "--no-block", services.MANAGER_UNIT) in w.actions
def test_browser_restart_disabled_is_respected(world, paths):
w, hc = world
save_config(paths.config_file, {"browser_restart": False})
w.units[services.BROWSER_UNIT] = {"ActiveState": "inactive"}
hc.run()
assert w.actions == []
def test_unresponsive_devtools_restarts_browser(world):
w, hc = world
hc.run() # browser seen active
w.now += 100
w.cdp_ok = False
for _ in range(CDP_FAILURES_BEFORE_RESTART - 1):
hc.run()
assert w.actions == []
hc.run()
assert ("restart", "--no-block", services.BROWSER_UNIT) in w.actions
def test_maintenance_mode_blocks_actions(world, paths):
w, hc = world
(paths.health_run_dir / "maintenance").touch()
w.units[services.AGENT_UNIT] = {"ActiveState": "inactive"}
report = hc.run()
assert report["maintenance"] is True and w.actions == []