from __future__ import annotations import json import re from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def read(relative: str) -> str: return (ROOT / relative).read_text(encoding="utf-8") def service_block(compose: str, name: str) -> str: match = re.search( rf"^ {re.escape(name)}:\n(?P(?:^(?: |\s*$).*\n?)*)", compose, re.MULTILINE, ) assert match, f"missing Compose service {name}" return match.group("body") def test_collector_has_only_approved_prometheus_targets() -> None: config = read("observability/otel-collector.yaml") targets = re.findall(r'targets: \["([^"]+)"\]', config) assert targets == [ "127.0.0.1:8888", "redis-exporter:9121", "nginx-exporter:9113", ] assert "service_name: otel-collector" in config assert "service_name: redis" in config assert "service_name: nginx" in config assert "hostmetrics:" in config assert "service.namespace, value: han-chat" in config assert "filter/noise:" in config assert "tail_sampling:" in config def test_logs_are_direct_otlp_without_filelog() -> None: config = read("observability/otel-collector.yaml") logs = config.split(" logs:\n", 1)[1] assert "receivers: [otlp]" in logs assert "otlp/remote" in logs assert "filelog" not in config def test_apps_receive_release_and_logging_context() -> None: compose = read("docker-compose.yml") assert compose.count("RELEASE_VERSION: ${RELEASE_VERSION:?set RELEASE_VERSION}") >= 3 assert compose.count("LOG_LEVEL: ${LOG_LEVEL:-INFO}") == 2 def test_collector_exposes_health_and_self_metrics_and_validates_config() -> None: compose = read("docker-compose.yml") collector = service_block(compose, "otel-collector") assert 'expose: ["4317", "4318", "13133", "8888"]' in collector assert '"/otelcol-contrib", "validate"' in collector def test_exporters_are_internal_only_and_digest_pinned() -> None: compose = read("docker-compose.yml") for name, port in (("redis-exporter", "9121"), ("nginx-exporter", "9113")): block = service_block(compose, name) assert f'expose: ["{port}"]' in block assert "\n ports:" not in block assert "observability" in block assert "${REDIS_EXPORTER_IMAGE:?set immutable Redis exporter image digest}" in compose assert "${NGINX_EXPORTER_IMAGE:?set immutable nginx exporter image digest}" in compose def test_nginx_status_is_internal_and_query_free() -> None: template = read("nginx/templates/10-vm2.conf.template") status = template.split("location = /stub_status", 1)[1].split("}", 1)[0] assert "stub_status;" in status assert "access_log off;" in status assert "listen 8081;" in template assert ":8081:8081" not in read("docker-compose.yml") def test_redis_exporter_uses_restricted_acl_and_secret_file() -> None: acl = read("redis/redis-safety.acl.template") compose = read("docker-compose.yml") secret_config = json.loads(read("deployment/secrets/config.example.json")) exporter_line = next(line for line in acl.splitlines() if line.startswith("user exporter ")) assert "-@all +ping +info" in exporter_line assert "~*" not in exporter_line assert "REDIS_PASSWORD_FILE: /run/secrets/redis_exporter_password" in compose assert secret_config["secrets"]["REDIS_EXPORTER_PASSWORD"]["consumers"] == [ "redis-exporter" ] def test_self_hosted_signoz_does_not_require_fake_auth() -> None: collector = read("observability/otel-collector.yaml") env_example = read(".env.example") assert "OTEL_REMOTE_AUTH" not in collector assert "OTEL_REMOTE_AUTH" not in env_example assert "headers:" not in collector def test_preflight_covers_observability_images_and_acl_pair() -> None: preflight = read("deployment/preflight.sh") assert "REDIS_EXPORTER_IMAGE NGINX_EXPORTER_IMAGE" in preflight assert "REDIS_EXPORTER_PASSWORD" in preflight assert 'target = "redis://redis-safety:6379"' in preflight assert "Redis exporter password map does not match REDIS_SAFETY_ACL" in preflight assert "Collector must enforce service.namespace=han-chat" in preflight assert "Collector direct OTLP logs pipeline is missing" in preflight assert "Collector filelog receiver is forbidden" in preflight