feat: troppa roba davvero
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
import asyncio
|
||||
from datetime import UTC, datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from app.models.health import HealthSnapshot
|
||||
from app.models.proxy import ProxyDocument
|
||||
from app.models.service import ServiceEndpointDocument
|
||||
from app.services.mitmproxy.health_monitor import HealthMonitor
|
||||
|
||||
|
||||
def make_proxy(**updates):
|
||||
data = {
|
||||
"proxy_port": 8080,
|
||||
"name": "svc",
|
||||
"code": "",
|
||||
"status": "running",
|
||||
"service": ServiceEndpointDocument(port=9000),
|
||||
}
|
||||
data.update(updates)
|
||||
return ProxyDocument(**data)
|
||||
|
||||
|
||||
def make_snapshot(proxy_port: int, *, overall: str = "healthy") -> HealthSnapshot:
|
||||
return HealthSnapshot(
|
||||
proxy_port=proxy_port,
|
||||
timestamp=datetime.now(UTC),
|
||||
enabled=True,
|
||||
overall=overall,
|
||||
checks=[],
|
||||
)
|
||||
|
||||
|
||||
def test_run_cycle_records_and_publishes_running_healthchecks(monkeypatch):
|
||||
monitor = HealthMonitor()
|
||||
proxy = make_proxy()
|
||||
captured: dict[str, object] = {}
|
||||
snapshot = make_snapshot(8080)
|
||||
|
||||
async def fake_list_proxies():
|
||||
return [proxy]
|
||||
|
||||
async def fake_check_proxy(document):
|
||||
captured["checked"] = document.proxy_port
|
||||
return snapshot
|
||||
|
||||
async def fake_record_health_sample(document):
|
||||
captured["recorded"] = document
|
||||
return document
|
||||
|
||||
async def fake_publish(proxy_port, document):
|
||||
captured["published"] = (proxy_port, document)
|
||||
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.list_proxies",
|
||||
fake_list_proxies,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.check_proxy",
|
||||
fake_check_proxy,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.record_health_sample",
|
||||
fake_record_health_sample,
|
||||
)
|
||||
monkeypatch.setattr(monitor, "publish", fake_publish)
|
||||
|
||||
asyncio.run(monitor.run_cycle())
|
||||
|
||||
assert captured["checked"] == 8080
|
||||
assert captured["recorded"] == snapshot
|
||||
assert captured["published"] == (8080, snapshot)
|
||||
|
||||
|
||||
def test_run_cycle_skips_stopped_or_disabled_proxies(monkeypatch):
|
||||
monitor = HealthMonitor()
|
||||
running_disabled = make_proxy(healthcheck={"enabled": False})
|
||||
stopped = make_proxy(proxy_port=8081, status="stopped")
|
||||
called = False
|
||||
|
||||
async def fake_list_proxies():
|
||||
return [running_disabled, stopped]
|
||||
|
||||
async def fake_check_proxy(_document):
|
||||
nonlocal called
|
||||
called = True
|
||||
return make_snapshot(8080)
|
||||
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.list_proxies",
|
||||
fake_list_proxies,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.check_proxy",
|
||||
fake_check_proxy,
|
||||
)
|
||||
|
||||
asyncio.run(monitor.run_cycle())
|
||||
|
||||
assert called is False
|
||||
|
||||
|
||||
def test_run_cycle_checks_proxies_in_parallel(monkeypatch):
|
||||
monitor = HealthMonitor()
|
||||
proxies = [
|
||||
make_proxy(proxy_port=8080),
|
||||
make_proxy(proxy_port=8081),
|
||||
make_proxy(proxy_port=8082),
|
||||
]
|
||||
started: list[int] = []
|
||||
release = asyncio.Event()
|
||||
|
||||
async def fake_list_proxies():
|
||||
return proxies
|
||||
|
||||
async def fake_check_proxy(document):
|
||||
started.append(document.proxy_port)
|
||||
if len(started) == len(proxies):
|
||||
release.set()
|
||||
await release.wait()
|
||||
return make_snapshot(document.proxy_port)
|
||||
|
||||
async def fake_record_health_sample(document):
|
||||
return document
|
||||
|
||||
async def fake_publish(_proxy_port, _document):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.list_proxies",
|
||||
fake_list_proxies,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.check_proxy",
|
||||
fake_check_proxy,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.record_health_sample",
|
||||
fake_record_health_sample,
|
||||
)
|
||||
monkeypatch.setattr(monitor, "publish", fake_publish)
|
||||
|
||||
asyncio.run(asyncio.wait_for(monitor.run_cycle(), timeout=1))
|
||||
|
||||
assert started == [8080, 8081, 8082]
|
||||
|
||||
|
||||
def test_run_cycle_continues_when_one_proxy_check_fails(monkeypatch):
|
||||
monitor = HealthMonitor()
|
||||
proxies = [
|
||||
make_proxy(proxy_port=8080),
|
||||
make_proxy(proxy_port=8081),
|
||||
]
|
||||
captured: list[int] = []
|
||||
|
||||
async def fake_list_proxies():
|
||||
return proxies
|
||||
|
||||
async def fake_check_proxy(document):
|
||||
if document.proxy_port == 8080:
|
||||
raise RuntimeError("boom")
|
||||
return make_snapshot(document.proxy_port)
|
||||
|
||||
async def fake_record_health_sample(document):
|
||||
captured.append(document.proxy_port)
|
||||
return document
|
||||
|
||||
async def fake_publish(proxy_port, _document):
|
||||
captured.append(proxy_port + 10_000)
|
||||
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.list_proxies",
|
||||
fake_list_proxies,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.check_proxy",
|
||||
fake_check_proxy,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.record_health_sample",
|
||||
fake_record_health_sample,
|
||||
)
|
||||
monkeypatch.setattr(monitor, "publish", fake_publish)
|
||||
|
||||
asyncio.run(monitor.run_cycle())
|
||||
|
||||
assert captured == [8081, 18081]
|
||||
|
||||
|
||||
def test_run_retries_after_cycle_failure(monkeypatch):
|
||||
monitor = HealthMonitor()
|
||||
calls = {"run_cycle": 0}
|
||||
sleep_calls: list[float] = []
|
||||
|
||||
async def fake_run_cycle():
|
||||
calls["run_cycle"] += 1
|
||||
if calls["run_cycle"] == 1:
|
||||
raise RuntimeError("temporary failure")
|
||||
raise asyncio.CancelledError
|
||||
|
||||
async def fake_sleep(seconds):
|
||||
sleep_calls.append(seconds)
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(monitor, "run_cycle", fake_run_cycle)
|
||||
monkeypatch.setattr(
|
||||
"app.services.mitmproxy.health_monitor.asyncio.sleep",
|
||||
fake_sleep,
|
||||
)
|
||||
|
||||
try:
|
||||
asyncio.run(monitor.run())
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
assert calls["run_cycle"] == 2
|
||||
assert len(sleep_calls) == 1
|
||||
assert sleep_calls[0] == pytest.approx(1.0, abs=0.01)
|
||||
Reference in New Issue
Block a user