From ea4d5276104e23b355c30be79df8cfa1c1781682 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Tue, 27 Aug 2019 12:24:05 +0200
Subject: [PATCH 1/3] Move to the latest pytest versions for Python 2 and 3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Lumír Balhar <lbalhar@redhat.com>
---
requirements-dev.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 27b71a268..5df32bfb5 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -2,5 +2,6 @@ coverage==4.4.2
ddt==1.2.0
flake8==3.5.0
mock==3.0.5
-pytest==3.6.3
+pytest==5.1.1; python_version >= '3.5'
+pytest==4.6.5; python_version < '3.5'
pytest-cov==2.5.1
From 899004290becf866b5dc890c8b498b92e41aee05 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Tue, 27 Aug 2019 12:25:20 +0200
Subject: [PATCH 2/3] Implement custom context manager for changing CWD
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Lumír Balhar <lbalhar@redhat.com>
---
tests/helpers.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tests/helpers.py b/tests/helpers.py
index 327715ee2..1365c5bcf 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
+import contextlib
import os
from compose.config.config import ConfigDetails
@@ -55,3 +56,17 @@ def create_host_file(client, filename):
content = fh.read()
return create_custom_host_file(client, filename, content)
+
+
+@contextlib.contextmanager
+def cd(path):
+ """
+ A context manager which changes the working directory to the given
+ path, and then changes it back to its previous value on exit.
+ """
+ prev_cwd = os.getcwd()
+ os.chdir(path)
+ try:
+ yield
+ finally:
+ os.chdir(prev_cwd)
From 297bfb332254848d7617e6dbfac62d64c92e3a10 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Tue, 27 Aug 2019 12:26:01 +0200
Subject: [PATCH 3/3] Use stdlib modules instead of deprecated pytest fixtures
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Lumír Balhar <lbalhar@redhat.com>
---
tests/acceptance/cli_test.py | 8 +-
tests/integration/project_test.py | 8 +-
tests/integration/state_test.py | 29 ++-
tests/unit/config/config_test.py | 323 ++++++++++++++------------
tests/unit/config/environment_test.py | 15 +-
5 files changed, 204 insertions(+), 179 deletions(-)
diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py
index 14dbb7d6c..9f8ff1fef 100644
--- a/tests/acceptance/cli_test.py
+++ b/tests/acceptance/cli_test.py
@@ -6,8 +6,10 @@
import json
import os.path
import re
+import shutil
import signal
import subprocess
+import tempfile
import time
from collections import Counter
from collections import namedtuple
@@ -844,9 +846,9 @@ def test_build_with_buildarg_old_api_version(self):
def test_bundle_with_digests(self):
self.base_dir = 'tests/fixtures/bundle-with-digests/'
- tmpdir = pytest.ensuretemp('cli_test_bundle')
- self.addCleanup(tmpdir.remove)
- filename = str(tmpdir.join('example.dab'))
+ tmpdir = tempfile.mkdtemp('cli_test_bundle')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ filename = os.path.join(tmpdir, 'example.dab')
self.dispatch(['bundle', '--output', filename])
with open(filename, 'r') as fh:
diff --git a/tests/integration/project_test.py b/tests/integration/project_test.py
index 4c88f3d6b..cb620a8c9 100644
--- a/tests/integration/project_test.py
+++ b/tests/integration/project_test.py
@@ -8,7 +8,6 @@
import shutil
import tempfile
-import py
import pytest
from docker.errors import APIError
from docker.errors import NotFound
@@ -16,6 +15,7 @@
from .. import mock
from ..helpers import build_config as load_config
from ..helpers import BUSYBOX_IMAGE_WITH_TAG
+from ..helpers import cd
from ..helpers import create_host_file
from .testcases import DockerClientTestCase
from .testcases import SWARM_SKIP_CONTAINERS_ALL
@@ -1329,9 +1329,9 @@ def test_project_up_logging_with_multiple_files(self):
})
details = config.ConfigDetails('.', [base_file, override_file])
- tmpdir = py.test.ensuretemp('logging_test')
- self.addCleanup(tmpdir.remove)
- with tmpdir.as_cwd():
+ tmpdir = tempfile.mkdtemp('logging_test')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with cd(tmpdir):
config_data = config.load(details)
project = Project.from_config(
name='composetest', config_data=config_data, client=self.client
diff --git a/tests/integration/state_test.py b/tests/integration/state_test.py
index 714945ee5..492de7b8a 100644
--- a/tests/integration/state_test.py
+++ b/tests/integration/state_test.py
@@ -6,8 +6,10 @@
from __future__ import unicode_literals
import copy
+import os
+import shutil
+import tempfile
-import py
from docker.errors import ImageNotFound
from ..helpers import BUSYBOX_IMAGE_WITH_TAG
@@ -426,29 +428,32 @@ def safe_remove_image(image):
@no_cluster('Can not guarantee the build will be run on the same node the service is deployed')
def test_trigger_recreate_with_build(self):
- context = py.test.ensuretemp('test_trigger_recreate_with_build')
- self.addCleanup(context.remove)
+ context = tempfile.mkdtemp('test_trigger_recreate_with_build')
+ self.addCleanup(shutil.rmtree, context)
base_image = "FROM busybox\nLABEL com.docker.compose.test_image=true\n"
- dockerfile = context.join('Dockerfile')
- dockerfile.write(base_image)
+ dockerfile = os.path.join(context, 'Dockerfile')
+ with open(dockerfile, mode="w") as dockerfile_fh:
+ dockerfile_fh.write(base_image)
web = self.create_service('web', build={'context': str(context)})
container = web.create_container()
- dockerfile.write(base_image + 'CMD echo hello world\n')
+ with open(dockerfile, mode="w") as dockerfile_fh:
+ dockerfile_fh.write(base_image + 'CMD echo hello world\n')
web.build()
web = self.create_service('web', build={'context': str(context)})
assert ('recreate', [container]) == web.convergence_plan()
def test_image_changed_to_build(self):
- context = py.test.ensuretemp('test_image_changed_to_build')
- self.addCleanup(context.remove)
- context.join('Dockerfile').write("""
- FROM busybox
- LABEL com.docker.compose.test_image=true
- """)
+ context = tempfile.mkdtemp('test_image_changed_to_build')
+ self.addCleanup(shutil.rmtree, context)
+ with open(os.path.join(context, 'Dockerfile'), mode="w") as dockerfile:
+ dockerfile.write("""
+ FROM busybox
+ LABEL com.docker.compose.test_image=true
+ """)
web = self.create_service('web', image='busybox')
container = web.create_container()
diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py
index 5ad1a2334..4d3e6b4ab 100644
--- a/tests/unit/config/config_test.py
+++ b/tests/unit/config/config_test.py
@@ -10,12 +10,12 @@
from operator import itemgetter
from random import shuffle
-import py
import pytest
import yaml
from ...helpers import build_config_details
from ...helpers import BUSYBOX_IMAGE_WITH_TAG
+from ...helpers import cd
from compose.config import config
from compose.config import types
from compose.config.config import resolve_build_args
@@ -776,13 +776,14 @@ def test_load_with_multiple_files_and_extends_in_override_file(self):
})
details = config.ConfigDetails('.', [base_file, override_file])
- tmpdir = py.test.ensuretemp('config_test')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('common.yml').write("""
- base:
- labels: ['label=one']
- """)
- with tmpdir.as_cwd():
+ tmpdir = tempfile.mkdtemp('config_test')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'common.yml'), mode="w") as common_fh:
+ common_fh.write("""
+ base:
+ labels: ['label=one']
+ """)
+ with cd(tmpdir):
service_dicts = config.load(details).services
expected = [
@@ -811,19 +812,20 @@ def test_load_mixed_extends_resolution(self):
}
)
- tmpdir = pytest.ensuretemp('config_test')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('base.yml').write("""
- version: '2.2'
- services:
- base:
- image: base
- web:
- extends: base
- """)
+ tmpdir = tempfile.mkdtemp('config_test')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'base.yml'), mode="w") as base_fh:
+ base_fh.write("""
+ version: '2.2'
+ services:
+ base:
+ image: base
+ web:
+ extends: base
+ """)
details = config.ConfigDetails('.', [main_file])
- with tmpdir.as_cwd():
+ with cd(tmpdir):
service_dicts = config.load(details).services
assert service_dicts[0] == {
'name': 'prodweb',
@@ -1761,22 +1763,23 @@ def test_config_valid_environment_dict_key_contains_dashes(self):
assert services[0]['environment']['SPRING_JPA_HIBERNATE_DDL-AUTO'] == 'none'
def test_load_yaml_with_yaml_error(self):
- tmpdir = py.test.ensuretemp('invalid_yaml_test')
- self.addCleanup(tmpdir.remove)
- invalid_yaml_file = tmpdir.join('docker-compose.yml')
- invalid_yaml_file.write("""
- web:
- this is bogus: ok: what
- """)
+ tmpdir = tempfile.mkdtemp('invalid_yaml_test')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ invalid_yaml_file = os.path.join(tmpdir, 'docker-compose.yml')
+ with open(invalid_yaml_file, mode="w") as invalid_yaml_file_fh:
+ invalid_yaml_file_fh.write("""
+ web:
+ this is bogus: ok: what
+ """)
with pytest.raises(ConfigurationError) as exc:
config.load_yaml(str(invalid_yaml_file))
- assert 'line 3, column 32' in exc.exconly()
+ assert 'line 3, column 36' in exc.exconly()
def test_load_yaml_with_bom(self):
- tmpdir = py.test.ensuretemp('bom_yaml')
- self.addCleanup(tmpdir.remove)
- bom_yaml = tmpdir.join('docker-compose.yml')
+ tmpdir = tempfile.mkdtemp('bom_yaml')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ bom_yaml = os.path.join(tmpdir, 'docker-compose.yml')
with codecs.open(str(bom_yaml), 'w', encoding='utf-8') as f:
f.write('''\ufeff
version: '2.3'
@@ -4700,43 +4703,48 @@ def test_extended_service_with_verbose_and_shorthand_way(self):
@mock.patch.dict(os.environ)
def test_extends_with_environment_and_env_files(self):
- tmpdir = py.test.ensuretemp('test_extends_with_environment')
- self.addCleanup(tmpdir.remove)
- commondir = tmpdir.mkdir('common')
- commondir.join('base.yml').write("""
- app:
- image: 'example/app'
- env_file:
- - 'envs'
- environment:
- - SECRET
- - TEST_ONE=common
- - TEST_TWO=common
- """)
- tmpdir.join('docker-compose.yml').write("""
- ext:
- extends:
- file: common/base.yml
- service: app
- env_file:
- - 'envs'
- environment:
- - THING
- - TEST_ONE=top
- """)
- commondir.join('envs').write("""
- COMMON_ENV_FILE
- TEST_ONE=common-env-file
- TEST_TWO=common-env-file
- TEST_THREE=common-env-file
- TEST_FOUR=common-env-file
- """)
- tmpdir.join('envs').write("""
- TOP_ENV_FILE
- TEST_ONE=top-env-file
- TEST_TWO=top-env-file
- TEST_THREE=top-env-file
- """)
+ tmpdir = tempfile.mkdtemp('test_extends_with_environment')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ commondir = os.path.join(tmpdir, 'common')
+ os.mkdir(commondir)
+ with open(os.path.join(commondir, 'base.yml'), mode="w") as base_fh:
+ base_fh.write("""
+ app:
+ image: 'example/app'
+ env_file:
+ - 'envs'
+ environment:
+ - SECRET
+ - TEST_ONE=common
+ - TEST_TWO=common
+ """)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ ext:
+ extends:
+ file: common/base.yml
+ service: app
+ env_file:
+ - 'envs'
+ environment:
+ - THING
+ - TEST_ONE=top
+ """)
+ with open(os.path.join(commondir, 'envs'), mode="w") as envs_fh:
+ envs_fh.write("""
+ COMMON_ENV_FILE
+ TEST_ONE=common-env-file
+ TEST_TWO=common-env-file
+ TEST_THREE=common-env-file
+ TEST_FOUR=common-env-file
+ """)
+ with open(os.path.join(tmpdir, 'envs'), mode="w") as envs_fh:
+ envs_fh.write("""
+ TOP_ENV_FILE
+ TEST_ONE=top-env-file
+ TEST_TWO=top-env-file
+ TEST_THREE=top-env-file
+ """)
expected = [
{
@@ -4759,72 +4767,77 @@ def test_extends_with_environment_and_env_files(self):
os.environ['THING'] = 'thing'
os.environ['COMMON_ENV_FILE'] = 'secret'
os.environ['TOP_ENV_FILE'] = 'secret'
- config = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ config = load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert config == expected
def test_extends_with_mixed_versions_is_error(self):
- tmpdir = py.test.ensuretemp('test_extends_with_mixed_version')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('docker-compose.yml').write("""
- version: "2"
- services:
- web:
- extends:
- file: base.yml
- service: base
- image: busybox
- """)
- tmpdir.join('base.yml').write("""
- base:
- volumes: ['/foo']
- ports: ['3000:3000']
- """)
+ tmpdir = tempfile.mkdtemp('test_extends_with_mixed_version')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ version: "2"
+ services:
+ web:
+ extends:
+ file: base.yml
+ service: base
+ image: busybox
+ """)
+ with open(os.path.join(tmpdir, 'base.yml'), mode="w") as base_fh:
+ base_fh.write("""
+ base:
+ volumes: ['/foo']
+ ports: ['3000:3000']
+ """)
with pytest.raises(ConfigurationError) as exc:
- load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert 'Version mismatch' in exc.exconly()
def test_extends_with_defined_version_passes(self):
- tmpdir = py.test.ensuretemp('test_extends_with_defined_version')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('docker-compose.yml').write("""
- version: "2"
- services:
- web:
- extends:
- file: base.yml
- service: base
- image: busybox
- """)
- tmpdir.join('base.yml').write("""
- version: "2"
- services:
- base:
- volumes: ['/foo']
- ports: ['3000:3000']
- command: top
- """)
-
- service = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ tmpdir = tempfile.mkdtemp('test_extends_with_defined_version')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ version: "2"
+ services:
+ web:
+ extends:
+ file: base.yml
+ service: base
+ image: busybox
+ """)
+ with open(os.path.join(tmpdir, 'base.yml'), mode="w") as base_fh:
+ base_fh.write("""
+ version: "2"
+ services:
+ base:
+ volumes: ['/foo']
+ ports: ['3000:3000']
+ command: top
+ """)
+
+ service = load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert service[0]['command'] == "top"
def test_extends_with_depends_on(self):
- tmpdir = py.test.ensuretemp('test_extends_with_depends_on')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('docker-compose.yml').write("""
- version: "2"
- services:
- base:
- image: example
- web:
- extends: base
- image: busybox
- depends_on: ['other']
- other:
- image: example
- """)
- services = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ tmpdir = tempfile.mkdtemp('test_extends_with_depends_on')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ version: "2"
+ services:
+ base:
+ image: example
+ web:
+ extends: base
+ image: busybox
+ depends_on: ['other']
+ other:
+ image: example
+ """)
+ services = load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert service_sort(services)[2]['depends_on'] == {
'other': {'condition': 'service_started'}
}
@@ -4843,45 +4856,47 @@ def test_extends_with_healthcheck(self):
}]
def test_extends_with_ports(self):
- tmpdir = py.test.ensuretemp('test_extends_with_ports')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('docker-compose.yml').write("""
- version: '2'
-
- services:
- a:
- image: nginx
- ports:
- - 80
-
- b:
- extends:
- service: a
- """)
- services = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ tmpdir = tempfile.mkdtemp('test_extends_with_ports')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ version: '2'
+
+ services:
+ a:
+ image: nginx
+ ports:
+ - 80
+
+ b:
+ extends:
+ service: a
+ """)
+ services = load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert len(services) == 2
for svc in services:
assert svc['ports'] == [types.ServicePort('80', None, None, None, None)]
def test_extends_with_security_opt(self):
- tmpdir = py.test.ensuretemp('test_extends_with_ports')
- self.addCleanup(tmpdir.remove)
- tmpdir.join('docker-compose.yml').write("""
- version: '2'
-
- services:
- a:
- image: nginx
- security_opt:
- - apparmor:unconfined
- - seccomp:unconfined
-
- b:
- extends:
- service: a
- """)
- services = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+ tmpdir = tempfile.mkdtemp('test_extends_with_ports')
+ self.addCleanup(shutil.rmtree, tmpdir)
+ with open(os.path.join(tmpdir, 'docker-compose.yml'), mode="w") as docker_compose_fh:
+ docker_compose_fh.write("""
+ version: '2'
+
+ services:
+ a:
+ image: nginx
+ security_opt:
+ - apparmor:unconfined
+ - seccomp:unconfined
+
+ b:
+ extends:
+ service: a
+ """)
+ services = load_from_filename(str(os.path.join(tmpdir, 'docker-compose.yml')))
assert len(services) == 2
for svc in services:
assert types.SecurityOpt.parse('apparmor:unconfined') in svc['security_opt']
diff --git a/tests/unit/config/environment_test.py b/tests/unit/config/environment_test.py
index 88eb0d6e1..186702db1 100644
--- a/tests/unit/config/environment_test.py
+++ b/tests/unit/config/environment_test.py
@@ -4,6 +4,9 @@
from __future__ import unicode_literals
import codecs
+import os
+import shutil
+import tempfile
import pytest
@@ -46,19 +49,19 @@ def test_get_boolean(self):
assert env.get_boolean('UNDEFINED') is False
def test_env_vars_from_file_bom(self):
- tmpdir = pytest.ensuretemp('env_file')
- self.addCleanup(tmpdir.remove)
+ tmpdir = tempfile.mkdtemp('env_file')
+ self.addCleanup(shutil.rmtree, tmpdir)
with codecs.open('{}/bom.env'.format(str(tmpdir)), 'w', encoding='utf-8') as f:
f.write('\ufeffPARK_BOM=박봄\n')
- assert env_vars_from_file(str(tmpdir.join('bom.env'))) == {
+ assert env_vars_from_file(str(os.path.join(tmpdir, 'bom.env'))) == {
'PARK_BOM': '박봄'
}
def test_env_vars_from_file_whitespace(self):
- tmpdir = pytest.ensuretemp('env_file')
- self.addCleanup(tmpdir.remove)
+ tmpdir = tempfile.mkdtemp('env_file')
+ self.addCleanup(shutil.rmtree, tmpdir)
with codecs.open('{}/whitespace.env'.format(str(tmpdir)), 'w', encoding='utf-8') as f:
f.write('WHITESPACE =yes\n')
with pytest.raises(ConfigurationError) as exc:
- env_vars_from_file(str(tmpdir.join('whitespace.env')))
+ env_vars_from_file(str(os.path.join(tmpdir, 'whitespace.env')))
assert 'environment variable' in exc.exconly()