summaryrefslogtreecommitdiff
path: root/shared/tests
diff options
context:
space:
mode:
Diffstat (limited to 'shared/tests')
-rw-r--r--shared/tests/test_healthcheck.py88
-rw-r--r--shared/tests/test_metrics.py51
2 files changed, 139 insertions, 0 deletions
diff --git a/shared/tests/test_healthcheck.py b/shared/tests/test_healthcheck.py
new file mode 100644
index 0000000..1af86b1
--- /dev/null
+++ b/shared/tests/test_healthcheck.py
@@ -0,0 +1,88 @@
+"""Tests for health check server."""
+import pytest
+import asyncio
+from prometheus_client import CollectorRegistry
+
+
+@pytest.fixture
+def registry():
+ return CollectorRegistry()
+
+
+def make_server(service_name="test-service", port=8080, registry=None):
+ from shared.healthcheck import HealthCheckServer
+ return HealthCheckServer(service_name, port=port, registry=registry)
+
+
+def test_init_defaults(registry):
+ """HealthCheckServer initialises with service name and port."""
+ server = make_server("my-service", registry=registry)
+ assert server.service_name == "my-service"
+ assert server.port == 8080
+ assert server._checks == {}
+
+
+def test_register_check(registry):
+ """register_check stores an async callable."""
+ server = make_server(registry=registry)
+
+ async def check_redis():
+ return True
+
+ server.register_check("redis", check_redis)
+ assert "redis" in server._checks
+ assert server._checks["redis"] is check_redis
+
+
+@pytest.mark.asyncio
+async def test_run_checks_all_pass(registry):
+ """run_checks returns 'ok' when all checks pass."""
+ server = make_server(registry=registry)
+
+ async def ok_check():
+ return True
+
+ server.register_check("db", ok_check)
+ server.register_check("redis", ok_check)
+
+ result = await server.run_checks()
+ assert result["status"] == "ok"
+ assert result["service"] == "test-service"
+ assert "uptime_seconds" in result
+ assert result["checks"]["db"] == "ok"
+ assert result["checks"]["redis"] == "ok"
+
+
+@pytest.mark.asyncio
+async def test_run_checks_one_fails(registry):
+ """run_checks returns 'degraded' when a check fails."""
+ server = make_server(registry=registry)
+
+ async def ok_check():
+ return True
+
+ async def bad_check():
+ raise ConnectionError("down")
+
+ server.register_check("db", ok_check)
+ server.register_check("redis", bad_check)
+
+ result = await server.run_checks()
+ assert result["status"] == "degraded"
+ assert result["checks"]["db"] == "ok"
+ assert "fail" in result["checks"]["redis"]
+
+
+@pytest.mark.asyncio
+async def test_run_checks_false_is_fail(registry):
+ """run_checks treats False return as failure."""
+ server = make_server(registry=registry)
+
+ async def false_check():
+ return False
+
+ server.register_check("cache", false_check)
+
+ result = await server.run_checks()
+ assert result["status"] == "degraded"
+ assert result["checks"]["cache"] == "fail"
diff --git a/shared/tests/test_metrics.py b/shared/tests/test_metrics.py
new file mode 100644
index 0000000..079f01c
--- /dev/null
+++ b/shared/tests/test_metrics.py
@@ -0,0 +1,51 @@
+"""Tests for Prometheus metrics utilities."""
+import pytest
+from prometheus_client import CollectorRegistry
+
+
+def make_metrics(service_name="test-service", registry=None):
+ from shared.metrics import ServiceMetrics
+ return ServiceMetrics(service_name, registry=registry)
+
+
+def test_metrics_creates_with_prefix():
+ """ServiceMetrics stores sanitized service name prefix."""
+ registry = CollectorRegistry()
+ m = make_metrics("my-service", registry=registry)
+ assert m.service_name == "my_service"
+
+
+def test_errors_total_increment():
+ """errors_total counter can be incremented with labels."""
+ registry = CollectorRegistry()
+ m = make_metrics("test-svc", registry=registry)
+ m.errors_total.labels(service="test_svc", error_type="timeout").inc()
+ assert m.errors_total.labels(service="test_svc", error_type="timeout")._value.get() == 1.0
+
+
+def test_events_processed_increment():
+ """events_processed counter can be incremented with labels."""
+ registry = CollectorRegistry()
+ m = make_metrics("test-svc", registry=registry)
+ m.events_processed.labels(service="test_svc", event_type="candle").inc(5)
+ assert m.events_processed.labels(service="test_svc", event_type="candle")._value.get() == 5.0
+
+
+def test_processing_seconds_observe():
+ """processing_seconds histogram can observe values."""
+ registry = CollectorRegistry()
+ m = make_metrics("test-svc", registry=registry)
+ m.processing_seconds.labels(service="test_svc").observe(0.5)
+ m.processing_seconds.labels(service="test_svc").observe(1.5)
+ # Sum should be 2.0
+ assert m.processing_seconds.labels(service="test_svc")._sum.get() == 2.0
+
+
+def test_service_up_gauge():
+ """service_up gauge can be set."""
+ registry = CollectorRegistry()
+ m = make_metrics("test-svc", registry=registry)
+ m.service_up.labels(service="test_svc").set(1)
+ assert m.service_up.labels(service="test_svc")._value.get() == 1.0
+ m.service_up.labels(service="test_svc").set(0)
+ assert m.service_up.labels(service="test_svc")._value.get() == 0.0