diff --git a/heatclient/common/template_utils.py b/heatclient/common/template_utils.py index 9e9c85bf..b38710be 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 a48e0b36..01cfa13a 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 = '''