Skip to content

Commit

Permalink
Merge branch 'main' into fix-hardcoded-mysql-dialect
Browse files Browse the repository at this point in the history
  • Loading branch information
nightblure authored Nov 27, 2024
2 parents a974a75 + 3e00e71 commit f57013d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 5 deletions.
3 changes: 3 additions & 0 deletions core/testcontainers/compose/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class DockerCompose:
env_file: Optional[str] = None
services: Optional[list[str]] = None
docker_command_path: Optional[str] = None
profiles: Optional[list[str]] = None

def __post_init__(self):
if isinstance(self.compose_file_name, str):
Expand Down Expand Up @@ -198,6 +199,8 @@ def compose_command_property(self) -> list[str]:
if self.compose_file_name:
for file in self.compose_file_name:
docker_compose_cmd += ["-f", file]
if self.profiles:
docker_compose_cmd += [item for profile in self.profiles for item in ["--profile", profile]]
if self.env_file:
docker_compose_cmd += ["--env-file", self.env_file]
return docker_compose_cmd
Expand Down
10 changes: 8 additions & 2 deletions core/testcontainers/core/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from testcontainers.core.config import ConnectionMode
from testcontainers.core.config import testcontainers_config as c
from testcontainers.core.docker_client import DockerClient
from testcontainers.core.exceptions import ContainerStartException
from testcontainers.core.exceptions import ContainerConnectException, ContainerStartException
from testcontainers.core.labels import LABEL_SESSION_ID, SESSION_ID
from testcontainers.core.network import Network
from testcontainers.core.utils import is_arm, setup_logger
Expand Down Expand Up @@ -228,15 +228,21 @@ def _create_instance(cls) -> "Reaper":
.with_env("RYUK_RECONNECTION_TIMEOUT", c.ryuk_reconnection_timeout)
.start()
)
wait_for_logs(Reaper._container, r".* Started!")
wait_for_logs(Reaper._container, r".* Started!", timeout=20, raise_on_exit=True)

container_host = Reaper._container.get_container_host_ip()
container_port = int(Reaper._container.get_exposed_port(8080))

if not container_host or not container_port:
raise ContainerConnectException(
f"Could not obtain network details for {Reaper._container._container.id}. Host: {container_host} Port: {container_port}"
)

last_connection_exception: Optional[Exception] = None
for _ in range(50):
try:
Reaper._socket = socket()
Reaper._socket.settimeout(1)
Reaper._socket.connect((container_host, container_port))
last_connection_exception = None
break
Expand Down
4 changes: 4 additions & 0 deletions core/testcontainers/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class ContainerStartException(RuntimeError):
pass


class ContainerConnectException(RuntimeError):
pass


class ContainerIsNotRunning(RuntimeError):
pass

Expand Down
16 changes: 16 additions & 0 deletions core/tests/compose_fixtures/profile_support/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
services:
runs-always: &simple-service
image: alpine:latest
init: true
command:
- sh
- -c
- 'while true; do sleep 0.1 ; date -Ins; done'
runs-profile-a:
<<: *simple-service
profiles:
- profile-a
runs-profile-b:
<<: *simple-service
profiles:
- profile-b
26 changes: 25 additions & 1 deletion core/tests/test_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path
from re import split
from time import sleep
from typing import Union
from typing import Union, Optional
from urllib.request import urlopen, Request

import pytest
Expand Down Expand Up @@ -352,3 +352,27 @@ def fetch(req: Union[Request, str]):
if 200 < res.getcode() >= 400:
raise Exception(f"HTTP Error: {res.getcode()} - {res.reason}: {body}")
return res.getcode(), body


@pytest.mark.parametrize(
argnames=["profiles", "running", "not_running"],
argvalues=[
pytest.param(None, ["runs-always"], ["runs-profile-a", "runs-profile-b"], id="default"),
pytest.param(
["profile-a"], ["runs-always", "runs-profile-a"], ["runs-profile-b"], id="one-additional-profile-via-str"
),
pytest.param(
["profile-a", "profile-b"],
["runs-always", "runs-profile-a", "runs-profile-b"],
[],
id="all-profiles-explicitly",
),
],
)
def test_compose_profile_support(profiles: Optional[list[str]], running: list[str], not_running: list[str]):
with DockerCompose(context=FIXTURES / "profile_support", profiles=profiles) as compose:
for service in running:
assert compose.get_container(service) is not None
for service in not_running:
with pytest.raises(ContainerIsNotRunning):
compose.get_container(service)
4 changes: 2 additions & 2 deletions modules/generic/testcontainers/generic/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Union
from urllib.error import HTTPError
from urllib.error import HTTPError, URLError
from urllib.request import urlopen

import httpx
Expand Down Expand Up @@ -40,7 +40,7 @@ def __init__(self, port: int, image: Union[str, DockerImage]) -> None:
self.internal_port = port
self.with_exposed_ports(self.internal_port)

@wait_container_is_ready(HTTPError)
@wait_container_is_ready(HTTPError, URLError)
def _connect(self) -> None:
# noinspection HttpUrlsUsage
url = self._create_connection_url()
Expand Down

0 comments on commit f57013d

Please sign in to comment.