2021-04-13 17:30:24 -07:00
|
|
|
import contextlib
|
|
|
|
import subprocess
|
2022-07-07 08:28:34 -07:00
|
|
|
from typing import Callable, Optional, Union
|
2021-04-13 17:30:24 -07:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
import pytest_docker.plugin
|
|
|
|
|
|
|
|
|
2021-08-11 15:47:18 -07:00
|
|
|
def is_responsive(container_name: str, port: int, hostname: Optional[str]) -> bool:
|
|
|
|
"""A cheap way to figure out if a port is responsive on a container"""
|
|
|
|
if hostname:
|
|
|
|
cmd = f"docker exec {container_name} /bin/bash -c 'echo -n > /dev/tcp/{hostname}/{port}'"
|
|
|
|
else:
|
|
|
|
# use the hostname of the container
|
|
|
|
cmd = f"docker exec {container_name} /bin/bash -c 'c_host=`hostname`;echo -n > /dev/tcp/$c_host/{port}'"
|
2021-04-13 17:30:24 -07:00
|
|
|
ret = subprocess.run(
|
2021-08-11 15:47:18 -07:00
|
|
|
cmd,
|
2021-04-13 17:30:24 -07:00
|
|
|
shell=True,
|
|
|
|
)
|
|
|
|
return ret.returncode == 0
|
|
|
|
|
|
|
|
|
|
|
|
def wait_for_port(
|
|
|
|
docker_services: pytest_docker.plugin.Services,
|
|
|
|
container_name: str,
|
|
|
|
container_port: int,
|
2022-12-02 13:53:28 -05:00
|
|
|
hostname: Optional[str] = None,
|
2021-04-14 19:25:57 -07:00
|
|
|
timeout: float = 30.0,
|
2022-05-26 12:42:50 +02:00
|
|
|
pause: float = 0.5,
|
2022-07-07 08:28:34 -07:00
|
|
|
checker: Optional[Callable[[], bool]] = None,
|
2021-04-14 13:40:24 -07:00
|
|
|
) -> None:
|
2021-06-22 17:05:08 -07:00
|
|
|
try:
|
|
|
|
docker_services.wait_until_responsive(
|
|
|
|
timeout=timeout,
|
2022-05-26 12:42:50 +02:00
|
|
|
pause=pause,
|
2022-07-07 08:28:34 -07:00
|
|
|
check=checker
|
|
|
|
if checker
|
|
|
|
else lambda: is_responsive(container_name, container_port, hostname),
|
2021-06-22 17:05:08 -07:00
|
|
|
)
|
|
|
|
finally:
|
|
|
|
# use check=True to raise an error if command gave bad exit code
|
|
|
|
subprocess.run(f"docker logs {container_name}", shell=True, check=True)
|
2021-04-13 17:30:24 -07:00
|
|
|
|
|
|
|
|
2022-02-02 22:52:50 -08:00
|
|
|
@pytest.fixture(scope="module")
|
2022-10-15 01:59:40 +00:00
|
|
|
def docker_compose_runner(
|
|
|
|
docker_compose_command, docker_compose_project_name, docker_setup, docker_cleanup
|
|
|
|
):
|
2021-04-13 17:30:24 -07:00
|
|
|
@contextlib.contextmanager
|
2021-11-04 03:33:05 +05:30
|
|
|
def run(
|
|
|
|
compose_file_path: Union[str, list], key: str
|
|
|
|
) -> pytest_docker.plugin.Services:
|
2021-06-16 16:59:28 -07:00
|
|
|
with pytest_docker.plugin.get_docker_services(
|
2022-10-15 01:59:40 +00:00
|
|
|
docker_compose_command=docker_compose_command,
|
|
|
|
docker_compose_file=compose_file_path,
|
|
|
|
docker_compose_project_name=f"{docker_compose_project_name}-{key}",
|
|
|
|
docker_setup=docker_setup,
|
|
|
|
docker_cleanup=docker_cleanup,
|
2021-06-16 16:59:28 -07:00
|
|
|
) as docker_services:
|
|
|
|
yield docker_services
|
2021-04-13 17:30:24 -07:00
|
|
|
|
|
|
|
return run
|