Skip to content

Commit f57013d

Browse files
authored
Merge branch 'main' into fix-hardcoded-mysql-dialect
2 parents a974a75 + 3e00e71 commit f57013d

File tree

6 files changed

+58
-5
lines changed

6 files changed

+58
-5
lines changed

core/testcontainers/compose/compose.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class DockerCompose:
171171
env_file: Optional[str] = None
172172
services: Optional[list[str]] = None
173173
docker_command_path: Optional[str] = None
174+
profiles: Optional[list[str]] = None
174175

175176
def __post_init__(self):
176177
if isinstance(self.compose_file_name, str):
@@ -198,6 +199,8 @@ def compose_command_property(self) -> list[str]:
198199
if self.compose_file_name:
199200
for file in self.compose_file_name:
200201
docker_compose_cmd += ["-f", file]
202+
if self.profiles:
203+
docker_compose_cmd += [item for profile in self.profiles for item in ["--profile", profile]]
201204
if self.env_file:
202205
docker_compose_cmd += ["--env-file", self.env_file]
203206
return docker_compose_cmd

core/testcontainers/core/container.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from testcontainers.core.config import ConnectionMode
1313
from testcontainers.core.config import testcontainers_config as c
1414
from testcontainers.core.docker_client import DockerClient
15-
from testcontainers.core.exceptions import ContainerStartException
15+
from testcontainers.core.exceptions import ContainerConnectException, ContainerStartException
1616
from testcontainers.core.labels import LABEL_SESSION_ID, SESSION_ID
1717
from testcontainers.core.network import Network
1818
from testcontainers.core.utils import is_arm, setup_logger
@@ -228,15 +228,21 @@ def _create_instance(cls) -> "Reaper":
228228
.with_env("RYUK_RECONNECTION_TIMEOUT", c.ryuk_reconnection_timeout)
229229
.start()
230230
)
231-
wait_for_logs(Reaper._container, r".* Started!")
231+
wait_for_logs(Reaper._container, r".* Started!", timeout=20, raise_on_exit=True)
232232

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

236+
if not container_host or not container_port:
237+
raise ContainerConnectException(
238+
f"Could not obtain network details for {Reaper._container._container.id}. Host: {container_host} Port: {container_port}"
239+
)
240+
236241
last_connection_exception: Optional[Exception] = None
237242
for _ in range(50):
238243
try:
239244
Reaper._socket = socket()
245+
Reaper._socket.settimeout(1)
240246
Reaper._socket.connect((container_host, container_port))
241247
last_connection_exception = None
242248
break

core/testcontainers/core/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ class ContainerStartException(RuntimeError):
1616
pass
1717

1818

19+
class ContainerConnectException(RuntimeError):
20+
pass
21+
22+
1923
class ContainerIsNotRunning(RuntimeError):
2024
pass
2125

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
services:
2+
runs-always: &simple-service
3+
image: alpine:latest
4+
init: true
5+
command:
6+
- sh
7+
- -c
8+
- 'while true; do sleep 0.1 ; date -Ins; done'
9+
runs-profile-a:
10+
<<: *simple-service
11+
profiles:
12+
- profile-a
13+
runs-profile-b:
14+
<<: *simple-service
15+
profiles:
16+
- profile-b

core/tests/test_compose.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pathlib import Path
33
from re import split
44
from time import sleep
5-
from typing import Union
5+
from typing import Union, Optional
66
from urllib.request import urlopen, Request
77

88
import pytest
@@ -352,3 +352,27 @@ def fetch(req: Union[Request, str]):
352352
if 200 < res.getcode() >= 400:
353353
raise Exception(f"HTTP Error: {res.getcode()} - {res.reason}: {body}")
354354
return res.getcode(), body
355+
356+
357+
@pytest.mark.parametrize(
358+
argnames=["profiles", "running", "not_running"],
359+
argvalues=[
360+
pytest.param(None, ["runs-always"], ["runs-profile-a", "runs-profile-b"], id="default"),
361+
pytest.param(
362+
["profile-a"], ["runs-always", "runs-profile-a"], ["runs-profile-b"], id="one-additional-profile-via-str"
363+
),
364+
pytest.param(
365+
["profile-a", "profile-b"],
366+
["runs-always", "runs-profile-a", "runs-profile-b"],
367+
[],
368+
id="all-profiles-explicitly",
369+
),
370+
],
371+
)
372+
def test_compose_profile_support(profiles: Optional[list[str]], running: list[str], not_running: list[str]):
373+
with DockerCompose(context=FIXTURES / "profile_support", profiles=profiles) as compose:
374+
for service in running:
375+
assert compose.get_container(service) is not None
376+
for service in not_running:
377+
with pytest.raises(ContainerIsNotRunning):
378+
compose.get_container(service)

modules/generic/testcontainers/generic/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from typing import Union
2-
from urllib.error import HTTPError
2+
from urllib.error import HTTPError, URLError
33
from urllib.request import urlopen
44

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

43-
@wait_container_is_ready(HTTPError)
43+
@wait_container_is_ready(HTTPError, URLError)
4444
def _connect(self) -> None:
4545
# noinspection HttpUrlsUsage
4646
url = self._create_connection_url()

0 commit comments

Comments
 (0)