"""Docker smoke test: build + run + healthcheck. If Docker is not available, the test is skipped with a clear reason. """ from __future__ import annotations import shutil import subprocess import time import pytest def _docker_available() -> bool: """Check if Docker daemon is reachable.""" if shutil.which("docker") is None: return False try: subprocess.run( ["docker", "info"], capture_output=True, timeout=5, check=True ) return True except (subprocess.SubprocessError, FileNotFoundError): return False @pytest.mark.skipif( not _docker_available(), reason="Docker daemon not available or docker CLI not found", ) def test_docker_build_and_healthcheck() -> None: """Build the CRM image, run it briefly, and curl the health endpoint.""" project_dir = "/a0/.a0/crm-system" # 1. Build build_result = subprocess.run( ["docker", "build", "-t", "crm-system:test", project_dir], capture_output=True, text=True, timeout=300, ) assert build_result.returncode == 0, f"docker build failed:\n{build_result.stderr}" # 2. Run container on exposed port 8765 → internal 8000 container_name = "crm-smoke-test" run_result = subprocess.run( [ "docker", "run", "--rm", "--detach", "--name", container_name, "-p", "8765:8000", "crm-system:test", ], capture_output=True, text=True, timeout=30, ) assert run_result.returncode == 0, f"docker run failed:\n{run_result.stderr}" container_id = run_result.stdout.strip() # 3. Wait a moment, then curl /health try: time.sleep(5) # give uvicorn + alembic time curl_result = subprocess.run( ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "http://localhost:8765/health"], capture_output=True, text=True, timeout=10, ) status = curl_result.stdout.strip() assert status == "200", f"Health check returned HTTP {status}" finally: # 4. Stop container subprocess.run( ["docker", "stop", container_id], capture_output=True, timeout=15, ) def test_docker_not_available_is_reported() -> None: """Document Docker availability in a non-skipped test so pytest reports it.""" if not _docker_available(): pytest.skip("Docker is not installed or the daemon is unreachable. " "Docker smoke test was skipped. " "Install Docker CE 24+ to run container-level tests.") else: # Docker is available – nothing to assert here. pass