from pathlib import Path import yaml PROJECT_ROOT = Path(__file__).resolve().parents[2] COMPOSE_FILE = PROJECT_ROOT / "docker-compose.yml" INFRA_README = PROJECT_ROOT / "infra" / "README.md" DEPLOY_WORKFLOW = PROJECT_ROOT / ".gitea" / "workflows" / "deploy.yml" COLLECTOR_TEMPLATE = PROJECT_ROOT / "otel-collector-config.template.yaml" def _load_compose() -> dict: content = yaml.safe_load(COMPOSE_FILE.read_text(encoding="utf-8")) assert isinstance(content, dict) return content def test_compose_defines_required_services() -> None: compose = _load_compose() services = compose.get("services") assert isinstance(services, dict) assert {"app", "redis", "postgres"}.issubset(services.keys()) assert "postgres" in services["app"]["depends_on"] def test_smoke_command_sequence_is_documented() -> None: readme = INFRA_README.read_text(encoding="utf-8") assert "docker compose config" in readme assert "docker compose up -d redis" in readme assert "docker compose ps" in readme def test_deploy_recreates_collector_after_config_update() -> None: workflow = DEPLOY_WORKFLOW.read_text(encoding="utf-8") recreate_command = ( "docker compose -p $COMPOSE_PROJECT up -d --force-recreate otel-collector" ) application_command = "docker compose -p $COMPOSE_PROJECT up -d" assert recreate_command in workflow assert workflow.index(recreate_command) < workflow.rindex(application_command) def test_collector_promotes_log_trace_attributes_to_trace_context() -> None: config = yaml.safe_load(COLLECTOR_TEMPLATE.read_text(encoding="utf-8")) operators = config["receivers"]["filelog"]["operators"] trace_parser = next( operator for operator in operators if operator["type"] == "trace_parser" ) assert trace_parser["trace_id"]["parse_from"] == "attributes.trace_id" assert trace_parser["span_id"]["parse_from"] == "attributes.span_id"