diff --git a/core/README.rst b/core/README.rst index 1461ba7d8..5176ce078 100644 --- a/core/README.rst +++ b/core/README.rst @@ -18,6 +18,8 @@ Testcontainers Core .. autoclass:: testcontainers.core.generic.DbContainer +.. autoclass:: testcontainers.core.network.Network + .. raw:: html
diff --git a/core/testcontainers/core/container.py b/core/testcontainers/core/container.py index 74f7828e0..b7979a613 100644 --- a/core/testcontainers/core/container.py +++ b/core/testcontainers/core/container.py @@ -28,6 +28,20 @@ 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'). + network: Optional network to connect the container to. + network_aliases: Optional list of aliases for the container in the network. + .. doctest:: >>> from testcontainers.core.container import DockerContainer @@ -41,18 +55,40 @@ def __init__( self, image: str, docker_client_kw: Optional[dict] = 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, + network: Optional[Network] = None, + network_aliases: Optional[list[str]] = None, **kwargs, ) -> None: - self.env = {} + self.env = env or {} + self.ports = {} + if ports: + self.with_exposed_ports(*ports) + self.volumes = {} + if volumes: + for vol in volumes: + self.with_volume_mapping(*vol) + self.image = image self._docker = DockerClient(**(docker_client_kw or {})) self._container = None - self._command = None - self._name = None + self._command = command + self._name = name + self._network: Optional[Network] = None + if network is not None: + self.with_network(network) + self._network_aliases: Optional[list[str]] = None + if network_aliases: + self.with_network_aliases(*network_aliases) + self._kwargs = kwargs def with_env(self, key: str, value: str) -> Self: diff --git a/core/tests/compose_fixtures/port_multiple/compose.yaml b/core/tests/compose_fixtures/port_multiple/compose.yaml index e8e147bbd..662079f5e 100644 --- a/core/tests/compose_fixtures/port_multiple/compose.yaml +++ b/core/tests/compose_fixtures/port_multiple/compose.yaml @@ -6,6 +6,7 @@ services: - '81' - '82' - target: 80 + published: "5000-5999" host_ip: 127.0.0.1 protocol: tcp command: @@ -18,6 +19,7 @@ services: init: true ports: - target: 80 + published: "5000-5999" host_ip: 127.0.0.1 protocol: tcp command: diff --git a/core/tests/test_container.py b/core/tests/test_container.py index e1e7cff7a..bb7dd0596 100644 --- a/core/tests/test_container.py +++ b/core/tests/test_container.py @@ -75,3 +75,24 @@ def test_get_exposed_port_original(container: DockerContainer, monkeypatch: pyte monkeypatch.setattr(client, "get_connection_mode", lambda: ConnectionMode.bridge_ip) assert container.get_exposed_port(8080) == 8080 + + +@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 diff --git a/core/tests/test_utils.py b/core/tests/test_utils.py index 4c240ed45..e811ee396 100644 --- a/core/tests/test_utils.py +++ b/core/tests/test_utils.py @@ -33,6 +33,7 @@ def test_is_windows(monkeypatch: MonkeyPatch) -> None: def test_is_arm(monkeypatch: MonkeyPatch) -> None: + monkeypatch.setattr("platform.machine", lambda: "x86_64") assert not utils.is_arm() monkeypatch.setattr("platform.machine", lambda: "arm64") assert utils.is_arm()