Skip to content

Commit 383f019

Browse files
committed
Return a copy of the original Container to test fixtures
1 parent 9526eec commit 383f019

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

pytest_container/container.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import contextlib
77
import enum
88
import functools
9+
import inspect
910
import itertools
1011
import operator
1112
import os
@@ -853,6 +854,16 @@ def release_lock() -> None:
853854

854855
extra_run_args.append(f"--cidfile={self._cidfile}")
855856

857+
# Create a copy of the container which was used to parametrize this test
858+
cls = type(self.container)
859+
constructor = inspect.signature(cls.__init__)
860+
constructor.parameters
861+
862+
kwargs = {
863+
k: v
864+
for k, v in self.container.__dict__.items()
865+
if k in constructor.parameters
866+
}
856867
# We must perform the launches in separate branches, as containers with
857868
# port forwards must be launched while the lock is being held. Otherwise
858869
# another container could pick the same ports before this one launches.
@@ -864,20 +875,26 @@ def release_lock() -> None:
864875
for new_forward in self._new_port_forwards:
865876
extra_run_args += new_forward.forward_cli_args
866877

867-
launch_cmd = self.container.get_launch_cmd(
878+
kwargs["forwarded_ports"] = self._new_port_forwards
879+
ctr = cls(**kwargs)
880+
881+
launch_cmd = ctr.get_launch_cmd(
868882
self.container_runtime, extra_run_args=extra_run_args
869883
)
870884

871885
_logger.debug("Launching container via: %s", launch_cmd)
872886
check_output(launch_cmd)
873887
else:
874-
launch_cmd = self.container.get_launch_cmd(
888+
ctr = cls(**kwargs)
889+
launch_cmd = ctr.get_launch_cmd(
875890
self.container_runtime, extra_run_args=extra_run_args
876891
)
877892

878893
_logger.debug("Launching container via: %s", launch_cmd)
879894
check_output(launch_cmd)
880895

896+
self.container = ctr
897+
881898
with open(self._cidfile, "r", encoding="utf8") as cidfile:
882899
self._container_id = cidfile.read(-1).strip()
883900

source/fixtures.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@ Fixtures
22
========
33

44

5+
Container class handling
6+
------------------------
7+
8+
Containers are defined as instances of
9+
:py:class:`~pytest_container.container.Container` and
10+
:py:class:`~pytest_container.container.DerivedContainer`. These class instances
11+
are then "passed" via pytest's parametrization to the fixtures which expose the
12+
class instances via the
13+
:py:attr:`~pytest_container.container.ContainerData.container` attribute.
14+
15+
The class instance exposed via this attribute is not guaranteed to be the
16+
**exact same** object as the one with which this test function was parametrized!
17+
The fixtures *might* only return copies, to prevent accidental mutation to
18+
cross-influence tests.
19+
20+
For example, the following code is not guaranteed to work:
21+
22+
.. code-block:: python
23+
24+
CTR = Container(url="registry.opensuse.org/opensuse/tumbleweed:latest")
25+
26+
@pytest.mark.parametrize("container", [CTR], indirect=True)
27+
def test_tw_ids(container: ContainerData) -> None:
28+
# this might or might not fail
29+
assert id(CTR) == id(container.container)
30+
31+
532
Handling Healthcheck
633
--------------------
734

0 commit comments

Comments
 (0)