From dc6bb7020dfb5e9ae9607697cc8b850c8c21bf46 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Wed, 2 Aug 2017 16:59:43 -0700 Subject: [PATCH] UCP 2.2.0 test fixes Signed-off-by: Joffrey F --- tests/acceptance/cli_test.py | 16 +++++++++------- tests/helpers.py | 4 ++++ tests/integration/project_test.py | 3 ++- tests/integration/service_test.py | 8 ++++++-- tests/integration/state_test.py | 17 ++++++++++++++++- tests/integration/testcases.py | 6 +++++- tox.ini | 1 + 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index adf645c2f..81bce5460 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -451,7 +451,6 @@ class CLITestCase(DockerClientTestCase): self.dispatch(['build', 'simple']) result = self.dispatch(['build', 'simple']) - assert BUILD_CACHE_TEXT in result.stdout assert BUILD_PULL_TEXT not in result.stdout def test_build_no_cache(self): @@ -469,7 +468,9 @@ class CLITestCase(DockerClientTestCase): self.dispatch(['build', 'simple'], None) result = self.dispatch(['build', '--pull', 'simple']) - assert BUILD_CACHE_TEXT in result.stdout + if not is_cluster(self.client): + # If previous build happened on another node, cache won't be available + assert BUILD_CACHE_TEXT in result.stdout assert BUILD_PULL_TEXT in result.stdout def test_build_no_cache_pull(self): @@ -602,11 +603,12 @@ class CLITestCase(DockerClientTestCase): def test_run_one_off_with_volume(self): self.base_dir = 'tests/fixtures/simple-composefile-volume-ready' volume_path = os.path.abspath(os.path.join(os.getcwd(), self.base_dir, 'files')) - create_host_file(self.client, os.path.join(volume_path, 'example.txt')) + node = create_host_file(self.client, os.path.join(volume_path, 'example.txt')) self.dispatch([ 'run', '-v', '{}:/data'.format(volume_path), + '-e', 'constraint:node=={}'.format(node if node is not None else '*'), 'simple', 'test', '-f', '/data/example.txt' ], returncode=0) @@ -621,12 +623,13 @@ class CLITestCase(DockerClientTestCase): def test_run_one_off_with_multiple_volumes(self): self.base_dir = 'tests/fixtures/simple-composefile-volume-ready' volume_path = os.path.abspath(os.path.join(os.getcwd(), self.base_dir, 'files')) - create_host_file(self.client, os.path.join(volume_path, 'example.txt')) + node = create_host_file(self.client, os.path.join(volume_path, 'example.txt')) self.dispatch([ 'run', '-v', '{}:/data'.format(volume_path), '-v', '{}:/data1'.format(volume_path), + '-e', 'constraint:node=={}'.format(node if node is not None else '*'), 'simple', 'test', '-f', '/data/example.txt' ], returncode=0) @@ -635,6 +638,7 @@ class CLITestCase(DockerClientTestCase): 'run', '-v', '{}:/data'.format(volume_path), '-v', '{}:/data1'.format(volume_path), + '-e', 'constraint:node=={}'.format(node if node is not None else '*'), 'simple', 'test', '-f' '/data1/example.txt' ], returncode=0) @@ -1376,9 +1380,7 @@ class CLITestCase(DockerClientTestCase): break volume_names = [v['Name'].split('/')[-1] for v in volumes] assert name in volume_names - if not is_cluster(self.client): - # The `-v` flag for `docker rm` in Swarm seems to be broken - assert anonymous_name not in volume_names + assert anonymous_name not in volume_names def test_run_service_with_dockerfile_entrypoint(self): self.base_dir = 'tests/fixtures/entrypoint-dockerfile' diff --git a/tests/helpers.py b/tests/helpers.py index 59efd2557..a93de993f 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -42,5 +42,9 @@ def create_host_file(client, filename): output = client.logs(container) raise Exception( "Container exited with code {}:\n{}".format(exitcode, output)) + + container_info = client.inspect_container(container) + if 'Node' in container_info: + return container_info['Node']['Name'] finally: client.remove_container(container, force=True) diff --git a/tests/integration/project_test.py b/tests/integration/project_test.py index 5ead7b8e7..4e44c7f6b 100644 --- a/tests/integration/project_test.py +++ b/tests/integration/project_test.py @@ -1265,7 +1265,7 @@ class ProjectTest(DockerClientTestCase): @v3_only() def test_project_up_with_secrets(self): - create_host_file(self.client, os.path.abspath('tests/fixtures/secrets/default')) + node = create_host_file(self.client, os.path.abspath('tests/fixtures/secrets/default')) config_data = build_config( version=V3_1, @@ -1276,6 +1276,7 @@ class ProjectTest(DockerClientTestCase): 'secrets': [ types.ServiceSecret.parse({'source': 'super', 'target': 'special'}), ], + 'environment': ['constraint:node=={}'.format(node if node is not None else '*')] }], secrets={ 'super': { diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index 8fb2251bf..2abb12c34 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -325,13 +325,15 @@ class ServiceTest(DockerClientTestCase): command=["top"], labels={LABEL_PROJECT: 'composetest'}, host_config={}, + environment=['affinity:container=={}'.format(volume_container_1.id)], ) host_service = self.create_service( 'host', volumes_from=[ VolumeFromSpec(volume_service, 'rw', 'service'), VolumeFromSpec(volume_container_2, 'rw', 'container') - ] + ], + environment=['affinity:container=={}'.format(volume_container_1.id)], ) host_container = host_service.create_container() host_service.start_container(host_container) @@ -785,6 +787,7 @@ class ServiceTest(DockerClientTestCase): assert service.image() @v2_3_only() + @no_cluster('Not supported on UCP 2.2.0-beta1') # FIXME: remove once support is added def test_build_with_target(self): self.require_api_version('1.30') base_dir = tempfile.mkdtemp() @@ -792,11 +795,12 @@ class ServiceTest(DockerClientTestCase): with open(os.path.join(base_dir, 'Dockerfile'), 'w') as f: f.write('FROM busybox as one\n') + f.write('LABEL com.docker.compose.test=true\n') f.write('LABEL com.docker.compose.test.target=one\n') f.write('FROM busybox as two\n') f.write('LABEL com.docker.compose.test.target=two\n') - service = self.create_service('buildlabels', build={ + service = self.create_service('buildtarget', build={ 'context': text_type(base_dir), 'target': 'one' }) diff --git a/tests/integration/state_test.py b/tests/integration/state_test.py index 0dd5f44ad..047dc7046 100644 --- a/tests/integration/state_test.py +++ b/tests/integration/state_test.py @@ -6,9 +6,11 @@ from __future__ import absolute_import from __future__ import unicode_literals import py +from docker.errors import ImageNotFound from .testcases import DockerClientTestCase from .testcases import get_links +from .testcases import no_cluster from compose.config import config from compose.project import Project from compose.service import ConvergenceStrategy @@ -243,21 +245,34 @@ class ServiceStateTest(DockerClientTestCase): tag = 'latest' image = '{}:{}'.format(repo, tag) + def safe_remove_image(image): + try: + self.client.remove_image(image) + except ImageNotFound: + pass + image_id = self.client.images(name='busybox')[0]['Id'] self.client.tag(image_id, repository=repo, tag=tag) - self.addCleanup(self.client.remove_image, image) + self.addCleanup(safe_remove_image, image) web = self.create_service('web', image=image) container = web.create_container() # update the image c = self.client.create_container(image, ['touch', '/hello.txt'], host_config={}) + + # In the case of a cluster, there's a chance we pick up the old image when + # calculating the new hash. To circumvent that, untag the old image first + # See also: https://github.com/moby/moby/issues/26852 + self.client.remove_image(image, force=True) + self.client.commit(c, repository=repo, tag=tag) self.client.remove_container(c) web = self.create_service('web', image=image) self.assertEqual(('recreate', [container]), web.convergence_plan()) + @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) diff --git a/tests/integration/testcases.py b/tests/integration/testcases.py index b1763b113..b72fb53a8 100644 --- a/tests/integration/testcases.py +++ b/tests/integration/testcases.py @@ -105,7 +105,11 @@ class DockerClientTestCase(unittest.TestCase): for i in self.client.images( filters={'label': 'com.docker.compose.test_image'}): - self.client.remove_image(i, force=True) + try: + self.client.remove_image(i, force=True) + except APIError as e: + if e.is_server_error(): + pass volumes = self.client.volumes().get('Volumes') or [] for v in volumes: diff --git a/tox.ini b/tox.ini index 749be3faa..e4f31ec85 100644 --- a/tox.ini +++ b/tox.ini @@ -18,6 +18,7 @@ deps = -rrequirements-dev.txt commands = py.test -v \ + --full-trace \ --cov=compose \ --cov-report html \ --cov-report term \