Files
daynivo-kiosk-os/tests/test_healthcheck.py
T
rothmanandClaude Opus 5.5 a33c4822bf
CI / test-bookworm (push) Failing after 11s
CI / test-latest (push) Successful in 1m27s
VoxIP Kiosk OS 1.0.0: Raspberry Pi kiosk with web management
Chromium kiosk without a desktop for the Raspberry Pi 3, a Flask web
interface on port 8080 (kiosk, system and network management), a
restricted root helper, network changes with automatic rollback, a
healthcheck timer, install/update/uninstall scripts and a pi-gen image
build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:38:49 +01:00

86 lines
2.5 KiB
Python

import pytest
from voxip_kiosk import services
from voxip_kiosk.cdp import CDPError
from voxip_kiosk.config import save_config
from voxip_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 == []