summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Herve <therve@redhat.com>2017-10-03 16:10:29 +0200
committerEmilien Macchi <emilien@redhat.com>2018-11-23 00:18:31 +0000
commit5619c0f7894718c2d6a15b80565c91d624726468 (patch)
treecd58e6cefc47fac3a561ac4511352d1b603972f3
parentfdc7ba604f1cf624d5ff5b7dd597b8dec5790c60 (diff)
downloadpython-heatclient-1.11.2.tar.gz
Don't override sections in deep_updatepike-em1.11.2
When you comment all the elements in a YAML mapping, you end up with None instead of an empty mapping, which can have bad side effect when handling multiple environemnents. Let's handle that by ignoring the latest None value. Change-Id: I77ffabeb8d4cd2886ef4f41351e42ebe487b5d4b (cherry picked from commit 2a8ce0d0656f47331a164163f9e3b302de4d3c88)
-rw-r--r--heatclient/common/template_utils.py3
-rw-r--r--heatclient/tests/unit/test_template_utils.py45
2 files changed, 48 insertions, 0 deletions
diff --git a/heatclient/common/template_utils.py b/heatclient/common/template_utils.py
index 9e9c85b..b38710b 100644
--- a/heatclient/common/template_utils.py
+++ b/heatclient/common/template_utils.py
@@ -198,6 +198,9 @@ def deep_update(old, new):
if isinstance(v, collections.Mapping):
r = deep_update(old.get(k, {}), v)
old[k] = r
+ elif v is None and isinstance(old.get(k), collections.Mapping):
+ # Don't override empty data, to work around yaml syntax issue
+ pass
else:
old[k] = new[k]
return old
diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py
index a48e0b3..01cfa13 100644
--- a/heatclient/tests/unit/test_template_utils.py
+++ b/heatclient/tests/unit/test_template_utils.py
@@ -448,6 +448,51 @@ class ShellEnvironmentTest(testtools.TestCase):
])
+ @mock.patch('six.moves.urllib.request.urlopen')
+ def test_process_multiple_environments_empty_registry(self, mock_url):
+ # Setup
+ env_file1 = '/home/my/dir/env1.yaml'
+ env_file2 = '/home/my/dir/env2.yaml'
+
+ env1 = b'''
+ resource_registry:
+ "OS::Thingy1": "file:///home/b/a.yaml"
+ '''
+ env2 = b'''
+ resource_registry:
+ '''
+ mock_url.side_effect = [six.BytesIO(env1),
+ six.BytesIO(self.template_a),
+ six.BytesIO(self.template_a),
+ six.BytesIO(env2)]
+
+ # Test
+ env_file_list = []
+ files, env = template_utils.process_multiple_environments_and_files(
+ [env_file1, env_file2], env_list_tracker=env_file_list)
+
+ # Verify
+ expected_env = {
+ 'resource_registry': {'OS::Thingy1': 'file:///home/b/a.yaml'}}
+ self.assertEqual(expected_env, env)
+
+ self.assertEqual(self.template_a.decode('utf-8'),
+ files['file:///home/b/a.yaml'])
+
+ self.assertEqual(['file:///home/my/dir/env1.yaml',
+ 'file:///home/my/dir/env2.yaml'], env_file_list)
+ self.assertIn('file:///home/my/dir/env1.yaml', files)
+ self.assertIn('file:///home/my/dir/env2.yaml', files)
+ self.assertEqual(expected_env,
+ json.loads(files['file:///home/my/dir/env1.yaml']))
+ mock_url.assert_has_calls([
+ mock.call('file://%s' % env_file1),
+ mock.call('file:///home/b/a.yaml'),
+ mock.call('file:///home/b/a.yaml'),
+ mock.call('file://%s' % env_file2),
+
+ ])
+
def test_global_files(self):
url = 'file:///home/b/a.yaml'
env = '''