From d92f323e6dd1b9dd210793263d81bd372f82b60d Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 1 Sep 2015 19:40:15 -0400 Subject: [PATCH] Fixes #1757 - include all service properties in the config_dict() Signed-off-by: Daniel Nephin --- compose/service.py | 3 ++ tests/integration/state_test.py | 22 +++++++++ tests/unit/service_test.py | 88 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/compose/service.py b/compose/service.py index 34a19a5991..a567a54c94 100644 --- a/compose/service.py +++ b/compose/service.py @@ -477,6 +477,9 @@ class Service(object): return { 'options': self.options, 'image_id': self.image()['Id'], + 'links': [(service.name, alias) for service, alias in self.links], + 'net': self.get_net_name() or getattr(self.net, 'id', self.net), + 'volumes_from': self.get_volumes_from_names(), } def get_dependency_names(self): diff --git a/tests/integration/state_test.py b/tests/integration/state_test.py index b124b19ffc..b254376171 100644 --- a/tests/integration/state_test.py +++ b/tests/integration/state_test.py @@ -1,3 +1,7 @@ +""" +Integration tests which cover state convergence (aka smart recreate) performed +by `docker-compose up`. +""" from __future__ import unicode_literals import tempfile import shutil @@ -151,6 +155,24 @@ class ProjectWithDependenciesTest(ProjectTestCase): self.assertEqual(new_containers - old_containers, set()) + def test_service_removed_while_down(self): + next_cfg = { + 'web': { + 'image': 'busybox:latest', + 'command': 'tail -f /dev/null', + }, + 'nginx': self.cfg['nginx'], + } + + containers = self.run_up(self.cfg) + self.assertEqual(len(containers), 3) + + project = self.make_project(self.cfg) + project.stop(timeout=1) + + containers = self.run_up(next_cfg) + self.assertEqual(len(containers), 2) + def converge(service, allow_recreate=True, diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 7e5266dd79..9979c8f123 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -221,6 +221,53 @@ class ServiceTest(unittest.TestCase): self.assertEqual(opts['hostname'], 'name.sub', 'hostname') self.assertEqual(opts['domainname'], 'domain.tld', 'domainname') + def test_get_container_create_options_with_name_option(self): + service = Service( + 'foo', + image='foo', + client=self.mock_client, + container_name='foo1') + name = 'the_new_name' + opts = service._get_container_create_options( + {'name': name}, + 1, + one_off=True) + self.assertEqual(opts['name'], name) + + def test_get_container_create_options_does_not_mutate_options(self): + labels = {'thing': 'real'} + environment = {'also': 'real'} + service = Service( + 'foo', + image='foo', + labels=dict(labels), + client=self.mock_client, + environment=dict(environment), + ) + self.mock_client.inspect_image.return_value = {'Id': 'abcd'} + prev_container = mock.Mock( + id='ababab', + image_config={'ContainerConfig': {}}) + + opts = service._get_container_create_options( + {}, + 1, + previous_container=prev_container) + + self.assertEqual(service.options['labels'], labels) + self.assertEqual(service.options['environment'], environment) + + self.assertEqual( + opts['labels'][LABEL_CONFIG_HASH], + '3c85881a8903b9d73a06c41860c8be08acce1494ab4cf8408375966dccd714de') + self.assertEqual( + opts['environment'], + { + 'affinity:container': '=ababab', + 'also': 'real', + } + ) + def test_get_container_not_found(self): self.mock_client.containers.return_value = [] service = Service('foo', client=self.mock_client, image='foo') @@ -340,6 +387,47 @@ class ServiceTest(unittest.TestCase): self.assertEqual(self.mock_client.build.call_count, 1) self.assertFalse(self.mock_client.build.call_args[1]['pull']) + def test_config_dict(self): + self.mock_client.inspect_image.return_value = {'Id': 'abcd'} + service = Service( + 'foo', + image='example.com/foo', + client=self.mock_client, + net=Service('other'), + links=[(Service('one'), 'one')], + volumes_from=[Service('two')]) + + config_dict = service.config_dict() + expected = { + 'image_id': 'abcd', + 'options': {'image': 'example.com/foo'}, + 'links': [('one', 'one')], + 'net': 'other', + 'volumes_from': ['two'], + } + self.assertEqual(config_dict, expected) + + def test_config_dict_with_net_from_container(self): + self.mock_client.inspect_image.return_value = {'Id': 'abcd'} + container = Container( + self.mock_client, + {'Id': 'aaabbb', 'Name': '/foo_1'}) + service = Service( + 'foo', + image='example.com/foo', + client=self.mock_client, + net=container) + + config_dict = service.config_dict() + expected = { + 'image_id': 'abcd', + 'options': {'image': 'example.com/foo'}, + 'links': [], + 'net': 'aaabbb', + 'volumes_from': [], + } + self.assertEqual(config_dict, expected) + def mock_get_image(images): if images: