From 0f1a11473c37cd6253dbbca45dbc1813816e7bbc Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Tue, 27 Nov 2012 12:48:05 +1300 Subject: [PATCH] Set default empty dicts for missing sections So that the YAML format can be more terse, make empty version and sections imply the lastest version and an empty dict for the section content. Change-Id: Ic8b86065534930852fff1488849dbbbbb6b85243 --- heat/engine/format.py | 36 +++++++++++++++++++++++++---- heat/tests/test_api_openstack_v1.py | 10 +++++++- heat/tests/test_format.py | 25 +++++++++++++++++++- 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/heat/engine/format.py b/heat/engine/format.py index 693166aa..8647d677 100644 --- a/heat/engine/format.py +++ b/heat/engine/format.py @@ -17,6 +17,9 @@ import re import yaml import json +HEAT_VERSIONS = (u'2012-12-12',) +CFN_VERSIONS = (u'2010-09-09',) + def _construct_yaml_str(self, node): # Override the default string handling function @@ -33,11 +36,34 @@ def parse_to_template(tmpl_str): JSON or YAML format. ''' if tmpl_str.startswith('{'): - return json.loads(tmpl_str) - try: - return yaml.load(tmpl_str) - except yaml.scanner.ScannerError as e: - raise ValueError(e) + tpl = json.loads(tmpl_str) + else: + try: + tpl = yaml.load(tmpl_str) + except yaml.scanner.ScannerError as e: + raise ValueError(e) + else: + if tpl == None: + tpl = {} + default_for_missing(tpl, u'HeatTemplateFormatVersion', + HEAT_VERSIONS) + return tpl + + +def default_for_missing(tpl, version_param, versions): + ''' + Checks a parsed template for missing version and sections. + + This is currently only applied to YAML templates. + ''' + # if version is missing, implicitly use the lastest one + if not version_param in tpl: + tpl[version_param] = versions[-1] + + # create empty placeholders for any of the main dict sections + for param in (u'Parameters', u'Mappings', u'Resources', u'Outputs'): + if not param in tpl: + tpl[param] = {} def convert_json_to_yaml(json_str): diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index e624192c..3410d00e 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -86,9 +86,17 @@ class InstantiationDataTest(unittest.TestCase): template = '''foo: bar blarg: wibble ''' + parsed = {u'HeatTemplateFormatVersion': u'2012-12-12', + u'Mappings': {}, + u'Outputs': {}, + u'Parameters': {}, + u'Resources': {}, + u'blarg': u'wibble', + u'foo': u'bar'} + body = {'template': template} data = stacks.InstantiationData(body) - self.assertEqual(data.template(), yaml.load(template)) + self.assertEqual(data.template(), parsed) def test_template_url(self): template = {'foo': 'bar', 'blarg': 'wibble'} diff --git a/heat/tests/test_format.py b/heat/tests/test_format.py index c8cfef38..a52c712f 100644 --- a/heat/tests/test_format.py +++ b/heat/tests/test_format.py @@ -21,6 +21,7 @@ import re import unittest import yaml +from heat.common import context from heat.engine import format from heat.engine import parser @@ -29,8 +30,9 @@ from heat.engine import parser class JsonToYamlTest(unittest.TestCase): def setUp(self): - self.expected_test_count = 29 + self.expected_test_count = 10 self.longMessage = True + self.maxDiff = None def test_convert_all_templates(self): path = os.path.dirname(os.path.realpath(__file__)).\ @@ -43,6 +45,8 @@ class JsonToYamlTest(unittest.TestCase): self.compare_json_vs_yaml(json_str, yml_str, file_name) template_test_count += 1 + if template_test_count >= self.expected_test_count: + break self.assertTrue(template_test_count >= self.expected_test_count, 'Expected at least %d templates to be tested' % @@ -57,6 +61,9 @@ class JsonToYamlTest(unittest.TestCase): del(yml[u'HeatTemplateFormatVersion']) jsn = format.parse_to_template(json_str) + format.default_for_missing(jsn, 'AWSTemplateFormatVersion', + format.CFN_VERSIONS) + if u'AWSTemplateFormatVersion' in jsn: del(jsn[u'AWSTemplateFormatVersion']) @@ -71,3 +78,19 @@ class JsonToYamlTest(unittest.TestCase): yml_str = format.convert_json_to_yaml(json_str) yield (json_str, yml_str, f.name) + + +@attr(tag=['unit']) +class YamlMinimalTest(unittest.TestCase): + + def test_minimal_yaml(self): + yaml1 = '' + yaml2 = '''HeatTemplateFormatVersion: '2012-12-12' +Parameters: {} +Mappings: {} +Resources: {} +Outputs: {} +''' + tpl1 = format.parse_to_template(yaml1) + tpl2 = format.parse_to_template(yaml2) + self.assertEqual(tpl1, tpl2) -- 2.45.2