Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions core/testcontainers/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import docker

ENABLE_FLAGS = ("yes", "true", "t", "y", "1")


class ConnectionMode(Enum):
bridge_ip = "bridge_ip"
Expand Down Expand Up @@ -45,16 +47,6 @@ def get_docker_socket() -> str:
return "/var/run/docker.sock"


def get_bool_env(name: str) -> bool:
"""
Get environment variable named `name` and convert it to bool.

Defaults to False.
"""
value = environ.get(name, "")
return value.lower() in ("yes", "true", "t", "y", "1")


TC_FILE = ".testcontainers.properties"
TC_GLOBAL = Path.home() / TC_FILE

Expand Down Expand Up @@ -96,11 +88,20 @@ def read_tc_properties() -> dict[str, str]:

@dataclass
class TestcontainersConfiguration:
def _render_bool(self, env_name: str, prop_name: str) -> bool:
env_val = environ.get(env_name, None)
if env_val is not None:
return env_val.lower() in ENABLE_FLAGS
prop_val = self.tc_properties.get(prop_name, None)
if prop_val is not None:
return prop_val.lower() in ENABLE_FLAGS
return False

max_tries: int = int(environ.get("TC_MAX_TRIES", "120"))
sleep_time: float = float(environ.get("TC_POOLING_INTERVAL", "1"))
ryuk_image: str = environ.get("RYUK_CONTAINER_IMAGE", "testcontainers/ryuk:0.8.1")
ryuk_privileged: bool = get_bool_env("TESTCONTAINERS_RYUK_PRIVILEGED")
ryuk_disabled: bool = get_bool_env("TESTCONTAINERS_RYUK_DISABLED")
_ryuk_privileged: Optional[bool] = None
_ryuk_disabled: Optional[bool] = None
_ryuk_docker_socket: str = ""
ryuk_reconnection_timeout: str = environ.get("RYUK_RECONNECTION_TIMEOUT", "10s")
tc_properties: dict[str, str] = field(default_factory=read_tc_properties)
Expand Down Expand Up @@ -129,6 +130,28 @@ def docker_auth_config(self, value: str) -> None:
def tc_properties_get_tc_host(self) -> Union[str, None]:
return self.tc_properties.get("tc.host")

@property
def ryuk_privileged(self) -> bool:
if self._ryuk_privileged is not None:
return bool(self._ryuk_privileged)
self._ryuk_privileged = self._render_bool("TESTCONTAINERS_RYUK_PRIVILEGED", "ryuk.container.privileged")
return self._ryuk_privileged

@ryuk_privileged.setter
def ryuk_privileged(self, value: bool) -> None:
self._ryuk_privileged = value

@property
def ryuk_disabled(self) -> bool:
if self._ryuk_disabled is not None:
return bool(self._ryuk_disabled)
self._ryuk_disabled = self._render_bool("TESTCONTAINERS_RYUK_DISABLED", "ryuk.disabled")
return self._ryuk_disabled

@ryuk_disabled.setter
def ryuk_disabled(self, value: bool) -> None:
self._ryuk_disabled = value

@property
def timeout(self) -> float:
return self.max_tries * self.sleep_time
Expand Down
62 changes: 62 additions & 0 deletions core/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,68 @@ def test_read_tc_properties(monkeypatch: MonkeyPatch) -> None:
assert config.tc_properties == {"tc.host": "some_value"}


def test_set_tc_properties(monkeypatch: MonkeyPatch) -> None:
"""
Ensure the configuration file variables can be read if no environment variable is set
"""
with tempfile.TemporaryDirectory() as tmpdirname:
file = f"{tmpdirname}/{TC_FILE}"
with open(file, "w") as f:
f.write("ryuk.disabled=true\n")
f.write("ryuk.container.privileged=false\n")

monkeypatch.setattr("testcontainers.core.config.TC_GLOBAL", file)

config = TCC()

assert config.ryuk_disabled == True
assert config.ryuk_privileged == False


def test_override_tc_properties_1(monkeypatch: MonkeyPatch) -> None:
"""
Ensure that we can re-set the configuration variables programattically to override
testcontainers.properties
"""
with tempfile.TemporaryDirectory() as tmpdirname:
file = f"{tmpdirname}/{TC_FILE}"
with open(file, "w") as f:
f.write("ryuk.disabled=true\n")
f.write("ryuk.container.privileged=false\n")

monkeypatch.setattr("testcontainers.core.config.TC_GLOBAL", file)

config = TCC()
config.ryuk_disabled = False
config.ryuk_privileged = True

assert config.ryuk_disabled == False
assert config.ryuk_privileged == True


def test_override_tc_properties_2(monkeypatch: MonkeyPatch) -> None:
"""
Ensure that we can override the testcontainers.properties with environment variables
"""
with tempfile.TemporaryDirectory() as tmpdirname:
file = f"{tmpdirname}/{TC_FILE}"
with open(file, "w") as f:
f.write("ryuk.disabled=true\n")
f.write("ryuk.container.privileged=false\n")

monkeypatch.setattr("testcontainers.core.config.TC_GLOBAL", file)

import os

os.environ["TESTCONTAINERS_RYUK_DISABLED"] = "false"
os.environ["TESTCONTAINERS_RYUK_PRIVILEGED"] = "true"

config = TCC()

assert config.ryuk_disabled == False
assert config.ryuk_privileged == True


@mark.parametrize("docker_auth_config_env", ["key=value", ""])
@mark.parametrize("warning_dict", [{}, {"key": "value"}, {"DOCKER_AUTH_CONFIG": "TEST"}])
@mark.parametrize("warning_dict_post", [{}, {"key": "value"}, {"DOCKER_AUTH_CONFIG": "TEST"}])
Expand Down