Private
Public Access
test(docker): add Docker Desktop auto-start and detection
This commit is contained in:
+75
-15
@@ -2,6 +2,7 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -14,14 +15,82 @@ WEB_PORT = 18080
|
|||||||
HOOK_PORT = 18999
|
HOOK_PORT = 18999
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.docker
|
def _docker_daemon_ready() -> bool:
|
||||||
def test_docker_image_builds(tmp_path):
|
result = subprocess.run(
|
||||||
"""Build the Docker image. Slow; opt-in."""
|
["docker", "info"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def _start_docker_desktop() -> bool:
|
||||||
|
if sys.platform != "win32":
|
||||||
|
return False
|
||||||
|
docker_paths = [
|
||||||
|
os.path.expandvars(r"%ProgramFiles%\Docker\Docker\Docker Desktop.exe"),
|
||||||
|
os.path.expandvars(r"%LOCALAPPDATA%\Docker\Docker Desktop.exe"),
|
||||||
|
r"C:\Program Files\Docker\Docker\Docker Desktop.exe",
|
||||||
|
r"C:\Users\Ed\AppData\Local\Docker\Docker Desktop.exe",
|
||||||
|
]
|
||||||
|
for path in docker_paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
try:
|
||||||
|
subprocess.Popen([path], shell=False)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
service_result = subprocess.run(
|
||||||
|
["net", "start", "com.docker.service"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
if service_result.returncode == 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _wait_for_docker(timeout: int = 60) -> bool:
|
||||||
|
start = time.time()
|
||||||
|
while time.time() - start < timeout:
|
||||||
|
if _docker_daemon_ready():
|
||||||
|
return True
|
||||||
|
time.sleep(2)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def ensure_docker():
|
||||||
|
"""Ensure Docker daemon is running before running tests."""
|
||||||
if os.environ.get("RUN_DOCKER_TEST") != "1":
|
if os.environ.get("RUN_DOCKER_TEST") != "1":
|
||||||
pytest.skip("Set RUN_DOCKER_TEST=1 to enable")
|
pytest.skip("Set RUN_DOCKER_TEST=1 to enable")
|
||||||
if not _docker_available():
|
|
||||||
pytest.skip("Docker not available in this environment")
|
|
||||||
|
|
||||||
|
if not shutil.which("docker"):
|
||||||
|
pytest.skip("Docker CLI not installed")
|
||||||
|
|
||||||
|
if _docker_daemon_ready():
|
||||||
|
yield
|
||||||
|
return
|
||||||
|
|
||||||
|
started = _start_docker_desktop()
|
||||||
|
if not started:
|
||||||
|
pytest.skip(
|
||||||
|
"Docker daemon not running and Docker Desktop not found/installed. "
|
||||||
|
"Please install Docker Desktop on this system."
|
||||||
|
)
|
||||||
|
|
||||||
|
ready = _wait_for_docker()
|
||||||
|
if not ready:
|
||||||
|
pytest.skip("Docker daemon did not become ready within 60s")
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.docker
|
||||||
|
def test_docker_image_builds(ensure_docker, tmp_path):
|
||||||
|
"""Build the Docker image. Slow; opt-in."""
|
||||||
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["docker", "build", "-t", IMAGE_NAME, "."],
|
["docker", "build", "-t", IMAGE_NAME, "."],
|
||||||
@@ -32,13 +101,8 @@ def test_docker_image_builds(tmp_path):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.docker
|
@pytest.mark.docker
|
||||||
def test_docker_container_starts_and_responds():
|
def test_docker_container_starts_and_responds(ensure_docker):
|
||||||
"""Run the container, verify web and hook endpoints respond."""
|
"""Run the container, verify web and hook endpoints respond."""
|
||||||
if os.environ.get("RUN_DOCKER_TEST") != "1":
|
|
||||||
pytest.skip("Set RUN_DOCKER_TEST=1 to enable")
|
|
||||||
if not _docker_available():
|
|
||||||
pytest.skip("Docker not available in this environment")
|
|
||||||
|
|
||||||
_cleanup_container()
|
_cleanup_container()
|
||||||
|
|
||||||
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
@@ -78,10 +142,6 @@ def test_docker_container_starts_and_responds():
|
|||||||
_cleanup_container()
|
_cleanup_container()
|
||||||
|
|
||||||
|
|
||||||
def _docker_available() -> bool:
|
|
||||||
return shutil.which("docker") is not None
|
|
||||||
|
|
||||||
|
|
||||||
def _cleanup_container() -> None:
|
def _cleanup_container() -> None:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["docker", "rm", "-f", CONTAINER_NAME],
|
["docker", "rm", "-f", CONTAINER_NAME],
|
||||||
|
|||||||
Reference in New Issue
Block a user