Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-1-parser-test-suite 2fdd7b718 -> 0377542a3 (forced update)
More template tests Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/0377542a Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/0377542a Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/0377542a Branch: refs/heads/ARIA-1-parser-test-suite Commit: 0377542a3eb8f8002718085bcd634c0ec5165495 Parents: da725c5 Author: Tal Liron <[email protected]> Authored: Fri Sep 15 15:24:41 2017 -0500 Committer: Tal Liron <[email protected]> Committed: Fri Sep 15 17:55:16 2017 -0500 ---------------------------------------------------------------------- aria/orchestrator/topology/template_handler.py | 7 +- .../simple_v1_0/modeling/__init__.py | 8 + .../simple_v1_0/modeling/groups.py | 43 +++++ .../presentation/field_validators.py | 59 ++++++- .../simple_v1_0/templates.py | 13 +- .../aria_extension_tosca/simple_v1_0/types.py | 6 + .../aria_extension_tosca/simple_v1_0/data.py | 5 +- .../simple_v1_0/templates/test_group.py | 158 +++++++++++++++++++ .../node-cellar/node-cellar.yaml | 6 +- 9 files changed, 291 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/aria/orchestrator/topology/template_handler.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/topology/template_handler.py b/aria/orchestrator/topology/template_handler.py index 86a60f5..067869d 100644 --- a/aria/orchestrator/topology/template_handler.py +++ b/aria/orchestrator/topology/template_handler.py @@ -108,17 +108,18 @@ class ServiceTemplate(common.TemplateHandlerBase): def _scaling(self, node_template): scaling = node_template.scaling - if any([scaling['min_instances'] < 0, + if any((scaling['min_instances'] < 0, scaling['max_instances'] < scaling['min_instances'], scaling['max_instances'] < 0, scaling['default_instances'] < 0, scaling['default_instances'] < scaling['min_instances'], scaling['default_instances'] > scaling['max_instances'] - ]): + )): self._topology.report( u'invalid scaling parameters for node template "{0}": min={min_instances}, max=' - u'{max_instances}, default={default_instances}'.format(self._model.name, **scaling), + u'{max_instances}, default={default_instances}'.format(node_template.name, + **scaling), level=self._topology.Issue.BETWEEN_TYPES) return scaling http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py index d7b69f6..d5938eb 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py +++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py @@ -316,6 +316,10 @@ def create_relationship_template_model(context, service_template, relationship): create_parameter_models_from_assignments(model.properties, relationship.properties, model_cls=Property) + # TODO: does not exist in models, but should + #create_parameter_models_from_assignments(model.attributes, + # relationship.attributes, + # model_cls=Attribute) create_interface_template_models(context, service_template, model.interface_templates, relationship.interfaces) @@ -347,6 +351,10 @@ def create_capability_template_model(context, service_template, capability): create_parameter_models_from_assignments(model.properties, capability.properties, model_cls=Property) + # TODO: does not exist in models, but should + #create_parameter_models_from_assignments(model.attributes, + # capability.attributes, + # model_cls=Attribute) return model http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/extensions/aria_extension_tosca/simple_v1_0/modeling/groups.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/groups.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/groups.py new file mode 100644 index 0000000..1d8013b --- /dev/null +++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/groups.py @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ..presentation.types import convert_name_to_full_type_name + + +# +# GroupType +# + +def get_inherited_members(context, presentation): + """ + Returns our target node types if we have them or those of our parent, if we have one + (recursively). + """ + + parent = presentation._get_parent(context) + + node_types = get_inherited_members(context, parent) if parent is not None else [] + + our_members = presentation.members + if our_members: + all_node_types = context.presentation.get('service_template', 'node_types') or {} + node_types = [] + + for our_member in our_members: + if our_member in all_node_types: + our_member = convert_name_to_full_type_name(context, our_member, all_node_types) + node_types.append(all_node_types[our_member]) + + return node_types http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py index d5c585e..067613b 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py @@ -469,6 +469,54 @@ def list_node_type_or_group_type_validator(field, presentation, context): # +# GroupTemplate +# + +def group_members_validator(field, presentation, context): + """ + Makes sure that the field's elements refer to node templates and that they match the node types + declared in the group type. + + Used with the :func:`field_validator` decorator for the ``targets`` field in + :class:`GroupTemplate`. + """ + + field.default_validate(presentation, context) + + values = getattr(presentation, field.name) + if values is not None: + node_templates = \ + context.presentation.get('service_template', 'topology_template', 'node_templates') \ + or {} + for value in values: + if value not in node_templates: + report_issue_for_unknown_type(context, presentation, 'node template', field.name, + value) + + group_type = presentation._get_type(context) + if group_type is None: + break + + node_types = group_type._get_members(context) + + is_valid = False + + if value in node_templates: + our_node_type = node_templates[value]._get_type(context) + for node_type in node_types: + if node_type._is_descendant(context, our_node_type): + is_valid = True + break + + if not is_valid: + context.validation.report( + u'group definition target does not match a node type' + u' declared in the group type in "{0}": {1}' + .format(presentation._name, safe_repr(value)), + locator=presentation._locator, level=Issue.BETWEEN_TYPES) + + +# # PolicyTemplate # @@ -485,13 +533,12 @@ def policy_targets_validator(field, presentation, context): values = getattr(presentation, field.name) if values is not None: - for value in values: - node_templates = \ - context.presentation.get('service_template', 'topology_template', - 'node_templates') \ - or {} - groups = context.presentation.get('service_template', 'topology_template', 'groups') \ + node_templates = \ + context.presentation.get('service_template', 'topology_template', 'node_templates') \ or {} + groups = context.presentation.get('service_template', 'topology_template', 'groups') \ + or {} + for value in values: if (value not in node_templates) and (value not in groups): report_issue_for_unknown_type(context, presentation, 'node template or group', field.name, value) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/extensions/aria_extension_tosca/simple_v1_0/templates.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/templates.py b/extensions/aria_extension_tosca/simple_v1_0/templates.py index 3c36bb8..64fd2d4 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/templates.py +++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py @@ -19,7 +19,7 @@ from aria.parser import implements_specification from aria.parser.presentation import (has_fields, primitive_field, primitive_list_field, object_field, object_list_field, object_dict_field, object_sequenced_list_field, field_validator, - type_validator, list_type_validator) + type_validator) from .assignments import (PropertyAssignment, AttributeAssignment, RequirementAssignment, CapabilityAssignment, InterfaceAssignment, ArtifactAssignment) @@ -34,7 +34,8 @@ from .modeling.artifacts import get_inherited_artifact_definitions from .modeling.policies import get_policy_targets from .modeling.copy import get_default_raw_from_copy from .presentation.extensible import ExtensiblePresentation -from .presentation.field_validators import copy_validator, policy_targets_validator +from .presentation.field_validators import (copy_validator, group_members_validator, + policy_targets_validator) from .presentation.types import (convert_name_to_full_type_name, get_type_by_name) from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType, NodeType, GroupType, PolicyType) @@ -182,6 +183,7 @@ class NodeTemplate(ExtensiblePresentation): def _validate(self, context): super(NodeTemplate, self)._validate(context) self._get_property_values(context) + self._get_attribute_default_values(context) self._get_requirements(context) self._get_capabilities(context) self._get_interfaces(context) @@ -284,12 +286,17 @@ class RelationshipTemplate(ExtensiblePresentation): return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property')) @cachedmethod + def _get_attribute_default_values(self, context): + return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'attribute')) + + @cachedmethod def _get_interfaces(self, context): return FrozenDict(get_template_interfaces(context, self, 'relationship template')) def _validate(self, context): super(RelationshipTemplate, self)._validate(context) self._get_property_values(context) + self._get_attribute_default_values(context) self._get_interfaces(context) def _dump(self, context): @@ -340,7 +347,7 @@ class GroupTemplate(ExtensiblePresentation): :type: {:obj:`basestring`: :class:`PropertyAssignment`} """ - @field_validator(list_type_validator('node template', 'topology_template', 'node_templates')) + @field_validator(group_members_validator) @primitive_list_field(str) def members(self): """ http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/extensions/aria_extension_tosca/simple_v1_0/types.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py index 88f4e1a..76e9fed 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/types.py +++ b/extensions/aria_extension_tosca/simple_v1_0/types.py @@ -34,6 +34,7 @@ from .modeling.capabilities import (get_inherited_valid_source_types, from .modeling.data_types import (get_data_type, get_inherited_constraints, coerce_data_type_value, validate_data_type_name) from .modeling.interfaces import (get_inherited_interface_definitions, get_inherited_operations) +from .modeling.groups import get_inherited_members from .modeling.policies import get_inherited_targets from .modeling.parameters import get_inherited_parameter_definitions from .modeling.requirements import get_inherited_requirement_definitions @@ -808,6 +809,11 @@ class GroupType(ExtensiblePresentation): return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties')) @cachedmethod + def _get_members(self, context): + node_types = get_inherited_members(context, self) + return FrozenList(node_types) + + @cachedmethod def _get_interfaces(self, context): return FrozenDict(get_inherited_interface_definitions(context, self, 'group type')) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py index 1859037..1fc808c 100644 --- a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py @@ -31,16 +31,19 @@ TYPE_NAME_PLURAL = { } PRIMITIVE_TYPE_NAMES = ('string', 'integer', 'float', 'boolean') PARAMETER_SECTION_NAMES = ('properties', 'attributes') -TEMPLATE_NAMES = ('node', 'group', 'policy') +TEMPLATE_NAMES = ('node', 'group', 'relationship', 'policy') TEMPLATE_NAME_SECTIONS = { 'node': 'node_templates', 'group': 'groups', + 'relationship': 'relationship_templates', 'policy': 'policies' } TEMPLATE_PARAMETER_SECTIONS = ( ('node', 'properties'), ('node', 'attributes'), ('group', 'properties'), + ('relationship', 'properties'), + ('relationship', 'attributes'), ('policy', 'properties') ) PARAMETER_SECTIONS = ( http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_group.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_group.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_group.py new file mode 100644 index 0000000..56eb35c --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_group.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from .. import data + + +# Members + [email protected]('value', data.NOT_A_LIST) +def test_group_members_wrong_yaml_type(parser, value): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +group_types: + MyType: {} +topology_template: + groups: + my_policy: + type: MyType + members: {{ value }} +""", dict(value=value)).assert_failure() + + [email protected]('value', data.NOT_A_STRING) +def test_group_members_element_wrong_yaml_type(parser, value): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +group_types: + MyType: {} +topology_template: + groups: + my_policy: + type: MyType + members: [ {{ value }} ] +""", dict(value=value)).assert_failure() + + +def test_group_members_empty(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +group_types: + MyType: {} +topology_template: + groups: + my_policy: + type: MyType + members: [] +""").assert_success() + + +def test_group_members(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType1: {} + MyType2: {} +group_types: + MyType: + members: [ MyType1, MyType2 ] +topology_template: + node_templates: + my_node1: + type: MyType1 + my_node2: + type: MyType2 + groups: + my_policy: + type: MyType + members: [ my_node1, my_node2 ] +""").assert_success() + + +def test_group_members_derived(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType1: {} + MyType2: + derived_from: MyType1 +group_types: + MyType: + members: [ MyType1 ] +topology_template: + node_templates: + my_node: + type: MyType2 + groups: + my_policy: + type: MyType + members: [ my_node ] +""").assert_success() + + +def test_group_members_derived_bad(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType1: {} + MyType2: + derived_from: MyType1 +group_types: + MyType: + members: [ MyType2 ] +topology_template: + node_templates: + my_node: + type: MyType1 + groups: + my_policy: + type: MyType + members: [ my_node ] +""").assert_failure() + + +def test_group_members_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + é¡å: {} +group_types: + é¡å: + members: [ é¡å ] +topology_template: + node_templates: + ç¯é»: + type: é¡å + groups: + æ¿ç: + type: é¡å + members: [ ç¯é» ] +""").assert_success() + + +def test_group_members_unknown(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +group_types: + MyType: {} +topology_template: + groups: + my_policy: + type: MyType + members: [ unknown ] +""").assert_failure() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0377542a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml ---------------------------------------------------------------------- diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml index ff5cb1f..0a0098a 100644 --- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml +++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml @@ -215,6 +215,10 @@ topology_template: os_users: # map of os.UserInfo root: password: admin123 + capabilities: + scalable: + properties: + max_instances: 2 interfaces: Standard: inputs: @@ -277,7 +281,7 @@ topology_template: node_cellar_group: type: openstack.Secured members: - - loadbalancer + - loadbalancer_host - application_host - data_host interfaces:
