From 2654b7d6927e6aa55aaf6efb966e6f2d5323c675 Mon Sep 17 00:00:00 2001 From: David Ankin Date: Sat, 9 Mar 2024 11:56:25 -0500 Subject: [PATCH 1/2] fix: DockerCompose.get_service_host returning unusable "0.0.0.0" --- core/testcontainers/compose/compose.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/testcontainers/compose/compose.py b/core/testcontainers/compose/compose.py index d59e683bf..1aac09508 100644 --- a/core/testcontainers/compose/compose.py +++ b/core/testcontainers/compose/compose.py @@ -2,6 +2,7 @@ from functools import cached_property from json import loads from os import PathLike +from platform import system from re import split from subprocess import CompletedProcess from subprocess import run as subprocess_run @@ -378,7 +379,15 @@ def get_service_host( str: The hostname for the service """ - return self.get_container(service_name).get_publisher(by_port=port).URL + url = self.get_container(service_name).get_publisher(by_port=port).URL + url = self._normalize_url(url) + return url + + def _normalize_url(self, url: str): + # reproducible on docker 24.0.7 on windows + if system() == "Windows" and url == "0.0.0.0": + url = "127.0.0.1" + return url def get_service_host_and_port( self, @@ -386,7 +395,8 @@ def get_service_host_and_port( port: Optional[int] = None, ): publisher = self.get_container(service_name).get_publisher(by_port=port) - return publisher.URL, publisher.PublishedPort + url = self._normalize_url(publisher.URL) + return url, publisher.PublishedPort @wait_container_is_ready(HTTPError, URLError) def wait_for(self, url: str) -> "DockerCompose": From 8b1b44c74f8bf9e8581efd8441b7307f66270a07 Mon Sep 17 00:00:00 2001 From: David Ankin Date: Wed, 13 Mar 2024 22:42:40 -0400 Subject: [PATCH 2/2] slight adjustment --- core/testcontainers/compose/compose.py | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/core/testcontainers/compose/compose.py b/core/testcontainers/compose/compose.py index 1aac09508..029e6d91e 100644 --- a/core/testcontainers/compose/compose.py +++ b/core/testcontainers/compose/compose.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, field, fields +from dataclasses import asdict, dataclass, field, fields from functools import cached_property from json import loads from os import PathLike @@ -39,6 +39,14 @@ class PublishedPort: PublishedPort: Optional[str] = None Protocol: Optional[str] = None + def normalize(self): + url_not_usable = system() == "Windows" and self.URL == "0.0.0.0" + if url_not_usable: + self_dict = asdict(self) + self_dict.update({"URL": "127.0.0.1"}) + return PublishedPort(**self_dict) + return self + OT = TypeVar("OT") @@ -357,7 +365,7 @@ def get_service_port( str: The mapped port on the host """ - return self.get_container(service_name).get_publisher(by_port=port).PublishedPort + return self.get_container(service_name).get_publisher(by_port=port).normalize().PublishedPort def get_service_host( self, @@ -379,24 +387,15 @@ def get_service_host( str: The hostname for the service """ - url = self.get_container(service_name).get_publisher(by_port=port).URL - url = self._normalize_url(url) - return url - - def _normalize_url(self, url: str): - # reproducible on docker 24.0.7 on windows - if system() == "Windows" and url == "0.0.0.0": - url = "127.0.0.1" - return url + return self.get_container(service_name).get_publisher(by_port=port).normalize().URL def get_service_host_and_port( self, service_name: Optional[str] = None, port: Optional[int] = None, ): - publisher = self.get_container(service_name).get_publisher(by_port=port) - url = self._normalize_url(publisher.URL) - return url, publisher.PublishedPort + publisher = self.get_container(service_name).get_publisher(by_port=port).normalize() + return publisher.URL, publisher.PublishedPort @wait_container_is_ready(HTTPError, URLError) def wait_for(self, url: str) -> "DockerCompose":