Skip to content

Commit e7feb53

Browse files
feat: DockerContainer initializer to accept its private members as kwargs (#809)
Re submitting what is the end result of the iterations in #238 submitted originally by @vikhal. Simply enabling the initializer of `DockerContainer` to accept its private members as kwargs. --------- Co-authored-by: David Ankin <[email protected]>
1 parent 408f5c2 commit e7feb53

File tree

5 files changed

+65
-3
lines changed

5 files changed

+65
-3
lines changed

core/README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Testcontainers Core
1818

1919
.. autoclass:: testcontainers.core.generic.DbContainer
2020

21+
.. autoclass:: testcontainers.core.network.Network
22+
2123
.. raw:: html
2224

2325
<hr>

core/testcontainers/core/container.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ class DockerContainer:
2828
"""
2929
Basic container object to spin up Docker instances.
3030
31+
Args:
32+
image: The name of the image to start.
33+
docker_client_kw: Dictionary with arguments that will be passed to the
34+
docker.DockerClient init.
35+
command: Optional execution command for the container.
36+
name: Optional name for the container.
37+
ports: Ports to be exposed by the container. The port number will be
38+
automatically assigned on the host, use
39+
:code:`get_exposed_port(PORT)` method to get the port number on the host.
40+
volumes: Volumes to mount into the container. Each entry should be a tuple with
41+
three values: host path, container path and. mode (default 'ro').
42+
network: Optional network to connect the container to.
43+
network_aliases: Optional list of aliases for the container in the network.
44+
3145
.. doctest::
3246
3347
>>> from testcontainers.core.container import DockerContainer
@@ -41,18 +55,40 @@ def __init__(
4155
self,
4256
image: str,
4357
docker_client_kw: Optional[dict] = None,
58+
command: Optional[str] = None,
59+
env: Optional[dict[str, str]] = None,
60+
name: Optional[str] = None,
61+
ports: Optional[list[int]] = None,
62+
volumes: Optional[list[tuple[str, str, str]]] = None,
63+
network: Optional[Network] = None,
64+
network_aliases: Optional[list[str]] = None,
4465
**kwargs,
4566
) -> None:
46-
self.env = {}
67+
self.env = env or {}
68+
4769
self.ports = {}
70+
if ports:
71+
self.with_exposed_ports(*ports)
72+
4873
self.volumes = {}
74+
if volumes:
75+
for vol in volumes:
76+
self.with_volume_mapping(*vol)
77+
4978
self.image = image
5079
self._docker = DockerClient(**(docker_client_kw or {}))
5180
self._container = None
52-
self._command = None
53-
self._name = None
81+
self._command = command
82+
self._name = name
83+
5484
self._network: Optional[Network] = None
85+
if network is not None:
86+
self.with_network(network)
87+
5588
self._network_aliases: Optional[list[str]] = None
89+
if network_aliases:
90+
self.with_network_aliases(*network_aliases)
91+
5692
self._kwargs = kwargs
5793

5894
def with_env(self, key: str, value: str) -> Self:

core/tests/compose_fixtures/port_multiple/compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ services:
66
- '81'
77
- '82'
88
- target: 80
9+
published: "5000-5999"
910
host_ip: 127.0.0.1
1011
protocol: tcp
1112
command:
@@ -18,6 +19,7 @@ services:
1819
init: true
1920
ports:
2021
- target: 80
22+
published: "5000-5999"
2123
host_ip: 127.0.0.1
2224
protocol: tcp
2325
command:

core/tests/test_container.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,24 @@ def test_get_exposed_port_original(container: DockerContainer, monkeypatch: pyte
7575
monkeypatch.setattr(client, "get_connection_mode", lambda: ConnectionMode.bridge_ip)
7676

7777
assert container.get_exposed_port(8080) == 8080
78+
79+
80+
@pytest.mark.parametrize(
81+
"init_attr,init_value,class_attr,stored_value",
82+
[
83+
("command", "ps", "_command", "ps"),
84+
("env", {"e1": "v1"}, "env", {"e1": "v1"}),
85+
("name", "foo-bar", "_name", "foo-bar"),
86+
("ports", [22, 80], "ports", {22: None, 80: None}),
87+
(
88+
"volumes",
89+
[("/tmp", "/tmp2", "ro")],
90+
"volumes",
91+
{"/tmp": {"bind": "/tmp2", "mode": "ro"}},
92+
),
93+
],
94+
)
95+
def test_attribute(init_attr, init_value, class_attr, stored_value):
96+
"""Test that the attributes set through the __init__ function are properly stored."""
97+
with DockerContainer("ubuntu", **{init_attr: init_value}) as container:
98+
assert getattr(container, class_attr) == stored_value

core/tests/test_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def test_is_windows(monkeypatch: MonkeyPatch) -> None:
3333

3434

3535
def test_is_arm(monkeypatch: MonkeyPatch) -> None:
36+
monkeypatch.setattr("platform.machine", lambda: "x86_64")
3637
assert not utils.is_arm()
3738
monkeypatch.setattr("platform.machine", lambda: "arm64")
3839
assert utils.is_arm()

0 commit comments

Comments
 (0)