http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py index e2af4b8..ae2f924 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py +++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py @@ -18,8 +18,7 @@ from aria.parser.validation import Issue def validate_substitution_mappings_requirement(context, presentation): - - # validate that the requirement in substitution_mapping is defined in the substitution node type + # Validate that the requirement in substitution_mapping is defined in the substitution node type substitution_node_type = presentation._container._get_type(context) if substitution_node_type is None: return @@ -29,7 +28,7 @@ def validate_substitution_mappings_requirement(context, presentation): break else: context.validation.report( - 'substitution mapping requirement "{0}" is not declared in node type "{1}"'.format( + u'substitution mapping requirement "{0}" is not declared in node type "{1}"'.format( presentation._name, substitution_node_type._name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return @@ -38,7 +37,7 @@ def validate_substitution_mappings_requirement(context, presentation): _report_invalid_mapping_format(context, presentation, field='requirement') return - # validate that the mapped requirement is defined in the corresponding node template + # Validate that the mapped requirement is defined in the corresponding node template node_template = _get_node_template(context, presentation) if node_template is None: _report_missing_node_template(context, presentation, field='requirement') @@ -50,24 +49,24 @@ def validate_substitution_mappings_requirement(context, presentation): break else: context.validation.report( - 'substitution mapping requirement "{0}" refers to an unknown requirement of node ' - 'template "{1}": {mapped_requirement_name}'.format( + u'substitution mapping requirement "{0}" refers to an unknown requirement of node ' + u'template "{1}": {mapped_requirement_name}'.format( presentation._name, node_template._name, mapped_requirement_name=safe_repr(mapped_requirement_name)), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return - # validate that the requirement's capability type in substitution_mapping is derived from the + # Validate that the requirement's capability type in substitution_mapping is derived from the # requirement's capability type in the corresponding node template substitution_type_requirement_capability_type = \ substitution_type_requirement._get_capability_type(context) node_template_requirement_capability_type = \ node_template_requirement._get_capability(context)[0] - if not node_template_requirement_capability_type._is_descendant( - context, substitution_type_requirement_capability_type): + if not substitution_type_requirement_capability_type._is_descendant( + context, node_template_requirement_capability_type): context.validation.report( - 'substitution mapping requirement "{0}" of capability type "{1}" is not a descendant ' - 'of the mapped node template capability type "{2}"'.format( + u'substitution mapping requirement "{0}" of capability type "{1}" is not a descendant ' + u'of the mapped node template capability type "{2}"'.format( presentation._name, substitution_type_requirement_capability_type._name, node_template_requirement_capability_type._name), @@ -75,8 +74,7 @@ def validate_substitution_mappings_requirement(context, presentation): def validate_substitution_mappings_capability(context, presentation): - - # validate that the capability in substitution_mapping is defined in the substitution node type + # Validate that the capability in substitution_mapping is defined in the substitution node type substitution_node_type = presentation._container._get_type(context) if substitution_node_type is None: return @@ -84,8 +82,8 @@ def validate_substitution_mappings_capability(context, presentation): substitution_type_capability = substitution_type_capabilities.get(presentation._name) if substitution_type_capability is None: context.validation.report( - 'substitution mapping capability "{0}" ' - 'is not declared in node type "{substitution_type}"'.format( + u'substitution mapping capability "{0}" ' + u'is not declared in node type "{substitution_type}"'.format( presentation._name, substitution_type=substitution_node_type._name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return @@ -94,7 +92,7 @@ def validate_substitution_mappings_capability(context, presentation): _report_invalid_mapping_format(context, presentation, field='capability') return - # validate that the capability in substitution_mapping is declared in the corresponding + # Validate that the capability in substitution_mapping is declared in the corresponding # node template node_template = _get_node_template(context, presentation) if node_template is None: @@ -105,22 +103,21 @@ def validate_substitution_mappings_capability(context, presentation): if node_template_capability is None: context.validation.report( - 'substitution mapping capability "{0}" refers to an unknown ' - 'capability of node template "{1}": {mapped_capability_name}'.format( + u'substitution mapping capability "{0}" refers to an unknown ' + u'capability of node template "{1}": {mapped_capability_name}'.format( presentation._name, node_template._name, mapped_capability_name=safe_repr(mapped_capability_name)), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return - # validate that the capability type in substitution_mapping is derived from the capability type + # Validate that the capability type in substitution_mapping is derived from the capability type # in the corresponding node template substitution_type_capability_type = substitution_type_capability._get_type(context) node_template_capability_type = node_template_capability._get_type(context) - if not substitution_type_capability_type._is_descendant(context, node_template_capability_type): context.validation.report( - 'node template capability type "{0}" is not a descendant of substitution mapping ' - 'capability "{1}" of type "{2}"'.format( + u'node template capability type "{0}" is not a descendant of substitution mapping ' + u'capability "{1}" of type "{2}"'.format( node_template_capability_type._name, presentation._name, substitution_type_capability_type._name), @@ -132,7 +129,9 @@ def validate_substitution_mappings_capability(context, presentation): # def _validate_mapping_format(presentation): - """Validate that the mapping is a list of 2 strings""" + """ + Validate that the mapping is a list of 2 strings. + """ if not isinstance(presentation._raw, list) or \ len(presentation._raw) != 2 or \ not isinstance(presentation._raw[0], basestring) or \ @@ -150,8 +149,8 @@ def _get_node_template(context, presentation): def _report_missing_node_template(context, presentation, field): context.validation.report( - 'substitution mappings {field} "{node_template_mapping}" ' - 'refers to an unknown node template: {node_template_name}'.format( + u'substitution mappings {field} "{node_template_mapping}" ' + u'refers to an unknown node template: {node_template_name}'.format( field=field, node_template_mapping=presentation._name, node_template_name=safe_repr(presentation._raw[0])), @@ -160,7 +159,7 @@ def _report_missing_node_template(context, presentation, field): def _report_invalid_mapping_format(context, presentation, field): context.validation.report( - 'substitution mapping {field} "{field_name}" is not a list of 2 strings: {value}'.format( + u'substitution mapping {field} "{field_name}" is not a list of 2 strings: {value}'.format( field=field, field_name=presentation._name, value=safe_repr(presentation._raw)),
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py index 0e3c94d..9fa056d 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py @@ -30,4 +30,4 @@ class ExtensiblePresentation(Presentation): @cachedmethod def _get_extension(self, name, default=None): extensions = self._extensions - return extensions.get(name, default) if extensions is not None else None # pylint: disable=no-member + return extensions.get(name, default) if extensions is not None else None # pylint: disable=no-member http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py index f14164a..9cd58e2 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py @@ -14,10 +14,12 @@ # limitations under the License. from aria.utils.formatting import safe_repr +from aria.utils.type import full_type_name from aria.parser.exceptions import InvalidValueError +from aria.parser.presentation import NULL -def data_type_class_getter(cls): +def data_type_class_getter(cls, allow_null=False): """ Wraps the field value in a specialized data type class. @@ -26,12 +28,14 @@ def data_type_class_getter(cls): def getter(field, presentation, context=None): raw = field.default_get(presentation, context) - if raw is not None: - try: - return cls(None, None, raw, None) - except ValueError as e: - raise InvalidValueError( - '%s is not a valid "%s" in "%s": %s' - % (field.full_name, field.full_cls_name, presentation._name, safe_repr(raw)), - cause=e, locator=field.get_locator(raw)) + if (raw is None) or (allow_null and (raw is NULL)): + return raw + try: + return cls(None, None, raw, None) + except ValueError as e: + raise InvalidValueError( + u'{0} is not a valid "{1}" in "{2}": {3}' + .format(field.full_name, full_type_name(cls), presentation._name, + safe_repr(raw)), + cause=e, locator=field.get_locator(raw)) return getter http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/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 e5853d8..2ff5143 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 @@ -52,8 +52,8 @@ def copy_validator(template_type_name, templates_dict_name): else: if copy.copy is not None: context.validation.report( - '"copy" field refers to a %s that itself is a copy in "%s": %s' - % (template_type_name, presentation._fullname, safe_repr(value)), + u'"copy" field refers to a {0} that itself is a copy in "{1}": {2}' + .format(template_type_name, presentation._fullname, safe_repr(value)), locator=presentation._locator, level=Issue.BETWEEN_TYPES) return validator_fn @@ -84,8 +84,8 @@ def data_type_validator(type_name='data type'): container_data_type = get_container_data_type(presentation) if (container_data_type is not None) and (container_data_type._name == value): context.validation.report( - 'type of property "%s" creates a circular value hierarchy: %s' - % (presentation._fullname, safe_repr(value)), + u'type of property "{0}" creates a circular value hierarchy: {1}' + .format(presentation._fullname, safe_repr(value)), locator=presentation._get_child_locator('type'), level=Issue.BETWEEN_TYPES) # Can be a complex data type @@ -135,14 +135,14 @@ def entry_schema_validator(field, presentation, context): if use_entry_schema: if value is None: context.validation.report( - '"entry_schema" does not have a value as required by data type "%s" in "%s"' - % (get_data_type_name(the_type), presentation._container._fullname), + u'"entry_schema" does not have a value as required by data type "{0}" in "{1}"' + .format(get_data_type_name(the_type), presentation._container._fullname), locator=presentation._locator, level=Issue.BETWEEN_TYPES) else: if value is not None: context.validation.report( - '"entry_schema" has a value but it is not used by data type "%s" in "%s"' - % (get_data_type_name(the_type), presentation._container._fullname), + u'"entry_schema" has a value but it is not used by data type "{0}" in "{1}"' + .format(get_data_type_name(the_type), presentation._container._fullname), locator=presentation._locator, level=Issue.BETWEEN_TYPES) @@ -201,8 +201,8 @@ def data_type_constraints_validator(field, presentation, context): if value is not None: if presentation._get_primitive_ancestor(context) is None: context.validation.report( - 'data type "%s" defines constraints but does not have a primitive ancestor' - % presentation._fullname, + u'data type "{0}" defines constraints but does not have a primitive ancestor' + .format(presentation._fullname), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES) @@ -220,8 +220,8 @@ def data_type_properties_validator(field, presentation, context): if values is not None: if presentation._get_primitive_ancestor(context) is not None: context.validation.report( - 'data type "%s" defines properties even though it has a primitive ancestor' - % presentation._fullname, + u'data type "{0}" defines properties even though it has a primitive ancestor' + .format(presentation._fullname), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES) @@ -272,17 +272,18 @@ def constraint_clause_in_range_validator(field, presentation, context): # Upper bound be coercible upper = coerce_value(context, presentation, the_type, None, None, upper, field.name) - # Second "in_range" value must be greater than first + # Second "in_range" value must be greater or equal than first if (lower is not None) and (upper is not None) and (lower >= upper): context.validation.report( - 'upper bound of "in_range" constraint is not greater than the lower bound' - ' in "%s": %s <= %s' - % (presentation._container._fullname, safe_repr(lower), safe_repr(upper)), + u'upper bound of "in_range" constraint is not greater than the lower bound' + u' in "{0}": {1} <= {2}' + .format(presentation._container._fullname, safe_repr(lower), + safe_repr(upper)), locator=presentation._locator, level=Issue.FIELD) else: context.validation.report( - 'constraint "%s" is not a list of exactly 2 elements in "%s"' - % (field.name, presentation._fullname), + u'constraint "{0}" is not a list of exactly 2 elements in "{1}": {2}' + .format(field.name, presentation._fullname, safe_repr(values)), locator=presentation._get_child_locator(field.name), level=Issue.FIELD) @@ -325,8 +326,8 @@ def constraint_clause_pattern_validator(field, presentation, context): re.compile(value) except re.error as e: context.validation.report( - 'constraint "%s" is not a valid regular expression in "%s"' - % (field.name, presentation._fullname), + u'constraint "{0}" is not a valid regular expression in "{1}": {2}' + .format(field.name, presentation._fullname, safe_repr(value)), locator=presentation._get_child_locator(field.name), level=Issue.FIELD, exception=e) @@ -379,21 +380,21 @@ def capability_definition_or_type_validator(field, presentation, context): if get_type_by_name(context, value, 'capability_types') is not None: if node is not None: context.validation.report( - '"%s" refers to a capability type even though "node" has a value in "%s"' - % (presentation._name, presentation._container._fullname), + u'"{0}" refers to a capability type even though "node" has a value in "{1}"' + .format(presentation._name, presentation._container._fullname), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) return if node_variant == 'node_template': context.validation.report( - 'requirement "%s" refers to an unknown capability definition name or capability' - ' type in "%s": %s' - % (presentation._name, presentation._container._fullname, safe_repr(value)), + u'requirement "{0}" refers to an unknown capability definition name or capability' + u' type in "{1}": {2}' + .format(presentation._name, presentation._container._fullname, safe_repr(value)), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES) else: context.validation.report( - 'requirement "%s" refers to an unknown capability type in "%s": %s' - % (presentation._name, presentation._container._fullname, safe_repr(value)), + u'requirement "{0}" refers to an unknown capability type in "{1}": {2}' + .format(presentation._name, presentation._container._fullname, safe_repr(value)), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES) @@ -412,9 +413,9 @@ def node_filter_validator(field, presentation, context): _, node_type_variant = presentation._get_node(context) if node_type_variant != 'node_type': context.validation.report( - 'requirement "%s" has a node filter even though "node" does not refer to a node' - ' type in "%s"' - % (presentation._fullname, presentation._container._fullname), + u'requirement "{0}" has a node filter even though "node" does not refer to a node' + u' type in "{1}"' + .format(presentation._fullname, presentation._container._fullname), locator=presentation._locator, level=Issue.BETWEEN_FIELDS) @@ -468,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 # @@ -484,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) @@ -519,9 +567,9 @@ def policy_targets_validator(field, presentation, context): if not is_valid: context.validation.report( - 'policy definition target does not match either a node type or a group type' - ' declared in the policy type in "%s": %s' - % (presentation._name, safe_repr(value)), + u'policy definition target does not match either a node type or a group type' + u' declared in the policy type in "{0}": {1}' + .format(presentation._name, safe_repr(value)), locator=presentation._locator, level=Issue.BETWEEN_TYPES) @@ -547,8 +595,8 @@ def node_filter_properties_validator(field, presentation, context): for name, _ in values: if name not in properties: context.validation.report( - 'node filter refers to an unknown property definition in "%s": %s' - % (node_type._name, name), + u'node filter refers to an unknown property definition in "{0}": {1}' + .format(node_type._name, name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) @@ -564,7 +612,7 @@ def node_filter_capabilities_validator(field, presentation, context): field.default_validate(presentation, context) values = getattr(presentation, field.name) - if values is not None: # pylint: disable=too-many-nested-blocks + if values is not None: # pylint: disable=too-many-nested-blocks node_type = presentation._get_node_type(context) if node_type is not None: capabilities = node_type._get_capabilities(context) @@ -577,12 +625,12 @@ def node_filter_capabilities_validator(field, presentation, context): for property_name, _ in properties: if property_name not in capability_properties: context.validation.report( - 'node filter refers to an unknown capability definition' - ' property in "%s": %s' - % (node_type._name, property_name), + u'node filter refers to an unknown capability definition' + u' property in "{0}": {1}' + .format(node_type._name, property_name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) else: context.validation.report( - 'node filter refers to an unknown capability definition in "%s": %s' - % (node_type._name, name), + u'node filter refers to an unknown capability definition in "{0}": {1}' + .format(node_type._name, name), locator=presentation._locator, level=Issue.BETWEEN_TYPES) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py index 5f9750e..f31b6c9 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py @@ -14,7 +14,7 @@ # limitations under the License. -def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument +def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument """ Converts a type name to its full type name, or else returns it unchanged. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/extensions/aria_extension_tosca/simple_v1_0/presenter.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_v1_0/presenter.py index 28c9f7b..3aca91d 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py @@ -23,7 +23,7 @@ from .modeling.functions import (Concat, Token, GetInput, GetProperty, GetAttrib from .templates import ServiceTemplate -class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name,abstract-method +class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name,abstract-method """ ARIA presenter for the `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html>`__. @@ -78,5 +78,5 @@ class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name,abstrac return FrozenList(import_locations) if import_locations else EMPTY_READ_ONLY_LIST @cachedmethod - def _get_model(self, context): # pylint: disable=no-self-use + def _get_model(self, context): # pylint: disable=no-self-use return create_service_template_model(context) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/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..d4d012e 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/templates.py +++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py @@ -19,11 +19,11 @@ 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) -from .definitions import ParameterDefinition +from .definitions import (InputDefinition, OutputDefinition) from .filters import NodeFilter from .misc import (Description, MetaData, Repository, Import, SubstitutionMappings) from .modeling.parameters import (get_assigned_and_defined_parameter_values, get_parameter_values) @@ -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): """ @@ -464,13 +471,13 @@ class TopologyTemplate(ExtensiblePresentation): :type: :class:`Description` """ - @object_dict_field(ParameterDefinition) + @object_dict_field(InputDefinition) def inputs(self): """ An optional list of input parameters (i.e., as parameter definitions) for the Topology Template. - :type: {:obj:`basestring`: :class:`ParameterDefinition`} + :type: {:obj:`basestring`: :class:`InputDefinition`} """ @object_dict_field(NodeTemplate) @@ -506,13 +513,13 @@ class TopologyTemplate(ExtensiblePresentation): :type: {:obj:`basestring`: :class:`PolicyTemplate`} """ - @object_dict_field(ParameterDefinition) + @object_dict_field(OutputDefinition) def outputs(self): """ An optional list of output parameters (i.e., as parameter definitions) for the Topology Template. - :type: {:obj:`basestring`: :class:`ParameterDefinition`} + :type: {:obj:`basestring`: :class:`OutputDefinition`} """ @object_field(SubstitutionMappings) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/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 43af44b..060c38c 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 @@ -70,7 +71,7 @@ class ArtifactType(ExtensiblePresentation): """ @field_getter(data_type_class_getter(Version)) - @primitive_field() + @primitive_field(str) def version(self): """ An optional version for the Artifact Type definition. @@ -153,7 +154,8 @@ class DataType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Data Type definition. @@ -210,7 +212,7 @@ class DataType(ExtensiblePresentation): if not isinstance(parent, DataType): return parent else: - return parent._get_primitive_ancestor(context) # pylint: disable=no-member + return parent._get_primitive_ancestor(context) # pylint: disable=no-member return None @cachedmethod @@ -261,7 +263,8 @@ class CapabilityType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Capability Type definition. @@ -312,7 +315,9 @@ class CapabilityType(ExtensiblePresentation): @cachedmethod def _is_descendant(self, context, other_type): - """returns True iff `other_type` is a descendant of the represented capability type""" + """ + Checks if ``other_type`` is our descendant (or equal to us). + """ if other_type is None: return False elif other_type._name == self._name: @@ -324,12 +329,17 @@ class CapabilityType(ExtensiblePresentation): return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties')) @cachedmethod + def _get_attributes(self, context): + return FrozenDict(get_inherited_parameter_definitions(context, self, 'attributes')) + + @cachedmethod def _get_valid_source_types(self, context): return get_inherited_valid_source_types(context, self) def _validate(self, context): super(CapabilityType, self)._validate(context) self._get_properties(context) + self._get_attributes(context) def _dump(self, context): self._dump_content(context, ( @@ -363,7 +373,8 @@ class InterfaceType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Interface Type definition. @@ -417,7 +428,7 @@ class InterfaceType(ExtensiblePresentation): def _validate(self, context): super(InterfaceType, self)._validate(context) self._get_inputs(context) - for operation in self.operations.itervalues(): # pylint: disable=no-member + for operation in self.operations.itervalues(): # pylint: disable=no-member operation._validate(context) def _dump(self, context): @@ -450,7 +461,8 @@ class RelationshipType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Relationship Type definition. @@ -508,6 +520,9 @@ class RelationshipType(ExtensiblePresentation): @cachedmethod def _is_descendant(self, context, the_type): + """ + Checks if ``other_type`` is our descendant (or equal to us). + """ if the_type is None: return False elif the_type._name == self._name: @@ -565,7 +580,8 @@ class NodeType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Node Type definition. @@ -639,6 +655,9 @@ class NodeType(ExtensiblePresentation): @cachedmethod def _is_descendant(self, context, the_type): + """ + Checks if ``other_type`` is our descendant (or equal to us). + """ if the_type is None: return False elif the_type._name == self._name: @@ -721,7 +740,8 @@ class GroupType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Group Type definition. @@ -775,6 +795,9 @@ class GroupType(ExtensiblePresentation): @cachedmethod def _is_descendant(self, context, the_type): + """ + Checks if ``other_type`` is our descendant (or equal to us). + """ if the_type is None: return False elif the_type._name == self._name: @@ -786,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')) @@ -827,7 +855,8 @@ class PolicyType(ExtensiblePresentation): :type: :obj:`basestring` """ - @object_field(Version) + @field_getter(data_type_class_getter(Version)) + @primitive_field(str) def version(self): """ An optional version for the Policy Type definition. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/requirements.in ---------------------------------------------------------------------- diff --git a/requirements.in b/requirements.in index 1d83ec8..caeaaf3 100644 --- a/requirements.in +++ b/requirements.in @@ -14,16 +14,17 @@ # pip-compile --output-file requirements.txt requirements.in (pip-tools package is needed). requests>=2.3.0, <2.14.0 -networkx>=1.9, <1.10 # version 1.10 dropped support of python 2.6 +networkx>=1.9, <1.10 # version 1.10 dropped support for Python 2.6 retrying>=1.3.0, <1.4.0 blinker>1.3, <1.5 jsonpickle>0.9.0, <=0.9.4 -ruamel.yaml>=0.11.12, <0.12.0 # version 0.12.0 dropped support of python 2.6 -Jinja2>=2.8, <2.9 +ruamel.yaml>=0.11.12, <0.12.0 # version 0.12.0 dropped support for Python 2.6 +Jinja2>=2.8, <3.0 shortuuid>=0.5, <0.6 CacheControl[filecache]>=0.11.0, <0.13 -SQLAlchemy>=1.1.0, <1.2 # version 1.2 dropped support of python 2.6 +SQLAlchemy>=1.1.0, <1.2 # version 1.2 dropped support for Python 2.6 wagon==0.6.0 +wheel==0.29.0 # version 0.30.0 dropped support for Python 2.6 bottle>=0.12.0, <0.13 setuptools>=35.0.0, <36.0.0 click>=6.0, < 7.0 @@ -32,8 +33,8 @@ PrettyTable>=0.7,<0.8 click_didyoumean==0.0.3 backports.shutil_get_terminal_size==1.0.0 logutils==0.3.4.1 -psutil>=5.2.2, < 6.0.0 +psutil>=5.2.2, <6.0.0 importlib ; python_version < '2.7' ordereddict ; python_version < '2.7' -total-ordering ; python_version < '2.7' # only one version on pypi +total-ordering ; python_version < '2.7' # only one version on PyPI wheel<=0.29.0 ; python_version < '2.7' http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/requirements.txt ---------------------------------------------------------------------- diff --git a/requirements.txt b/requirements.txt index bcc5296..cbb015a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,19 +2,18 @@ # This file is autogenerated by pip-compile # To update, run: # -# pip-compile --output-file requirements.txt requirements.in +# pip-compile --output-file ./requirements.txt ./requirements.in # -appdirs==1.4.3 # via setuptools backports.shutil_get_terminal_size==1.0.0 blinker==1.4 bottle==0.12.13 -cachecontrol[filecache]==0.12.1 +cachecontrol[filecache]==0.12.3 click==6.7 click_didyoumean==0.0.3 colorama==0.3.9 -decorator==4.0.11 # via networkx +decorator==4.1.2 # via networkx importlib==1.0.4 ; python_version < "2.7" -jinja2==2.8.1 +jinja2==2.9.6 jsonpickle==0.9.4 lockfile==0.12.2 # via cachecontrol logutils==0.3.4.1 @@ -22,20 +21,18 @@ markupsafe==1.0 # via jinja2 msgpack-python==0.4.8 # via cachecontrol networkx==1.9.1 ordereddict==1.1 ; python_version < "2.7" -packaging==16.8 # via setuptools prettytable==0.7.2 -psutil==5.2.2 -pyparsing==2.2.0 # via packaging +psutil==5.4.0 requests==2.13.0 retrying==1.3.3 -ruamel.ordereddict==0.4.9 # via ruamel.yaml +ruamel.ordereddict==0.4.13 # via ruamel.yaml ruamel.yaml==0.11.15 shortuuid==0.5.0 -six==1.10.0 # via packaging, retrying, setuptools -sqlalchemy==1.1.6 +six==1.11.0 # via retrying +sqlalchemy==1.1.14 total-ordering==0.1.0 ; python_version < "2.7" wagon==0.6.0 wheel==0.29.0 ; python_version < "2.7" # The following packages are considered to be unsafe in a requirements file: -setuptools==35.0.2 +# setuptools http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/setup.py ---------------------------------------------------------------------- diff --git a/setup.py b/setup.py index 8e95c19..df557c6 100644 --- a/setup.py +++ b/setup.py @@ -60,17 +60,17 @@ extras_require = { with open(os.path.join(root_dir, 'requirements.in')) as requirements: for requirement in requirements.readlines(): - requirement = requirement.split('#')[0].strip() # get rid of comments or trailing comments + requirement = requirement.split('#', 1)[0].strip() # Remove comments if not requirement: - continue # skip empty and comment lines + continue # Skip empty and comment lines - # dependencies which use environment markers have to go in as conditional dependencies + # Dependencies which use environment markers have to go in as conditional dependencies # under "extra_require" rather than "install_requires", or otherwise the environment # markers get ignored when installing from wheel. See more here: # https://wheel.readthedocs.io/en/latest/index.html#defining-conditional-dependencies # https://hynek.me/articles/conditional-python-dependencies/ if ';' in requirement: - package, condition = requirement.split(';') + package, condition = requirement.split(';', 1) cond_name = ':{0}'.format(condition.strip()) extras_require.setdefault(cond_name, []) extras_require[cond_name].append(package.strip()) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/__init__.py b/tests/extensions/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/__init__.py b/tests/extensions/aria_extension_tosca/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/aria_extension_tosca/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/aria_v1_0/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/aria_v1_0/__init__.py b/tests/extensions/aria_extension_tosca/aria_v1_0/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/aria_extension_tosca/aria_v1_0/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/aria_v1_0/test_profile.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/aria_v1_0/test_profile.py b/tests/extensions/aria_extension_tosca/aria_v1_0/test_profile.py new file mode 100644 index 0000000..14a2e8a --- /dev/null +++ b/tests/extensions/aria_extension_tosca/aria_v1_0/test_profile.py @@ -0,0 +1,22 @@ +# 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. + + +def test_profile(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +imports: + - aria-1.0 +""", import_profile=True, validate_normative=True).assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/conftest.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/conftest.py b/tests/extensions/aria_extension_tosca/conftest.py new file mode 100644 index 0000000..a2020b7 --- /dev/null +++ b/tests/extensions/aria_extension_tosca/conftest.py @@ -0,0 +1,45 @@ +# 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. + +""" +PyTest configuration module. + +Add support for a "--tosca-parser" CLI option. +""" + +import pytest + +from ...mechanisms.parsing.aria import AriaParser + + +def pytest_addoption(parser): + parser.addoption('--tosca-parser', action='store', default='aria', help='TOSCA parser') + + +def pytest_report_header(config): + tosca_parser = config.getoption('--tosca-parser') + return 'tosca-parser: {0}'.format(tosca_parser) + + [email protected](scope='session') +def parser(request): + tosca_parser = request.config.getoption('--tosca-parser') + verbose = request.config.getoption('verbose') > 0 + if tosca_parser == 'aria': + with AriaParser() as p: + p.verbose = verbose + yield p + else: + pytest.fail('configured tosca-parser not supported: {0}'.format(tosca_parser)) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py b/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/test_profile.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/test_profile.py b/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/test_profile.py new file mode 100644 index 0000000..fb756bc --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_nfv_v1_0/test_profile.py @@ -0,0 +1,20 @@ +# 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. + + +def test_profile(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0 +""", import_profile=True, validate_normative=True).assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/__init__.py b/tests/extensions/aria_extension_tosca/simple_v1_0/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/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 new file mode 100644 index 0000000..104e6bb --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py @@ -0,0 +1,82 @@ +# -*- 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. + + +# Keywords + +TYPE_NAME_PLURAL = { + 'artifact': 'artifacts', + 'data': 'datatypes', + 'capability': 'capabilities', + 'interface': 'interfaces', + 'relationship': 'relationships', + 'node': 'nodes', + 'group': 'groups', + 'policy': 'policies' +} +TEMPLATE_NAME_SECTIONS = { + 'node': 'node_templates', + 'group': 'groups', + 'relationship': 'relationship_templates', + 'policy': 'policies' +} +PRIMITIVE_TYPE_NAMES = ('string', 'integer', 'float', 'boolean') +PARAMETER_TYPE_NAMES = PRIMITIVE_TYPE_NAMES + ('MyType',) +CONSTRAINTS_WITH_VALUE = ('equal', 'greater_than', 'greater_or_equal', 'less_than', 'less_or_equal') +CONSTRAINTS_WITH_VALUE_LIST = ('valid_values',) +CONSTRAINTS_WITH_VALUE_RANGE = ('in_range',) +CONSTRAINTS_WITH_VALUE_NON_NEGATIVE_INT = ('length', 'min_length', 'max_length') + + +# Values + +PRIMITIVE_VALUES = ('null', 'true', 'a string', '123', '0.123', '[]', '{}') +NOT_A_DICT = ('null', 'true', 'a string', '123', '0.123', '[]') +NOT_A_DICT_WITH_ONE_KEY = NOT_A_DICT + ('{}', '{k1: v1, k2: v2}',) +NOT_A_DICT_OR_STRING = ('null', 'true', '123', '0.123', '[]') +NOT_A_LIST = ('null', 'true', 'a string', '123', '0.123', '{}') +NOT_A_LIST_OF_TWO = NOT_A_LIST + ('[]', '[a]', '[a, b, c]') +NOT_A_STRING = ('null', 'true', '123', '0.123', '[]', '{}') +NOT_A_BOOL = ('null', 'a string', '123', '0.123', '[]', '{}') +NOT_A_RANGE = NOT_A_LIST + ( + '[]', '[ 1 ]', '[ 1, 2, 3 ]', + '[ 1, 1 ]', '[ 2, 1 ]', + '[ 1, a string ]', '[ a string, 1 ]', + '[ 1.5, 2 ]', '[ 1, 2.5 ]' +) +OCCURRENCES = ('[ 0, 1 ]', '[ 10, UNBOUNDED ]') +BAD_OCCURRENCES = NOT_A_RANGE + ('[ -1, 1 ]', '[ 0, unbounded ]') +GOOD_VERSIONS = ("'6.1'", '2.0.1', '3.1.0.beta', "'1.0.0.alpha-10'") +BAD_VERSIONS = ('a_string', '1.2.3.4.5', '1.2.beta', '1.0.0.alpha-x') +STATUSES = ('supported', 'unsupported', 'experimental', 'deprecated') +PARAMETER_VALUES = ( + ('string', 'a string'), + ('integer', '1'), + ('float', '1.1'), + ('MyType', '{my_field: a string}') +) +ENTRY_SCHEMA_VALUES = ( + ('string', 'a string', 'another string'), + ('integer', '1', '2'), + ('float', '1.1', '2.2'), + ('MyType', '{my_field: a string}', '{}') +) +ENTRY_SCHEMA_VALUES_BAD = ( + ('string', 'a string', '1'), + ('integer', '1', 'a string'), + ('float', '1.1', 'a string'), + ('MyType', '{my_field: a string}', 'a string') +) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/__init__.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/__init__.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/__init__.py new file mode 100644 index 0000000..ae1e83e --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/__init__.py @@ -0,0 +1,14 @@ +# 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. http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_concat.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_concat.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_concat.py new file mode 100644 index 0000000..23a274a --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_concat.py @@ -0,0 +1,102 @@ + # -*- 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. + + +def test_functions_concat_syntax_empty(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { concat: [] } +""").assert_success() + + +def test_functions_concat_strings(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { concat: [ a, b, c ] } +""").assert_success() + + +def test_functions_concat_mixed(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { concat: [ a, 1, 1.1, null, [], {} ] } +""").assert_success() + + +def test_functions_concat_nested(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { concat: [ a, { concat: [ b, c ] } ] } +""").assert_success() + + +# Unicode + +def test_functions_concat_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + é¡å: + properties: + 忏: + type: string +topology_template: + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { concat: [ ä¸, äº, ä¸ ] } +""").assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_artifact.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_artifact.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_artifact.py new file mode 100644 index 0000000..11be88a --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_artifact.py @@ -0,0 +1,156 @@ +# -*- 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 + + +# Syntax + +def test_functions_get_artifact_syntax_empty(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_artifact: [] } # needs at least two args +""").assert_failure() + + +# Arguments + +def test_functions_get_artifact_2_arguments(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +artifact_types: + MyType: {} +node_types: + MyType: + properties: + my_parameter: + type: string + artifacts: + my_artifact: + type: MyType + file: filename +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_artifact: [ my_node, my_artifact ] } +""").assert_success() + + [email protected](reason='not implemented') +def test_functions_get_artifact_unknown(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +artifact_types: + MyType: {} +node_types: + MyType: + properties: + my_parameter: + type: string + artifacts: + my_artifact: + type: MyType + file: filename +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_artifact: [ unknown, my_artifact ] } +""").assert_failure() + + +def test_functions_get_artifact_3_arguments(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +artifact_types: + MyType: {} +node_types: + MyType: + properties: + my_parameter: + type: string + artifacts: + my_artifact: + type: MyType + file: filename +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_artifact: [ my_node, my_artifact, path ] } +""").assert_success() + + +def test_functions_get_artifact_4_arguments(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +artifact_types: + MyType: {} +node_types: + MyType: + properties: + my_parameter: + type: string + artifacts: + my_artifact: + type: MyType + file: filename +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_artifact: [ my_node, my_artifact, path, true ] } +""").assert_success() + + +# Unicode + +def test_functions_get_artifact_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +artifact_types: + é¡å: {} +node_types: + é¡å: + properties: + 忏: + type: string + artifacts: + ç¥å¨: + type: é¡å + file: æä»¶å +topology_template: + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { get_artifact: [ 模æ¿, ç¥å¨, è·¯å¾, true ] } +""").assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_input.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_input.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_input.py new file mode 100644 index 0000000..a4c97a4 --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_input.py @@ -0,0 +1,94 @@ +# -*- 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. + + +def test_functions_get_input_unknown(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_input: unknown } +""").assert_failure() + + +def test_functions_get_input(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + inputs: + my_input: + type: string + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_input: my_input } +""").assert_success() + + +def test_functions_get_input_nested(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + inputs: + my_input: + type: string + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_input: { concat: [ my, _, input ] } } +""").assert_success() + + +# Unicode + +def test_functions_get_input_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + é¡å: + properties: + 忏: + type: string +topology_template: + inputs: + è¾å ¥: + type: string + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { get_input: è¾å ¥ } +""").assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_nodes_of_type.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_nodes_of_type.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_nodes_of_type.py new file mode 100644 index 0000000..ffa2f9c --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_nodes_of_type.py @@ -0,0 +1,70 @@ +# -*- 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. + + +def test_functions_get_nodes_of_type_unknown(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_nodes_of_type: unknown } +""", import_profile=True).assert_failure() + + +def test_functions_get_nodes_of_type(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: list + entry_schema: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_nodes_of_type: MyType } +""", import_profile=True).assert_success() + + +# Unicode + +def test_functions_get_nodes_of_type_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + é¡å: + properties: + 忏: + type: list + entry_schema: string +topology_template: + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { get_nodes_of_type: é¡å } +""", import_profile=True).assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_operation_output.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_operation_output.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_operation_output.py new file mode 100644 index 0000000..c115d0d --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_get_operation_output.py @@ -0,0 +1,84 @@ +# -*- 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. + + +# Syntax + +def test_functions_get_operation_output_syntax_empty(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_operation_output: [] } # needs at least two args +""").assert_failure() + + +# Arguments + +def test_functions_get_operation_output(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +interface_types: + MyType: + my_operation: {} +node_types: + MyType: + properties: + my_parameter: + type: string + interfaces: + MyInterface: + type: MyType +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { get_operation_output: [ my_node, MyInterface, my_operation, my_variable ] } +""").assert_success() + + +# Unicode + +def test_functions_get_operation_output_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +interface_types: + é¡å: + æè¡: {} +node_types: + é¡å: + properties: + 忏: + type: string + interfaces: + æ¥å£: + type: é¡å +topology_template: + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { get_operation_output: [ 模æ¿, æ¥å£, æè¡, è®é ] } +""").assert_success() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f4f09852/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_token.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_token.py b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_token.py new file mode 100644 index 0000000..8f99824 --- /dev/null +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/functions/test_function_token.py @@ -0,0 +1,119 @@ +# -*- 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. + + +def test_functions_token_syntax_empty(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { token: [] } # needs exactly three args +""").assert_failure() + + +def test_functions_token_syntax_index_type(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { token: [ hello world, ' ', c ] } +""").assert_failure() + + +def test_functions_token_syntax_index_negative(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { token: [ hello world, ' ', -1 ] } +""").assert_failure() + + +def test_functions_token(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { token: [ hello world, ' ', 1 ] } +""").assert_success() + + +def test_functions_token_nested(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + MyType: + properties: + my_parameter: + type: string +topology_template: + node_templates: + my_node: + type: MyType + properties: + my_parameter: { token: [ { token: [ hello/goodbye world, ' ', 0 ] }, '/', 1 ] } +""").assert_success() + + +# Unicode + +def test_functions_token_unicode(parser): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +node_types: + é¡å: + properties: + 忏: + type: string +topology_template: + node_templates: + 模æ¿: + type: é¡å + properties: + 忏: { token: [ 'ä½ å¥½ï¼ä¸ç', 'ï¼', 1 ] } +""").assert_success()
