diff --git a/core/testcontainers/core/container.py b/core/testcontainers/core/container.py index 65acf9bed..ac25a6eda 100644 --- a/core/testcontainers/core/container.py +++ b/core/testcontainers/core/container.py @@ -1,6 +1,6 @@ from docker.models.containers import Container import os -from typing import Iterable, Optional, Tuple +from typing import Iterable, Optional, Tuple, Any, Dict, List from .waiting_utils import wait_container_is_ready from .docker_client import DockerClient @@ -14,6 +14,18 @@ class DockerContainer: """ Basic container object to spin up Docker instances. + Args: + image: The name of the image to start. + docker_client_kw: Dictionary with arguments that will be passed to the + docker.DockerClient init. + command: Optional execution command for the container. + name: Optional name for the container. + ports: Ports to be exposed by the container. The port number will be + automatically assigned on the host, use + :code:`get_exposed_port(PORT)` method to get the port number on the host. + volumes: Volumes to mount into the container. Each entry should be a tuple with + three values: host path, container path and. mode (default 'ro'). + .. doctest:: >>> from testcontainers.core.container import DockerContainer @@ -22,15 +34,37 @@ class DockerContainer: >>> with DockerContainer("hello-world") as container: ... delay = wait_for_logs(container, "Hello from Docker!") """ - def __init__(self, image: str, docker_client_kw: Optional[dict] = None, **kwargs) -> None: - self.env = {} - self.ports = {} - self.volumes = {} + def __init__( + self, + image: str, + docker_client_kw: Optional[Dict[str, Any]] = None, + command: Optional[str] = None, + env: Optional[Dict[str, str]] = None, + name: Optional[str] = None, + ports: Optional[List[int]] = None, + volumes: Optional[List[Tuple[str, str, str]]] = None, + **kwargs + ) -> None: + self.image = image self._docker = DockerClient(**(docker_client_kw or {})) + + self._command = command + + self.env = env or {} + + self._name = name + + self.ports = {} + if ports: + self.with_exposed_ports(*ports) + + self.volumes = {} + if volumes: + for vol in volumes: + self.with_volume_mapping(*vol) + self._container = None - self._command = None - self._name = None self._kwargs = kwargs def with_env(self, key: str, value: str) -> 'DockerContainer': diff --git a/core/tests/test_core.py b/core/tests/test_core.py index 5a6663502..85b203d1e 100644 --- a/core/tests/test_core.py +++ b/core/tests/test_core.py @@ -20,3 +20,24 @@ def test_can_get_logs(): wait_for_logs(container, "Hello from Docker!") stdout, stderr = container.get_logs() assert stdout, 'There should be something on stdout' + + +@pytest.mark.parametrize( + "init_attr,init_value,class_attr,stored_value", + [ + ("command", "ps", "_command", "ps"), + ("env", {"e1": "v1"}, "env", {"e1": "v1"}), + ("name", "foo-bar", "_name", "foo-bar"), + ("ports", [22, 80], "ports", {22: None, 80: None}), + ( + "volumes", + [("/tmp", "/tmp2", "ro")], + "volumes", + {"/tmp": {"bind": "/tmp2", "mode": "ro"}}, + ), + ], +) +def test_attribute(init_attr, init_value, class_attr, stored_value): + """Test that the attributes set through the __init__ function are properly stored.""" + with DockerContainer("ubuntu", **{init_attr: init_value}) as container: + assert getattr(container, class_attr) == stored_value