diff --git a/core/testcontainers/core/config.py b/core/testcontainers/core/config.py index e8a330c1..0f960b02 100644 --- a/core/testcontainers/core/config.py +++ b/core/testcontainers/core/config.py @@ -15,7 +15,6 @@ RYUK_DOCKER_SOCKET: str = environ.get("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock") RYUK_RECONNECTION_TIMEOUT: str = environ.get("RYUK_RECONNECTION_TIMEOUT", "10s") TC_HOST_OVERRIDE: Optional[str] = environ.get("TC_HOST", environ.get("TESTCONTAINERS_HOST_OVERRIDE")) -REUSE_ENABLED: bool = environ.get("TESTCONTAINERS_REUSE_ENABLED", "false") == "true" TC_FILE = ".testcontainers.properties" TC_GLOBAL = Path.home() / TC_FILE @@ -58,7 +57,6 @@ class TestcontainersConfiguration: tc_properties: dict[str, str] = field(default_factory=read_tc_properties) _docker_auth_config: Optional[str] = field(default_factory=lambda: environ.get("DOCKER_AUTH_CONFIG")) tc_host_override: Optional[str] = TC_HOST_OVERRIDE - reuse_enabled: bool = REUSE_ENABLED """ https://github.com/testcontainers/testcontainers-go/blob/dd76d1e39c654433a3d80429690d07abcec04424/docker.go#L644 if os env TC_HOST is set, use it @@ -87,8 +85,8 @@ def tc_properties_tc_host(self) -> Union[str, None]: return self.tc_properties.get("tc.host") @property - def tc_properties_testcontainers_reuse_enabled(self) -> bool: - enabled = self.tc_properties.get("testcontainers.reuse.enabled") + def tc_properties_testcontainers_reuse_enable(self) -> bool: + enabled = self.tc_properties.get("testcontainers.reuse.enable") return enabled == "true" @property diff --git a/core/testcontainers/core/container.py b/core/testcontainers/core/container.py index 83539ba7..caa4c61e 100644 --- a/core/testcontainers/core/container.py +++ b/core/testcontainers/core/container.py @@ -1,5 +1,6 @@ import contextlib import hashlib +import logging from platform import system from socket import socket from typing import TYPE_CHECKING, Optional @@ -50,7 +51,7 @@ def __init__( self._name = None self._network: Optional[Network] = None self._network_aliases: Optional[list[str]] = None - self._reuse: bool = kwargs.pop("reuse", False) + self._reuse: bool = False self._kwargs = kwargs def with_env(self, key: str, value: str) -> Self: @@ -106,9 +107,16 @@ def start(self) -> Self: ) hash_ = hashlib.sha256(bytes(str(args), encoding="utf-8")).hexdigest() - # TODO: warn user if self._reuse=True but reuse_enabled=False - reuse_enabled = c.reuse_enabled or c.tc_properties_testcontainers_reuse_enabled - if self._reuse and reuse_enabled: + # TODO: check also if ryuk is disabled + if self._reuse and not c.tc_properties_testcontainers_reuse_enable: + logging.warning( + "Reuse was requested (`with_reuse`) but the environment does not " + + "support the reuse of containers. To enable container reuse, add " + + "the property 'testcontainers.reuse.enable=true' to a file at " + + "~/.testcontainers.properties (you may need to create it)." + ) + + if self._reuse and c.tc_properties_testcontainers_reuse_enable: docker_client = self.get_docker_client() container = docker_client.find_container_by_hash(hash_) if container: @@ -143,7 +151,7 @@ def _start(self, hash_): def stop(self, force=True, delete_volume=True) -> None: if self._container: - if self._reuse and c.reuse_enabled: + if self._reuse and c.tc_properties_testcontainers_reuse_enable: self._container.stop() else: self._container.remove(force=force, v=delete_volume) diff --git a/core/tests/test_reusable_containers.py b/core/tests/test_reusable_containers.py index a0e07570..a8ab8a9d 100644 --- a/core/tests/test_reusable_containers.py +++ b/core/tests/test_reusable_containers.py @@ -1,7 +1,6 @@ from time import sleep from docker.models.containers import Container -from docker import DockerClient as DockerDockerClient from testcontainers.core.config import testcontainers_config from testcontainers.core.container import DockerContainer @@ -31,7 +30,8 @@ def test_docker_container_with_reuse_reuse_disabled(): def test_docker_container_with_reuse_reuse_enabled_ryuk_enabled(monkeypatch): # Make sure Ryuk cleanup is not active from previous test runs Reaper.delete_instance() - monkeypatch.setattr(testcontainers_config, "reuse_enabled", True) + tc_properties_mock = testcontainers_config.tc_properties | {"testcontainers.reuse.enable": "true"} + monkeypatch.setattr(testcontainers_config, "tc_properties", tc_properties_mock) monkeypatch.setattr(testcontainers_config, "ryuk_reconnection_timeout", "0.1s") with DockerContainer("hello-world").with_reuse() as container: @@ -52,7 +52,8 @@ def test_docker_container_with_reuse_reuse_enabled_ryuk_enabled(monkeypatch): def test_docker_container_with_reuse_reuse_enabled_ryuk_disabled(monkeypatch): # Make sure Ryuk cleanup is not active from previous test runs Reaper.delete_instance() - monkeypatch.setattr(testcontainers_config, "reuse_enabled", True) + tc_properties_mock = testcontainers_config.tc_properties | {"testcontainers.reuse.enable": "true"} + monkeypatch.setattr(testcontainers_config, "tc_properties", tc_properties_mock) monkeypatch.setattr(testcontainers_config, "ryuk_disabled", True) with DockerContainer("hello-world").with_reuse() as container: assert container._reuse == True