From 0603b445e28502fc27850ce16dbdb158b3089f7e Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 4 Oct 2016 17:35:20 -0700 Subject: [PATCH] Properly merge logging dictionaries in overriding configs Signed-off-by: Joffrey F --- compose/config/config.py | 12 +++ tests/unit/config/config_test.py | 158 ++++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/compose/config/config.py b/compose/config/config.py index aea1e0949..8582d83c8 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -760,6 +760,8 @@ def merge_service_dicts(base, override, version): for field in ['dns', 'dns_search', 'env_file', 'tmpfs']: md.merge_field(field, merge_list_or_string) + md.merge_field('logging', merge_logging) + for field in set(ALLOWED_KEYS) - set(md): md.merge_scalar(field) @@ -789,6 +791,16 @@ def merge_build(output, base, override): return dict(md) +def merge_logging(base, override): + md = MergeDict(base, override) + md.merge_scalar('driver') + if md.get('driver') == base.get('driver') or base.get('driver') is None: + md.merge_mapping('options', lambda m: m or {}) + else: + md['options'] = override.get('options') + return dict(md) + + def legacy_v1_merge_image_or_build(output, base, override): output.pop('image', None) output.pop('build', None) diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py index 88b990e52..d9269ab43 100644 --- a/tests/unit/config/config_test.py +++ b/tests/unit/config/config_test.py @@ -1330,7 +1330,7 @@ class ConfigTest(unittest.TestCase): 'image': 'alpine', 'group_add': ["docker", 777] } - } + } })) assert actual.services == [ @@ -1429,6 +1429,162 @@ class ConfigTest(unittest.TestCase): 'command': 'true', } + def test_merge_logging_v2(self): + base = { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'json-file', + 'options': { + 'frequency': '2000', + 'timeout': '23' + } + } + } + override = { + 'logging': { + 'options': { + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + actual = config.merge_service_dicts(base, override, V2_0) + assert actual == { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'json-file', + 'options': { + 'frequency': '2000', + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + def test_merge_logging_v2_override_driver(self): + base = { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'json-file', + 'options': { + 'frequency': '2000', + 'timeout': '23' + } + } + } + override = { + 'logging': { + 'driver': 'syslog', + 'options': { + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + actual = config.merge_service_dicts(base, override, V2_0) + assert actual == { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'syslog', + 'options': { + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + def test_merge_logging_v2_no_base_driver(self): + base = { + 'image': 'alpine:edge', + 'logging': { + 'options': { + 'frequency': '2000', + 'timeout': '23' + } + } + } + override = { + 'logging': { + 'driver': 'json-file', + 'options': { + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + actual = config.merge_service_dicts(base, override, V2_0) + assert actual == { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'json-file', + 'options': { + 'frequency': '2000', + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + def test_merge_logging_v2_no_drivers(self): + base = { + 'image': 'alpine:edge', + 'logging': { + 'options': { + 'frequency': '2000', + 'timeout': '23' + } + } + } + override = { + 'logging': { + 'options': { + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + actual = config.merge_service_dicts(base, override, V2_0) + assert actual == { + 'image': 'alpine:edge', + 'logging': { + 'options': { + 'frequency': '2000', + 'timeout': '360', + 'pretty-print': 'on' + } + } + } + + def test_merge_logging_v2_no_override_options(self): + base = { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'json-file', + 'options': { + 'frequency': '2000', + 'timeout': '23' + } + } + } + override = { + 'logging': { + 'driver': 'syslog' + } + } + + actual = config.merge_service_dicts(base, override, V2_0) + assert actual == { + 'image': 'alpine:edge', + 'logging': { + 'driver': 'syslog', + 'options': None + } + } + def test_external_volume_config(self): config_details = build_config_details({ 'version': '2',