Skip to content

Commit d6b7de4

Browse files
authored
Merge branch 'master' into master
2 parents 2fa9df1 + 4581a70 commit d6b7de4

9 files changed

Lines changed: 101 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## Unreleased
4+
Changes:
5+
- Default behavior is not to install `docker-compose` at all when
6+
installing `pytest-docker` with PIP. If you want to, you install
7+
`pytest-docker` with the `docker-compose-v1` extra (`pip install
8+
pytest-docker[docker-compose-v1]`).
9+
- Add support for Docker Compose v2 via a new pytest fixture,
10+
`docker_compose_command` that should return `docker compose`.
11+
12+
## Version 0.13.0
13+
Feat:
14+
- In get_docker_ip(), if `DOCKER_HOST` is using the `unix:` scheme then return "127.0.0.1"
15+
316
## Version 0.12.0
417
Changes:
518
- Add `docker_setup` fixture to allow custom setup actions for docker-compose

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ environment to ensure that it is available during tests. This will prevent
2424
potential dependency conflicts that can occur when the system wide
2525
`docker-compose` is used in tests.
2626

27+
The default behavior is not to install `docker-compose` with `pytest-docker`. If you
28+
want to, you install `pytest-docker` with the `docker-compose-v1`
29+
extra. You can use the following command:
30+
31+
```
32+
pip install pytest-docker[docker-compose-v1]
33+
```
34+
35+
## Docker Compose v2 compatiblity
36+
37+
`pytest-docker` will work with Docker Compose v2 out of the box if
38+
[`compose-switch`](https://github.com/docker/compose-switch)
39+
is installed.
40+
41+
If you want to use the real Docker Compose v2, it has to be installed
42+
system wide ([more information](https://github.com/docker/compose#linux))
43+
and you have to modify the [`docker-compose-command`](#docker_compose_command)
44+
fixture (this behavior might change in the future versions).
2745

2846
# Usage
2947
Here is an example of a test that depends on a HTTP service.
@@ -114,6 +132,12 @@ your tests if you need a particular project name.
114132
Start all services from the docker compose file (`docker-compose up`).
115133
After test are finished, shutdown all services (`docker-compose down`).
116134

135+
### `docker_compose_command`
136+
137+
Docker Compose command to use to execute Dockers. Default is to use
138+
Docker Compose v1 (command is `docker-compose`). If you want to use
139+
Docker Compose v2, change this fixture to return `docker compose`.
140+
117141
### `docker_setup`
118142

119143
Get the docker_compose command to be executed for test spawn actions.
@@ -126,6 +150,7 @@ Get the docker_compose command to be executed for test clean-up actions.
126150
Override this fixture in your tests if you need to change clean-up actions.
127151
Returning anything that would evaluate to False will skip this command.
128152

153+
129154
# Development
130155
Use of a virtual environment is recommended. See the
131156
[venv](https://docs.python.org/3/library/venv.html) package for more

setup.cfg

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = pytest-docker
3-
version = 0.12.0
3+
version = 0.13.0
44
description = Simple pytest fixtures for Docker and docker-compose based tests
55
long_description = file: README.md
66
long_description_content_type = text/markdown
@@ -35,9 +35,10 @@ packages=pytest_docker
3535
install_requires =
3636
pytest >=4.0, <8.0
3737
attrs >=19, <22
38-
docker-compose >=1.27.3, <2.0
3938

4039
[options.extras_require]
40+
docker-compose-v1 =
41+
docker-compose >=1.27.3, <2.0
4142
tests =
4243
requests >=2.22.0, <3.0
4344
pytest-pylint >=0.14.1, <1.0

src/pytest_docker/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from .plugin import (
22
docker_cleanup,
3+
docker_compose_command,
34
docker_compose_file,
45
docker_compose_project_name,
56
docker_ip,

src/pytest_docker/plugin.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def get_docker_ip():
3333
# When talking to the Docker daemon via a UNIX socket, route all TCP
3434
# traffic to docker containers via the TCP loopback interface.
3535
docker_host = os.environ.get("DOCKER_HOST", "").strip()
36-
if not docker_host:
36+
if not docker_host or docker_host.startswith("unix://"):
3737
return "127.0.0.1"
3838

3939
match = re.match(r"^tcp://(.+?):\d+$", docker_host)
@@ -123,17 +123,27 @@ def str_to_list(arg):
123123
@attr.s(frozen=True)
124124
class DockerComposeExecutor:
125125

126+
_compose_command = attr.ib()
126127
_compose_files = attr.ib(converter=str_to_list)
127128
_compose_project_name = attr.ib()
128129

129130
def execute(self, subcommand):
130-
command = "docker-compose"
131+
command = self._compose_command
131132
for compose_file in self._compose_files:
132133
command += ' -f "{}"'.format(compose_file)
133134
command += ' -p "{}" {}'.format(self._compose_project_name, subcommand)
134135
return execute(command)
135136

136137

138+
@pytest.fixture(scope="session")
139+
def docker_compose_command():
140+
"""Docker Compose command to use, it could be either `docker-compose`
141+
for Docker Compose v1 or `docker compose` for Docker Compose
142+
v2."""
143+
144+
return "docker-compose"
145+
146+
137147
@pytest.fixture(scope="session")
138148
def docker_compose_file(pytestconfig):
139149
"""Get an absolute path to the `docker-compose.yml` file. Override this
@@ -180,10 +190,14 @@ def docker_setup():
180190

181191
@contextlib.contextmanager
182192
def get_docker_services(
183-
docker_compose_file, docker_compose_project_name, docker_setup, docker_cleanup
193+
docker_compose_command,
194+
docker_compose_file,
195+
docker_compose_project_name,
196+
docker_setup,
197+
docker_cleanup,
184198
):
185199
docker_compose = DockerComposeExecutor(
186-
docker_compose_file, docker_compose_project_name
200+
docker_compose_command, docker_compose_file, docker_compose_project_name
187201
)
188202

189203
# setup containers.
@@ -201,6 +215,7 @@ def get_docker_services(
201215

202216
@pytest.fixture(scope="session")
203217
def docker_services(
218+
docker_compose_command,
204219
docker_compose_file,
205220
docker_compose_project_name,
206221
docker_setup,
@@ -210,6 +225,10 @@ def docker_services(
210225
After test are finished, shutdown all services (`docker-compose down`)."""
211226

212227
with get_docker_services(
213-
docker_compose_file, docker_compose_project_name, docker_setup, docker_cleanup
228+
docker_compose_command,
229+
docker_compose_file,
230+
docker_compose_project_name,
231+
docker_setup,
232+
docker_cleanup,
214233
) as docker_service:
215234
yield docker_service

tests/test_docker_ip.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ def test_docker_ip_remote():
1616
assert get_docker_ip() == "1.2.3.4"
1717

1818

19+
def test_docker_ip_unix():
20+
environ = {"DOCKER_HOST": "unix:///run/user/1000/podman/podman.sock"}
21+
with mock.patch("os.environ", environ):
22+
assert get_docker_ip() == "127.0.0.1"
23+
24+
1925
@pytest.mark.parametrize("docker_host", ["http://1.2.3.4:2376"])
2026
def test_docker_ip_remote_invalid(docker_host):
2127
environ = {"DOCKER_HOST": docker_host}

tests/test_docker_services.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def test_docker_services():
2222

2323
# The fixture is a context-manager.
2424
with get_docker_services(
25+
"docker-compose",
2526
"docker-compose.yml",
2627
docker_compose_project_name="pytest123",
2728
docker_setup=get_setup_command(),
@@ -76,6 +77,7 @@ def test_docker_services_unused_port():
7677

7778
# The fixture is a context-manager.
7879
with get_docker_services(
80+
"docker-compose",
7981
"docker-compose.yml",
8082
docker_compose_project_name="pytest123",
8183
docker_setup=get_setup_command(),
@@ -128,6 +130,7 @@ def test_docker_services_failure():
128130
# The fixture is a context-manager.
129131
with pytest.raises(Exception) as exc:
130132
with get_docker_services(
133+
"docker-compose",
131134
"docker-compose.yml",
132135
docker_compose_project_name="pytest123",
133136
docker_setup=get_setup_command(),
@@ -158,7 +161,9 @@ def test_wait_until_responsive_timeout():
158161

159162
with mock.patch("time.sleep") as sleep:
160163
docker_compose = DockerComposeExecutor(
161-
compose_files="docker-compose.yml", compose_project_name="pytest123"
164+
compose_command="docker-compose",
165+
compose_files="docker-compose.yml",
166+
compose_project_name="pytest123",
162167
)
163168
services = Services(docker_compose)
164169
with pytest.raises(Exception) as exc:

tests/test_dockercomposeexecutor.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77

88
def test_execute():
9-
docker_compose = DockerComposeExecutor("docker-compose.yml", "pytest123")
9+
docker_compose = DockerComposeExecutor(
10+
"docker-compose", "docker-compose.yml", "pytest123"
11+
)
1012
with mock.patch("subprocess.check_output") as check_output:
1113
docker_compose.execute("up")
1214
assert check_output.call_args_list == [
@@ -18,9 +20,24 @@ def test_execute():
1820
]
1921

2022

23+
def test_execute_docker_compose_v2():
24+
docker_compose = DockerComposeExecutor(
25+
"docker compose", "docker-compose.yml", "pytest123"
26+
)
27+
with mock.patch("subprocess.check_output") as check_output:
28+
docker_compose.execute("up")
29+
assert check_output.call_args_list == [
30+
mock.call(
31+
'docker compose -f "docker-compose.yml" -p "pytest123" up',
32+
shell=True,
33+
stderr=subprocess.STDOUT,
34+
)
35+
]
36+
37+
2138
def test_pypath_compose_files():
2239
compose_file = py.path.local("/tmp/docker-compose.yml")
23-
docker_compose = DockerComposeExecutor(compose_file, "pytest123")
40+
docker_compose = DockerComposeExecutor("docker-compose", compose_file, "pytest123")
2441
with mock.patch("subprocess.check_output") as check_output:
2542
docker_compose.execute("up")
2643
assert check_output.call_args_list == [
@@ -34,7 +51,7 @@ def test_pypath_compose_files():
3451

3552
def test_multiple_compose_files():
3653
docker_compose = DockerComposeExecutor(
37-
["docker-compose.yml", "other-compose.yml"], "pytest123"
54+
"docker-compose", ["docker-compose.yml", "other-compose.yml"], "pytest123"
3855
)
3956
with mock.patch("subprocess.check_output") as check_output:
4057
docker_compose.execute("up")

tests/test_fixtures.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ def test_docker_cleanup(docker_cleanup):
1717

1818
def test_docker_setup(docker_setup):
1919
assert docker_setup == "up --build -d"
20+
21+
def test_docker_compose_comand(docker_compose_command):
22+
assert docker_compose_command == "docker-compose"

0 commit comments

Comments
 (0)