Add keys validation testcase in substitution_mapping class 21/20921/1
authorshangxdy <shang.xiaodong@zte.com.cn>
Fri, 9 Sep 2016 09:41:48 +0000 (17:41 +0800)
committerxiaodong shang <shang.xiaodong@zte.com.cn>
Mon, 12 Sep 2016 15:20:19 +0000 (15:20 +0000)
Add keys validation in class of substitution_mapping according to
specification of
http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/TOSCA-Simple-Profile-YAML-v1.0.html:
1) Substitution mapping only supports keys of node_type, capabilities
and requirements;
2) The key of node_type is required, the others are optional.

JIRA:PARSER-80

Change-Id: Icd3284349175429e5ba5e52814819a6790f0e831
Signed-off-by: shangxdy <shang.xiaodong@zte.com.cn>
(cherry picked from commit 44540b6c2b16637659099c65e31309fc7573ba7d)

tosca2heat/tosca-parser/toscaparser/substitution_mappings.py
tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py
tosca2heat/tosca-parser/toscaparser/tosca_template.py

index fe47ae4..35ffdf3 100644 (file)
@@ -19,7 +19,7 @@ from toscaparser.common.exception import MissingRequiredInputError
 from toscaparser.common.exception import MissingRequiredParameterError
 from toscaparser.common.exception import UnknownFieldError
 from toscaparser.elements.nodetype import NodeType
-
+from toscaparser.utils.gettextutils import _
 
 log = logging.getLogger('tosca')
 
@@ -47,6 +47,11 @@ class SubstitutionMappings(object):
         self._capabilities = None
         self._requirements = None
 
+    @property
+    def type(self):
+        if self.sub_mapping_def:
+            return self.sub_mapping_def.get(self.NODE_TYPE)
+
     @classmethod
     def get_node_type(cls, sub_mapping_def):
         if isinstance(sub_mapping_def, dict):
@@ -84,7 +89,7 @@ class SubstitutionMappings(object):
         for key in self.sub_mapping_def.keys():
             if key not in self.SECTIONS:
                 ExceptionCollector.appendException(
-                    UnknownFieldError(what='SubstitutionMappings',
+                    UnknownFieldError(what=_('SubstitutionMappings'),
                                       field=key))
 
     def _validate_type(self):
@@ -119,7 +124,7 @@ class SubstitutionMappings(object):
                propery.name not in [input.name for input in self.inputs]:
                 ExceptionCollector.appendException(
                     MissingRequiredInputError(
-                        what='SubstitutionMappings with node_type:'
+                        what=_('SubstitutionMappings with node_type:')
                         + self.node_type,
                         input_name=propery.name))
 
@@ -140,7 +145,7 @@ class SubstitutionMappings(object):
             if input.name not in property_names and input.default is None:
                 ExceptionCollector.appendException(
                     MissingRequiredParameterError(
-                        what='SubstitutionMappings with node_type:'
+                        what=_('SubstitutionMappings with node_type:')
                         + self.node_type,
                         input_name=input.name))
 
index 6e3eb62..edb834b 100644 (file)
 
 import os
 
+from toscaparser.common import exception
+from toscaparser.substitution_mappings import SubstitutionMappings
 from toscaparser.tests.base import TestCase
 from toscaparser.topology_template import TopologyTemplate
 from toscaparser.tosca_template import ToscaTemplate
+from toscaparser.utils.gettextutils import _
 import toscaparser.utils.yamlparser
 
 YAML_LOADER = toscaparser.utils.yamlparser.load_yaml
@@ -162,3 +165,43 @@ class TopologyTemplateTest(TestCase):
         self.assertEqual(
             len(system_tosca_template.
                 nested_tosca_templates_with_topology), 4)
+
+    def test_invalid_keyname(self):
+        tpl_snippet = '''
+        substitution_mappings:
+          node_type: example.DatabaseSubsystem
+          capabilities:
+            database_endpoint: [ db_app, database_endpoint ]
+          requirements:
+            receiver1: [ tran_app, receiver1 ]
+          invalid_key: 123
+        '''
+        sub_mappings = (toscaparser.utils.yamlparser.
+                        simple_parse(tpl_snippet))['substitution_mappings']
+        expected_message = _(
+            'SubstitutionMappings contains unknown field '
+            '"invalid_key". Refer to the definition '
+            'to verify valid values.')
+        err = self.assertRaises(
+            exception.UnknownFieldError,
+            lambda: SubstitutionMappings(sub_mappings, None, None,
+                                         None, None, None))
+        self.assertEqual(expected_message, err.__str__())
+
+    def test_missing_required_keyname(self):
+        tpl_snippet = '''
+        substitution_mappings:
+          capabilities:
+            database_endpoint: [ db_app, database_endpoint ]
+          requirements:
+            receiver1: [ tran_app, receiver1 ]
+        '''
+        sub_mappings = (toscaparser.utils.yamlparser.
+                        simple_parse(tpl_snippet))['substitution_mappings']
+        expected_message = _('SubstitutionMappings used in topology_template '
+                             'is missing required field "node_type".')
+        err = self.assertRaises(
+            exception.MissingRequiredFieldError,
+            lambda: SubstitutionMappings(sub_mappings, None, None,
+                                         None, None, None))
+        self.assertEqual(expected_message, err.__str__())
index 2e815fd..84d953c 100644 (file)
@@ -233,7 +233,7 @@ class ToscaTemplate(object):
                         path=fname, parsed_params=parsed_params,
                         yaml_dict_tpl=tosca_tpl,
                         sub_mapped_node_template=nodetemplate)
-                    if nested_template.has_substitution_mappings():
+                    if nested_template._has_substitution_mappings():
                         # Record the nested templates in top level template
                         self.nested_tosca_templates_with_topology.\
                             append(nested_template)
@@ -329,7 +329,7 @@ class ToscaTemplate(object):
             return TopologyTemplate.get_sub_mapping_node_type(
                 tosca_tpl.get(TOPOLOGY_TEMPLATE))
 
-    def has_substitution_mappings(self):
+    def _has_substitution_mappings(self):
         """Return True if the template has valid substitution mappings."""
         return self.topology_template is not None and \
             self.topology_template.substitution_mappings is not None