feat(phase-5): test debug engineer, live + DB + E2E + docker smoke
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user