djay87 closed pull request #228: ARIA-438 : Support for storing the common TOSCA YAML files in the resource storage URL: https://github.com/apache/incubator-ariatosca/pull/228
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/aria/__init__.py b/aria/__init__.py index 980a2bb1..68778312 100644 --- a/aria/__init__.py +++ b/aria/__init__.py @@ -84,6 +84,7 @@ def application_resource_storage(api, api_kwargs=None, initiator=None, initiator return storage.ResourceStorage(api_cls=api, api_kwargs=api_kwargs, - items=['service_template', 'service', 'plugin'], + items=['type_definition', 'service_template', 'service',\ + 'plugin'], initiator=initiator, initiator_kwargs=initiator_kwargs) diff --git a/aria/cli/commands/__init__.py b/aria/cli/commands/__init__.py index ba34a43a..5cdfbac3 100644 --- a/aria/cli/commands/__init__.py +++ b/aria/cli/commands/__init__.py @@ -18,6 +18,7 @@ """ from . import ( + type_definitions, executions, logs, node_templates, diff --git a/aria/cli/commands/type_definitions.py b/aria/cli/commands/type_definitions.py new file mode 100644 index 00000000..fc389e9f --- /dev/null +++ b/aria/cli/commands/type_definitions.py @@ -0,0 +1,136 @@ +# 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. + +""" +CLI ``type-definitions`` sub-commands. +""" +from aria import exceptions +from ..core import aria +from .. import service_template_utils +from .. import table + +TYPE_DEFINITION_COLUMNS = \ + ('id', 'name', 'version', 'main_file_name', 'uploaded_at') + + +@aria.group(name='type-definitions') +@aria.options.verbose() +def type_definitions(): + """ + Manage type definitions + """ + pass + +@type_definitions.command(name='load', + short_help='Parse and load a type definition archive') +@aria.argument('type-definition-path') +@aria.options.verbose() +@aria.pass_type_definition_manager +@aria.pass_logger +def load(type_definition_path, type_definition_manager, logger): + """ + Parse and store a type definition archive + + TYPE_DEFINITION_PATH is the path to the type definition archive. + + """ + logger.info('Loading type definition {0}...'.format(type_definition_path)) + valid_extension = ('.yaml', '.csar') + if not type_definition_path.endswith(valid_extension): + raise exceptions.\ + TypeDefinitionException('Type definition file has invalid extension') + + type_definition_file_path = service_template_utils.get(type_definition_path, None) + type_definition = type_definition_manager.load_type_definition(type_definition_file_path) + logger.info("Type definition loaded. The type definition's name is {0} and version is {1}".\ + format(type_definition.name, type_definition.version)) + +@type_definitions.command(name='list', + short_help='List all stored type definitions') +@aria.options.sort_by('uploaded_at') +@aria.options.descending +@aria.options.verbose() +@aria.pass_type_definition_manager +@aria.pass_logger +def list(sort_by, descending, type_definition_manager, logger): + """ + List all stored type definitions + """ + + logger.info('Listing all type definitions...') + type_definitions_list = type_definition_manager.list_type_definition(sort_by, descending) + table.print_data(TYPE_DEFINITION_COLUMNS, type_definitions_list, 'Type definitions:') + +@type_definitions.command(name='show', + short_help='Show information for a stored type definition') +@aria.argument('type-definition-name') +@aria.argument('type-definition-version') +@aria.options.verbose() +@aria.pass_type_definition_manager +@aria.pass_logger +def show(type_definition_name, type_definition_version, type_definition_manager, logger): + """ + Show information for a stored type definition + + TYPE_DEFINITION_NAME is name of the stored type definition + TYPE_DEFINITION_VERSION is version of the stored type definition + """ + logger.info("Showing type definition name '{0}' version '{1}'...".\ + format(type_definition_name, type_definition_version)) + type_definition = type_definition_manager.get_type_definition(type_definition_name,\ + type_definition_version) + table.print_data(TYPE_DEFINITION_COLUMNS, type_definition, 'Type definition:') + +@type_definitions.command(name='delete', + short_help='Delete a stored type definition') +@aria.argument('type-definition-name') +@aria.argument('type-definition-version') +@aria.options.verbose() +@aria.pass_type_definition_manager +@aria.pass_logger +def delete(type_definition_name, type_definition_version, type_definition_manager, logger): + """ + Delete a stored type definition + + TYPE_DEFINITION_NAME is name of the stored type definition + TYPE_DEFINITION_VERSION is version of the stored type definition + """ + logger.info("Deleting type definition name '{0}' version '{1}'...".\ + format(type_definition_name, type_definition_version)) + type_definition_manager.delete_type_definition(type_definition_name, type_definition_version) + logger.info("Type definition name '{0}' version '{1}' deleted".\ + format(type_definition_name, type_definition_version)) + +@type_definitions.command(name='validate', + short_help='Validate a type definition archive') +@aria.argument('type-definition-path') +@aria.options.verbose() +@aria.pass_type_definition_manager +@aria.pass_logger +def validate(type_definition_path, type_definition_manager, logger): + """ + Validate a type definition archive + + TYPE_DEFINITION_PATH is the path to the type definition archive. + """ + logger.info('Validating type definition: {0}'.format(type_definition_path)) + valid_extension = ('.yaml', '.csar') + if not type_definition_path.endswith(valid_extension): + raise exceptions.\ + TypeDefinitionException('Type definition file has invalid extension') + + type_definition_file_path = service_template_utils.get(type_definition_path, None) + type_definition_manager.validate_type_definition(type_definition_file_path) + logger.info('Type definition validated successfully') diff --git a/aria/cli/core/aria.py b/aria/cli/core/aria.py index b84507c7..b16f68eb 100644 --- a/aria/cli/core/aria.py +++ b/aria/cli/core/aria.py @@ -176,6 +176,17 @@ def wrapper(*args, **kwargs): return wrapper +def pass_type_definition_manager(func): + """ + Simply passes the type definition manager to a command. + """ + # Wraps here makes sure the original docstring propagates to click + @wraps(func) + def wrapper(*args, **kwargs): + return func(type_definition_manager=env.type_definition_manager, *args, **kwargs) + + return wrapper + def pass_model_storage(func): """ diff --git a/aria/cli/env.py b/aria/cli/env.py index 84bdebed..a99d9a6c 100644 --- a/aria/cli/env.py +++ b/aria/cli/env.py @@ -19,7 +19,7 @@ import os import shutil - +from aria.type_definition_manager import TypeDefinitionManager from .config import config from .logger import Logging from .. import (application_model_storage, application_resource_storage) @@ -44,11 +44,13 @@ def __init__(self, workdir): self._model_storage_dir = os.path.join(workdir, 'models') self._resource_storage_dir = os.path.join(workdir, 'resources') self._plugins_dir = os.path.join(workdir, 'plugins') + self._type_definitions_dir = os.path.join(workdir, 'type_definitions') # initialized lazily self._model_storage = None self._resource_storage = None self._plugin_manager = None + self._type_definition_manager = None @property def workdir(self): @@ -80,6 +82,12 @@ def plugin_manager(self): self._plugin_manager = self._init_plugin_manager() return self._plugin_manager + @property + def type_definition_manager(self): + if not self._type_definition_manager: + self._type_definition_manager = self._init_type_definition_manager() + return self._type_definition_manager + def reset(self, reset_config): if reset_config: shutil.rmtree(self._workdir) @@ -120,6 +128,11 @@ def _init_plugin_manager(self): return PluginManager(self.model_storage, self._plugins_dir) + def _init_type_definition_manager(self): + if not os.path.exists(self._type_definitions_dir): + os.makedirs(self._type_definitions_dir) + + return TypeDefinitionManager(self.model_storage, self._type_definitions_dir) env = _Environment(os.path.join( os.environ.get('ARIA_WORKDIR', os.path.expanduser('~')), ARIA_DEFAULT_WORKDIR_NAME)) diff --git a/aria/cli/main.py b/aria/cli/main.py index 640360b2..a0e6b64b 100644 --- a/aria/cli/main.py +++ b/aria/cli/main.py @@ -44,6 +44,7 @@ def _register_commands(): Register the CLI's commands. """ + _aria.add_command(commands.type_definitions.type_definitions) _aria.add_command(commands.service_templates.service_templates) _aria.add_command(commands.node_templates.node_templates) _aria.add_command(commands.services.services) diff --git a/aria/exceptions.py b/aria/exceptions.py index 5d3e21d2..9d5b5f31 100644 --- a/aria/exceptions.py +++ b/aria/exceptions.py @@ -71,3 +71,27 @@ class ParsingError(AriaError): class InstantiationError(AriaError): pass + + +class TypeDefinitionException(AriaError): + """The base exception class of the type definition""" + pass + + +class TypeDefinitionNotFoundException(TypeDefinitionException): + """The exception class of the type definition thrown + if type definition does not exists""" + pass + + +class TypeDefinitionAlreadyExistsException(TypeDefinitionException): + """The exception class of the type definition thrown + if type definition already exists""" + pass + + +class InvalidTypeDefinitionException(TypeDefinitionException): + """The exception class of the type definition thrown + if type definition is not a valid archive or validation error + exists during the type definition load""" + pass diff --git a/aria/modeling/models.py b/aria/modeling/models.py index cf84fdb9..009717f5 100644 --- a/aria/modeling/models.py +++ b/aria/modeling/models.py @@ -16,6 +16,14 @@ """ Data models. +Type definition models +----------------------- + +.. autosummary:: + :nosignatures: + + aria.modeling.models.TypeDefinition + Service template models ----------------------- @@ -90,6 +98,7 @@ ) from . import ( + type_definition, service_template, service_instance, service_changes, @@ -107,6 +116,9 @@ __all__ = ( 'models_to_register', + # Type definition models + 'TypeDefinition', + # Service template models 'ServiceTemplate', 'NodeTemplate', @@ -157,6 +169,11 @@ 'Argument' ) +# region type definition models + +@utils.fix_doc +class TypeDefinition(aria_declarative_base, type_definition.TypeDefinitionBase): + pass # region service template models @@ -376,6 +393,9 @@ class Argument(aria_declarative_base, orchestration.ArgumentBase): # See also __all__ at the top of this file models_to_register = ( + # Type definition models + TypeDefinition, + # Service template models ServiceTemplate, NodeTemplate, diff --git a/aria/modeling/type_definition.py b/aria/modeling/type_definition.py new file mode 100644 index 00000000..a8cbccfa --- /dev/null +++ b/aria/modeling/type_definition.py @@ -0,0 +1,65 @@ +# 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. + +""" +ARIA modeling type definition module +""" + +# pylint: disable=too-many-lines, no-self-argument, no-member, abstract-method + +from sqlalchemy import ( + Column, + Text, + DateTime, + UniqueConstraint +) +from . import mixins + +class TypeDefinitionBase(mixins.ModelMixin): + """ + Loaded TypeDefinition. + + Usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can also be + created programmatically. + """ + + __tablename__ = 'type_definition' + + name = Column(Text, nullable=False, index=True, doc=""" + Name of the type definition + + :type: :obj:`basestring` + """) + + version = Column(Text, nullable=False, doc=""" + Version for the type definition + + :type: :obj:`basestring` + """) + + main_file_name = Column(Text, nullable=False, doc=""" + Filename of CSAR or YAML file from which this type definition was parsed. + + :type: :obj:`basestring` + """) + + uploaded_at = Column(DateTime, nullable=False, doc=""" + Timestamp for when the type definition was loaded. + + :type: :class:`~datetime.datetime` + """) + + __table_args__ = (UniqueConstraint('name', 'version', + name='_type_definition_name_version_unique'),) diff --git a/aria/orchestrator/topology/instance_handler.py b/aria/orchestrator/topology/instance_handler.py index fad00b9c..a1d61fd8 100644 --- a/aria/orchestrator/topology/instance_handler.py +++ b/aria/orchestrator/topology/instance_handler.py @@ -294,8 +294,9 @@ def _find_target(self, requirement_template): return target_node_template, target_node_capability - # Find the first node which has a capability of the required type - elif requirement_template.target_capability_type is not None: + # Find the first node which has a capability of the required type or name + elif requirement_template.target_capability_type is not None or \ + requirement_template.target_capability_name is not None: for target_node_template in \ self._model.node_template.service_template.node_templates.itervalues(): target_node_capability = \ @@ -323,6 +324,10 @@ def _satisfies_requirement( capability_template.type.name) is None): return False + if requirement_template.target_capability_name is not None: + if not requirement_template.target_capability_name == capability_template.name: + return False + # Are we in valid_source_node_types? if capability_template.valid_source_node_types: for valid_source_node_type in capability_template.valid_source_node_types: diff --git a/aria/type_definition_manager.py b/aria/type_definition_manager.py new file mode 100644 index 00000000..c473725b --- /dev/null +++ b/aria/type_definition_manager.py @@ -0,0 +1,225 @@ +# 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. + +""" +Type Definition management. +""" +from datetime import datetime +import os +from distutils import dir_util # pylint: disable=no-name-in-module +from aria.utils.yaml import yaml +from aria.utils import collections +from aria.exceptions import ( + ParsingError, + TypeDefinitionException, + TypeDefinitionAlreadyExistsException, + TypeDefinitionNotFoundException, + InvalidTypeDefinitionException + ) +from aria.parser import consumption +from aria.parser.loading.location import UriLocation + +class TypeDefinitionManager(object): + """TypeDefinitionManager class handles the type definition related management""" + + def __init__(self, model_storage, type_definitions_dir): + """ + :param model_storage: model storage object + :param type_definitions_dir: root directory in which to load type definitions + """ + self._model_storage = model_storage + self._type_definitions_dir = type_definitions_dir + + @property + def model_storage(self): + """Return model storage object""" + return self._model_storage + + def load_type_definition(self, type_definition_path): + """ + Load a type definition into model as well as into file system. + """ + type_definition = self.create_type_definition(type_definition_path) + + return type_definition + + def get_type_definition(self, type_definition_name, type_definition_version): + """ + Get type definition details based on name and version + """ + type_definition_query = self._model_storage.type_definition.\ + _get_query(None, {'name': type_definition_name, 'version': type_definition_version},\ + None) + type_definition_id = type_definition_query.value('id') + type_definition = self._model_storage.type_definition.get(type_definition_id) + return type_definition + + def delete_type_definition(self, type_definition_name, type_definition_version): + """ + Delete a type definition from model as well as from file system + """ + try: + type_definition_query = self._model_storage.type_definition.\ + _get_query(None, {'name': type_definition_name, 'version': type_definition_version}, + None) + type_definition_id = type_definition_query.value('id') + + if type_definition_id is None: + raise TypeDefinitionNotFoundException("Type definition name '{0}' version '{1}' " + "does not exist.".\ + format(type_definition_name,\ + type_definition_version)) + else: + type_definition = self._model_storage.type_definition.get(type_definition_id) + type_def_dir = self.get_type_definition_dir(type_definition) + + if os.path.exists(type_def_dir) and os.path.isdir(type_def_dir): + dir_util.remove_tree(type_def_dir) + + self._model_storage.type_definition.delete(type_definition) + except Exception, e: + raise e + + def list_type_definition(self, sort_by, descending): + """Lists the type definitions that are loaded""" + type_definitions_list = self._model_storage.type_definition.list( + sort={sort_by: 'desc' if descending else 'asc'}) + return type_definitions_list + + def get_type_definition_dir(self, type_definition_object): + """ + Get the particular type definition's file system directory. + """ + return os.path.join(self._type_definitions_dir, + '{0}-{1}'.format(type_definition_object.name, + type_definition_object.version)) + + def create_type_definition(self, type_definition_path): + + """validates & stores the type definition file/csar into model & resource storage""" + + context = self.validate_type_definition(type_definition_path) + service_template = context.modeling.template + + metadata = service_template.meta_data + template_name = metadata['template_name'].value + template_version = metadata['template_version'].value.value + main_file_name = service_template.main_file_name + + cls = self._model_storage.type_definition.model_cls + type_definition = cls( + name=template_name, + version=template_version, + main_file_name=main_file_name, + uploaded_at=datetime.now() + ) + number_of_rows_matched = len(self._model_storage.type_definition.list \ + (filters={'name': type_definition.name, + 'version': type_definition.version})) + if number_of_rows_matched: + raise TypeDefinitionAlreadyExistsException( + "Type Definition '{0}' with version '{1}' already exists".format( + type_definition.name, type_definition.version)) + + type_definition_directory = self.get_type_definition_dir(type_definition) + if os.path.exists(type_definition_directory): + raise TypeDefinitionAlreadyExistsException( + ("Type Definition '{0}' with version '{1}' already exists"). + format(type_definition.name, type_definition.version)) + + try: + os.mkdir(type_definition_directory) + type_def_src_dir = os.path.dirname(type_definition_path) + dir_util.copy_tree(type_def_src_dir, type_definition_directory) + except (IOError, OSError): + raise \ + TypeDefinitionException("Could not store type definition into directory") + + self._model_storage.type_definition.put(type_definition) + + return type_definition + + def validate_type_definition(self, type_definition_path): + """ Validates the provided type definition archive""" + try: + with open(type_definition_path, 'r') as type_definition_yaml_file: + type_definition_yaml = yaml.load(type_definition_yaml_file) + except (IOError, OSError) as e: + raise \ + TypeDefinitionException("Could not open/load type definition file", e) + + if ('metadata' not in type_definition_yaml) or \ + ('template_name' not in type_definition_yaml['metadata']) or \ + ('template_version' not in type_definition_yaml['metadata']): + raise InvalidTypeDefinitionException('Type definition is invalid. ' + 'It should have metadata information') + + name = type_definition_yaml['metadata']['template_name'] + version = type_definition_yaml['metadata']['template_version'] + try: + TypeDefinitionManager._check_topology_template_exists(type_definition_path, \ + type_definition_yaml, \ + name, version) + except InvalidTypeDefinitionException as e: + raise e + except TypeDefinitionException as e: + raise e + except Exception as e: + raise e + + type_definitions_dir = (self._type_definitions_dir).split() + context = consumption.ConsumptionContext() + context.presentation.location = UriLocation(type_definition_path) + context.loading.prefixes = collections.StrictList(type_definitions_dir) + consumption.ConsumerChain( + context, + ( + consumption.Read, + consumption.Validate, + consumption.ServiceTemplate + )).consume() + if context.validation.dump_issues(): + raise ParsingError('Failed to parse type definition') + return context + + @staticmethod + def _check_topology_template_exists(td_path, td_yaml, main_td_name, main_td_version): + + if 'topology_template' in td_yaml: + td_file_name = os.path.split(td_path)[1] + error_message = ("Type definition '{0}' with version '{1}' is invalid." + " It contains topology template in '{2}'.").\ + format(main_td_name, main_td_version, td_file_name) + raise InvalidTypeDefinitionException(error_message) + + if 'imports' not in td_yaml: + return + + main_type_definition_dir = os.path.dirname(td_path) + for td_import_file in td_yaml['imports']: + try: + td_import_file_path = os.path.join(main_type_definition_dir, td_import_file or ' ') + with open(td_import_file_path, 'r') as td_yaml_file: + td_import_yaml = yaml.load(td_yaml_file) + TypeDefinitionManager.\ + _check_topology_template_exists(td_import_file_path, td_import_yaml,\ + main_td_name, main_td_version) + except (IOError, OSError) as e: + raise TypeDefinitionException("Could not open/load type definition file",\ + e.message) + except InvalidTypeDefinitionException as e: + raise e + except Exception as e: + raise TypeDefinitionException("Failed to parse type definition") diff --git a/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/extensions/aria_extension_tosca/simple_v1_0/assignments.py index 62484839..c47a5e9d 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/assignments.py +++ b/extensions/aria_extension_tosca/simple_v1_0/assignments.py @@ -324,9 +324,19 @@ def _get_capability(self, context): capabilities = node._get_capabilities(context) if capability in capabilities: return capabilities[capability], 'capability_assignment' - capability_type = get_type_by_name(context, capability, 'capability_types') - if capability_type is not None: - return capability_type, 'capability_type' + capability_type = get_type_by_name(context, capability, 'capability_types') + if capability_type is not None: + return capability_type, 'capability_type' + else: + capability_type = get_type_by_name(context, capability, 'capability_types') + if capability_type is not None: + return capability_type, 'capability_type' + + for the_node_template in context.presentation.presenter.service_template.\ + topology_template.node_templates.iteritems(): + the_capabilities = the_node_template[1]._get_capabilities(context) + if capability in the_capabilities: + return the_capabilities[capability], 'capability_assignment' return None, None 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 2ff51438..c79a695a 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 @@ -347,22 +347,108 @@ def node_template_or_type_validator(field, presentation, context): value = getattr(presentation, field.name) if value is not None: - node_templates = \ - context.presentation.get('service_template', 'topology_template', 'node_templates') \ - or {} - if (value not in node_templates) and \ - (get_type_by_name(context, value, 'node_types') is None): - report_issue_for_unknown_type(context, presentation, 'node template or node type', - field.name) + node, node_variant = presentation._get_node(context) + if node_variant == 'node_template': + node_template_validator(field, presentation, context, value, node) + elif node_variant == 'node_type': + node_type_validator(field, presentation, context, value, node) + else: + context.validation.report( + '"%s" refers to a node type or node template that does not match the capability ' + 'requirement in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + +def node_template_validator(field, presentation, context, node_value, node_obj): + """ + Makes sure that the field refers to a node template. + """ + the_node_templates = context.presentation.get('service_template', 'topology_template',\ + 'node_templates') or {} + the_parent_capability_type_name = _get_requirement_in_type(context, presentation).\ + capability + the_parent_node_type_name = _get_requirement_in_type(context, presentation).node + the_nodetype_obj = node_obj._get_type(context) + + if node_value not in the_node_templates: + context.validation.report( + '"%s" refers to an unknown node template in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + return + if the_parent_node_type_name: + if not _is_parent(context, the_nodetype_obj, the_parent_node_type_name, 'node_types'): + context.validation.report( + '"%s" refers to an unknown/inappropriate node type in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name),\ + level=Issue.BETWEEN_FIELDS) + return + + if the_nodetype_obj._get_capabilities(context): + the_capabilities = the_nodetype_obj._get_capabilities(context) + for the_capability in the_capabilities.iteritems(): + if _is_parent(context, the_capability[1]._get_type(context),\ + the_parent_capability_type_name, 'capability_types'): + return + context.validation.report( + '"%s" refers to a node template that does not match the capability requirement in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + return + +def node_type_validator(field, presentation, context, node_value, node_obj): + """ + Makes sure that the field refers to a node type. + """ + the_child_nodetypes = [] + the_parent_capability_type_name = _get_requirement_in_type(context, presentation).\ + capability + the_parent_node_type_name = _get_requirement_in_type(context, presentation).node + + node_type = get_type_by_name(context, node_value, 'node_types') + if node_type is None: + context.validation.report( + '"%s" refers to an unknown node type in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name),\ + level=Issue.BETWEEN_FIELDS) + return + + if the_parent_node_type_name: + if not _is_parent(context, node_obj, the_parent_node_type_name, 'node_types'): + context.validation.report( + '"%s" refers to an unknown/inappropriate node type in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name),\ + level=Issue.BETWEEN_FIELDS) + return + + for the_node_type in context.presentation.presenter.service_template.node_types.\ + iteritems(): + if the_node_type[1]._get_capabilities(context): + the_capabilities = the_node_type[1]._get_capabilities(context) + for the_capability in the_capabilities.iteritems(): + if _is_parent(context, the_capability[1]._get_type(context),\ + the_parent_capability_type_name, 'capability_types'): + the_child_nodetypes.append(the_node_type) + + for the_child_node_type in the_child_nodetypes: + if _is_parent(context, the_child_node_type[1], node_obj._name, 'node_types'): + return + + context.validation.report( + '"%s" refers to a node type that does not match the capability requirement in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + return def capability_definition_or_type_validator(field, presentation, context): """ Makes sure refers to either a capability assignment name in the node template referred to by the ``node`` field or a general capability type. - If the value refers to a capability type, make sure the ``node`` field was not assigned. - Used with the :func:`field_validator` decorator for the ``capability`` field in :class:`RequirementAssignment`. """ @@ -372,31 +458,140 @@ def capability_definition_or_type_validator(field, presentation, context): value = getattr(presentation, field.name) if value is not None: node, node_variant = presentation._get_node(context) - if node_variant == 'node_template': - capabilities = node._get_capabilities(context) - if value in capabilities: - return + capability_variant = presentation._get_capability(context)[1] - if get_type_by_name(context, value, 'capability_types') is not None: - if node is not None: - context.validation.report( - 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( - 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) + if capability_variant == 'capability_assignment': + capability_definition_validator(field, presentation, context, value, node, node_variant) + elif capability_variant == 'capability_type': + capability_type_validator(field, presentation, context, value, node, node_variant) else: context.validation.report( - u'requirement "{0}" refers to an unknown capability type in "{1}": {2}' - .format(presentation._name, presentation._container._fullname, safe_repr(value)), + 'requirement "%s" refers to an unknown capability definition name or '\ + 'type in "%s": %s' + % (presentation._name, presentation._container._fullname, safe_repr(value)), locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES) +def capability_definition_validator(field, presentation, context, capability_value, node_obj, + node_variant): + """ + Makes sure if the capability name in the node template refers to a general capability definition + """ + the_parent_capability_type_name = _get_requirement_in_type(context, presentation).\ + capability + the_parent_node_type_name = _get_requirement_in_type(context, presentation).node + + if node_obj: + _is_capability_in_node(context, node_variant, node_obj, presentation, field, + capability_value) + + if the_parent_node_type_name: + the_nodetype_obj = get_type_by_name(context, the_parent_node_type_name,\ + 'node_types') + _is_capability_in_node(context, 'node_type', the_nodetype_obj, presentation,\ + field, capability_value) + + for the_node_type in context.presentation.presenter.service_template.node_types.\ + iteritems(): + if the_node_type[1]._get_capabilities(context): + the_capabilities = the_node_type[1]._get_capabilities(context) + for the_capability in the_capabilities.iteritems(): + if the_capability[1]._name == capability_value: + the_capability_type_name = the_capability[1].type + + the_capability_type_obj = get_type_by_name(context, the_capability_type_name,\ + 'capability_types') + if _is_parent(context, the_capability_type_obj, the_parent_capability_type_name, + 'capability_types'): + return + +def capability_type_validator(field, presentation, context, capability_value, node_obj, + node_variant): + """ + Makes sure if the capability type in the node template refers to a general capability type + """ + the_parent_capability_type_name = _get_requirement_in_type(context, presentation).\ + capability + the_parent_node_type_name = _get_requirement_in_type(context, presentation).node + the_capability_type_obj = get_type_by_name(context, capability_value, 'capability_types') + + if node_obj: + _is_capability_in_node(context, node_variant, node_obj, presentation, field, + capability_value) + + if the_parent_node_type_name: + the_nodetype_obj = get_type_by_name(context, the_parent_node_type_name,\ + 'node_types') + _is_capability_in_node(context, 'node_type', the_nodetype_obj, presentation,\ + field, capability_value) + + if the_capability_type_obj is not None and \ + _is_parent(context, the_capability_type_obj, the_parent_capability_type_name, + 'capability_types'): + + return + +def _get_requirement_in_type(context, presentation): + the_nodetype_obj = presentation._container._get_type(context) + the_requirements_obj = the_nodetype_obj._get_requirements(context) + the_requirement_obj = None + for the_requirement in the_requirements_obj: + if the_requirement[0] == presentation._name: + the_requirement_obj = the_requirement[1] + return the_requirement_obj + +def _is_capability_in_node(context, node_variant, node, presentation, field, value): + if node_variant == 'node_template': + the_nodetype_obj = node._get_type(context) + if the_nodetype_obj._get_capabilities(context): + the_capabilities = the_nodetype_obj._get_capabilities(context) + for the_capability in the_capabilities.iteritems(): + if the_capability[1]._name == value or \ + _is_parent(context, the_capability[1]._get_type(context), value, + 'capability_types'): + return + + context.validation.report( + '"%s" refers to a node template that does not match the capability requirement '\ + 'in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + return + + + if node_variant == 'node_type': + the_child_nodetypes = [] + if get_type_by_name(context, node._name, 'node_types') is None: + context.validation.report( + '"%s" refers to an unknown/inappropriate node type in "%s"' + % (presentation._name, presentation._container._fullname), + locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_FIELDS) + return + + for the_node_type in context.presentation.presenter.service_template.node_types.iteritems(): + if the_node_type[1]._get_capabilities(context): + the_capabilities = the_node_type[1]._get_capabilities(context) + for the_capability in the_capabilities.iteritems(): + if the_capability[1].type == value or the_capability[1]._name == value: + the_child_nodetypes.append(the_node_type) + + for the_node_type in the_child_nodetypes: + if _is_parent(context, the_node_type[1], node._name, 'node_types'): + return + +def _is_parent(context, type_obj, parent_type_name, parent_type): + parent_type_name = convert_name_to_full_type_name(context, parent_type_name, + context.presentation.get('service_template', + parent_type)) + if type_obj._name == parent_type_name: + return True + the_parent = type_obj._get_parent(context) + if the_parent is not None: + if the_parent._name == parent_type_name: + return True + found = _is_parent(context, the_parent, parent_type_name, parent_type) + return found + else: + return False def node_filter_validator(field, presentation, context): """ diff --git a/tests/cli/test_type_definitions.py b/tests/cli/test_type_definitions.py new file mode 100644 index 00000000..92b31567 --- /dev/null +++ b/tests/cli/test_type_definitions.py @@ -0,0 +1,228 @@ +# 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 os +from aria.exceptions import ( + TypeDefinitionException, + TypeDefinitionAlreadyExistsException, + TypeDefinitionNotFoundException, + AriaException + ) +from aria.cli.env import _Environment +from aria.storage import exceptions as storage_exceptions +from aria.type_definition_manager import TypeDefinitionManager +from aria.cli import service_template_utils +from ..mock import models as mock_models +from .base_test import ( # pylint: disable=unused-import + TestCliBase, + assert_exception_raised, + raise_exception, + mock_storage +) + +class TestTypeDefinitionsLoad(TestCliBase): + + def test_header_string(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions load stubpath.csar') + assert 'Loading type definition stubpath.csar...' in self.logger_output_string + + def test_load_no_exception(self, monkeypatch, mock_object, mock_storage): + + monkeypatch.setattr(TypeDefinitionManager, 'load_type_definition', mock_object) + monkeypatch.setattr(service_template_utils, 'get', mock_object) + monkeypatch.setattr(os.path, 'dirname', mock_object) + self.invoke('type_definitions load stubpath.csar') + assert 'Loading type definition stubpath.csar...' in self.logger_output_string + assert 'Type definition loaded.' in self.logger_output_string + + def test_load_relative_path_single_yaml_file(self, monkeypatch, mock_object): + + monkeypatch.setattr(TypeDefinitionManager, 'load_type_definition', mock_object) + monkeypatch.setattr(os.path, 'isfile', lambda x: True) + monkeypatch.setattr(service_template_utils, '_is_archive', lambda x: False) + + self.invoke('type_definitions load stubpath.yaml') + + mock_object.assert_called_with(os.path.join(os.getcwd(), 'stubpath.yaml')) + + def test_load_raises_exception_resulting_from_name_uniqueness(self, monkeypatch, mock_object): + + monkeypatch.setattr(service_template_utils, 'get', mock_object) + monkeypatch.setattr(TypeDefinitionManager, + 'load_type_definition', + raise_exception(TypeDefinitionAlreadyExistsException, + msg=("Type Definition '{0}' with version '{1}'" + " already exists.".\ + format(mock_models.TYPE_DEFINITION_NAME,\ + mock_models.TYPE_DEFINITION_VERSION)))) + monkeypatch.setattr(os.path, 'dirname', mock_object) + + assert_exception_raised( + self.invoke('type_definitions load stubpath.yaml'), + expected_exception=TypeDefinitionAlreadyExistsException, + expected_msg=("Type Definition '{0}' with version '{1}' already exists.".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION))) + + def test_load_raises_exception(self, monkeypatch, mock_object): + + monkeypatch.setattr(service_template_utils, 'get', mock_object) + monkeypatch.setattr(TypeDefinitionManager, + 'load_type_definition', + raise_exception(storage_exceptions.NotFoundError)) + monkeypatch.setattr(os.path, 'dirname', mock_object) + + assert_exception_raised( + self.invoke('type_definitions load stubpath.yaml'), + expected_exception=storage_exceptions.StorageError) + + def test_load_raises_invalid_format_exception(self): + + assert_exception_raised( + self.invoke('type_definitions load stubpath'), + expected_exception=TypeDefinitionException, + expected_msg='Type definition file has invalid extension') + +class TestTypeDefinitionsShow(TestCliBase): + + def test_header_string(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions show {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION)) + assert "Showing type definition name '{0}' version '{1}'...".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION) in \ + self.logger_output_string + + def test_no_services_no_description(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions show {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION)) + + assert "Showing type definition name '{0}' version '{1}'...".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION) in \ + self.logger_output_string + assert 'Description:' not in self.logger_output_string + assert 'Existing services:' not in self.logger_output_string + + def test_details(self, monkeypatch, mock_storage, mock_object): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + monkeypatch.setattr(mock_storage.type_definition, '_get_query', mock_object) + self.invoke('type_definitions show {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION)) + + assert "Showing type definition name '{0}' version '{1}'...".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION) in \ + self.logger_output_string + assert 'id' in self.logger_output_string + assert 'name' in self.logger_output_string + assert 'version' in self.logger_output_string + assert 'main_file_name' in self.logger_output_string + assert 'uploaded_at' in self.logger_output_string + + assert mock_models.TYPE_DEFINITION_NAME in self.logger_output_string + assert mock_models.TYPE_DEFINITION_VERSION in self.logger_output_string + assert mock_models.TYPE_DEFINITION_MAIN_FILE_NAME in self.logger_output_string + +class TestTypeDefinitionsList(TestCliBase): + + def test_header_string(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions list') + assert 'Listing all type definitions...' in self.logger_output_string + +class TestTypeDefinitionsDelete(TestCliBase): + + def test_header_string(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions delete {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION)) + assert "Deleting type definition name '{0}' version '{1}'...".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION) in \ + self.logger_output_string + + def test_delete_no_exception(self, monkeypatch, mock_storage, mock_object): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + monkeypatch.setattr(TypeDefinitionManager, 'delete_type_definition', mock_object) + self.invoke('type_definitions delete {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION)) + + assert "Type definition name '{0}' version '{1}' deleted".\ + format(mock_models.TYPE_DEFINITION_NAME, mock_models.TYPE_DEFINITION_VERSION) in \ + self.logger_output_string + + def test_delete_raises_exception(self, monkeypatch): + + monkeypatch.setattr(TypeDefinitionManager, + 'delete_type_definition', + raise_exception(storage_exceptions.StorageError)) + + assert_exception_raised( + self.invoke('type_definitions delete {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME,\ + mock_models.TYPE_DEFINITION_VERSION)), + expected_exception=storage_exceptions.StorageError, + expected_msg='') + + def test_delete_raises_not_found_exception(self, monkeypatch): + + monkeypatch.setattr(TypeDefinitionManager, + 'delete_type_definition', + raise_exception(TypeDefinitionNotFoundException, + msg='Type definition does not exist.')) + + assert_exception_raised( + self.invoke('type_definitions delete {0} {1}'.\ + format(mock_models.TYPE_DEFINITION_NAME,\ + mock_models.TYPE_DEFINITION_VERSION)), + expected_exception=TypeDefinitionNotFoundException, + expected_msg='Type definition does not exist.') + +class TestTypeDefinitionsValidate(TestCliBase): + + def test_header_string(self, monkeypatch, mock_storage): + + monkeypatch.setattr(_Environment, 'model_storage', mock_storage) + self.invoke('type_definitions validate stubpath.csar') + assert 'Validating type definition: stubpath.csar' in self.logger_output_string + + def test_validate_no_exception(self, monkeypatch, mock_object): + + monkeypatch.setattr(TypeDefinitionManager, 'validate_type_definition', mock_object) + monkeypatch.setattr(service_template_utils, 'get', mock_object) + self.invoke('type_definitions validate stubpath.csar') + assert 'Type definition validated successfully' in self.logger_output_string + + def test_validate_raises_exception(self, monkeypatch, mock_object): + + monkeypatch.setattr(TypeDefinitionManager, 'validate_type_definition',\ + raise_exception(AriaException)) + monkeypatch.setattr(service_template_utils, 'get', mock_object) + assert_exception_raised( + self.invoke('type_definitions validate stubpath.csar'), + expected_exception=AriaException) + + def test_validate_raises_invalid_format_exception(self): + + assert_exception_raised( + self.invoke('type_definitions load stubpath'), + expected_exception=TypeDefinitionException, + expected_msg='Type definition file has invalid extension') diff --git a/tests/cli/utils.py b/tests/cli/utils.py index a1e0c9a9..145f55b0 100644 --- a/tests/cli/utils.py +++ b/tests/cli/utils.py @@ -62,11 +62,20 @@ def setup_logger(logger_name, class MockStorage(object): def __init__(self): + self.type_definition = MockTypeDefinitionStorage() self.service_template = MockServiceTemplateStorage() self.service = MockServiceStorage() self.node_template = MockNodeTemplateStorage() self.node = MockNodeStorage() +class MockTypeDefinitionStorage(object): + + def __init__(self): + self.td = mock_models.load_type_definition() + self.list = MagicMock(return_value=[self.td]) + self.get = MagicMock(return_value=self.td) + self._get_query = MagicMock() + self.delete = MagicMock() class MockServiceTemplateStorage(object): diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/node_template/test_node_template_requirements.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/node_template/test_node_template_requirements.py index fdf6f16b..4b9d722c 100644 --- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/node_template/test_node_template_requirements.py +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/node_template/test_node_template_requirements.py @@ -200,7 +200,9 @@ def test_node_template_requirement_capability_type_short_form(parser): my_node: type: MyType requirements: - - my_requirement: MyType + - my_requirement: my_node1 + my_node1: + type: MyType """).assert_success() diff --git a/tests/fixtures.py b/tests/fixtures.py index 3b1b9b59..db5f1468 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -21,6 +21,7 @@ application_model_storage, application_resource_storage ) +from aria import type_definition_manager as type_definition from aria.orchestrator import plugin from aria.storage import ( sql_mapi, @@ -68,3 +69,16 @@ def plugins_dir(tmpdir): @pytest.fixture def plugin_manager(model, plugins_dir): return plugin.PluginManager(model=model, plugins_dir=plugins_dir) + + +@pytest.fixture +def type_definitions_dir(tmpdir): + result = tmpdir.join('type_definitions') + result.mkdir() + return str(result) + + +@pytest.fixture +def type_definition_manager(model, type_definitions_dir): + return type_definition.\ + TypeDefinitionManager(model_storage=model, type_definitions_dir=type_definitions_dir) diff --git a/tests/helpers.py b/tests/helpers.py index 4c3194b4..a2b881fa 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -32,6 +32,10 @@ def get_service_template_uri(*args): return os.path.join(RESOURCES_DIR, 'service-templates', *args) +def get_type_definition_uri(*args): + return os.path.join(RESOURCES_DIR, 'type-definitions', *args) + + class FilesystemDataHolder(object): def __init__(self, path, reset=False): diff --git a/tests/mock/models.py b/tests/mock/models.py index 8a3b87e8..045f0474 100644 --- a/tests/mock/models.py +++ b/tests/mock/models.py @@ -37,6 +37,9 @@ NORMATIVE_REMOVE_SOURCE ) +TYPE_DEFINITION_NAME = 'test_type_definition' +TYPE_DEFINITION_VERSION = '1.0' +TYPE_DEFINITION_MAIN_FILE_NAME = 'main_file_name' SERVICE_TEMPLATE_NAME = 'test_service_template' SERVICE_NAME = 'test_service1' NODE_TEMPLATE_NAME = 'test_node_template' @@ -51,6 +54,17 @@ DEPENDENT_NODE_NAME = 'dependent_node' +def load_type_definition(name=TYPE_DEFINITION_NAME, version=TYPE_DEFINITION_VERSION,\ + main_file_name=TYPE_DEFINITION_MAIN_FILE_NAME): + now = datetime.now() + return models.TypeDefinition( + name=name, + version=version, + main_file_name=main_file_name, + uploaded_at=now + ) + + def create_service_template(name=SERVICE_TEMPLATE_NAME, description=None, inputs=None): now = datetime.now() inputs = inputs or {} diff --git a/tests/modeling/test_models.py b/tests/modeling/test_models.py index 25b40800..8ed8500d 100644 --- a/tests/modeling/test_models.py +++ b/tests/modeling/test_models.py @@ -65,6 +65,13 @@ def _empty_storage(): initiator=init_inmemory_model_storage) +def _type_definition_storage(): + storage = _empty_storage() + type_definition = mock.models.load_type_definition() + storage.type_definition.put(type_definition) + return storage + + def _service_template_storage(): storage = _empty_storage() service_template = mock.models.create_service_template() @@ -131,6 +138,12 @@ def empty_storage(): yield storage +@pytest.fixture +def type_definition_storage(): + with sql_storage(_type_definition_storage) as storage: + yield storage + + @pytest.fixture def service_template_storage(): with sql_storage(_service_template_storage) as storage: diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..cc414a17 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..418deea5 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/custom_types/type4.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..889b4ab0 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_no_metadata/definitions/type_definitions_main.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: test10 + template_author: ekowsalya + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..cc414a17 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..418deea5 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/custom_types/type4.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..f6931c65 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_parsing_error/definitions/type_definitions_main.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: test10 + template_author: ekowsalya + template_version: 1.0 + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute1 + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..090c2cfe --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,5 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml + diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/custom_inner_type/inner_type1.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/custom_inner_type/inner_type1.yaml new file mode 100644 index 00000000..c0ec1ce9 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/custom_inner_type/inner_type1.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_inner_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true + +topology_template: + node_templates: + test_node: + type:non_normative_type_definition_inner_type1_compute diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..c58bfcea --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/custom_types/type4.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - custom_inner_type/inner_type1.yaml + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..9d731f17 --- /dev/null +++ b/tests/resources/type-definitions/invalid_type_definition_with_topology_template/definitions/type_definitions_main.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: test1 + template_author: ekowsalya + template_version: "1.0" + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/valid_type_definition/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..cc414a17 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml diff --git a/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..418deea5 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/definitions/custom_types/type4.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/valid_type_definition/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..a86cc557 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition/definitions/type_definitions_main.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: test10 + template_author: ekowsalya + template_version: "1.0" + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition1/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/valid_type_definition1/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..cc414a17 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml diff --git a/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..418deea5 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/definitions/custom_types/type4.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition1/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/valid_type_definition1/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..4ff3376d --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition1/definitions/type_definitions_main.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: apple + template_author: ekowsalya + template_version: "1.0" + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition2/TOSCA-Metadata/TOSCA.meta b/tests/resources/type-definitions/valid_type_definition2/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 00000000..cc414a17 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: Kowsalya +Entry-Definitions: definitions/type_definitions_main.yaml diff --git a/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type1.yaml b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type1.yaml new file mode 100644 index 00000000..1af60544 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type1.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type1_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type2.yaml b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type2.yaml new file mode 100644 index 00000000..f2c86928 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type2.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type2_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type3.yaml b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type3.yaml new file mode 100644 index 00000000..0ecee3a8 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type3.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type333_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type4.yaml b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type4.yaml new file mode 100644 index 00000000..418deea5 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/definitions/custom_types/type4.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + non_normative_type_definition_type4_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/resources/type-definitions/valid_type_definition2/definitions/type_definitions_main.yaml b/tests/resources/type-definitions/valid_type_definition2/definitions/type_definitions_main.yaml new file mode 100644 index 00000000..859ed3c4 --- /dev/null +++ b/tests/resources/type-definitions/valid_type_definition2/definitions/type_definitions_main.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +metadata: + template_name: ball + template_author: ekowsalya + template_version: "1.0" + +imports: + - custom_types/type1.yaml + - custom_types/type2.yaml + - custom_types/type3.yaml + - custom_types/type4.yaml + - custom_types/type4.yaml + +node_types: + non_normative_type_definition_compute: + derived_from: tosca.nodes.Compute + properties: + name: + type: string + required: true + password: + type: string + required: true diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py index bc5434a3..b70ecdf4 100644 --- a/tests/storage/test_model_storage.py +++ b/tests/storage/test_model_storage.py @@ -74,7 +74,7 @@ def test_model_storage(storage): def test_application_storage_factory(): storage = application_model_storage(sql_mapi.SQLAlchemyModelAPI, initiator=tests_storage.init_inmemory_model_storage) - + assert storage.type_definition assert storage.service_template assert storage.node_template assert storage.group_template diff --git a/tests/test_type_definition_manager.py b/tests/test_type_definition_manager.py new file mode 100644 index 00000000..55966011 --- /dev/null +++ b/tests/test_type_definition_manager.py @@ -0,0 +1,222 @@ +# 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 os +import pytest +from tests.fixtures import (# pylint: disable=unused-import + inmemory_model as model, + type_definition_manager, + type_definitions_dir +) +from aria.exceptions import( + TypeDefinitionException, + InvalidTypeDefinitionException, + ParsingError, + TypeDefinitionNotFoundException + ) +from tests.helpers import get_type_definition_uri # pylint: disable=ungrouped-imports +from aria.storage.exceptions import NotFoundError # pylint: disable=ungrouped-imports + +TYPE_DEFINITION_NAME = 'test10' +TYPE_DEFINITION_VERSION = '1.0' +TYPE_DEFINITION_MAIN_FILE_NAME = 'type_definitions_main.yaml' + +class TestTypeDefinitionManager(object): + def test_load_type_definition(self, type_definition_manager, model, type_definitions_dir): + type_definition = type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition', 'definitions', \ + 'type_definitions_main.yaml')) + assert type_definition.name == TYPE_DEFINITION_NAME + assert type_definition.version == TYPE_DEFINITION_VERSION + assert type_definition.main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition == model.type_definition.get(type_definition.id) + type_definition_dir = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir) + assert type_definition_dir == type_definition_manager.\ + get_type_definition_dir(type_definition) + + def test_invalid_load_type_definition_with_no_file_exist(self, type_definition_manager): + with pytest.raises(TypeDefinitionException) as excinfo: + type_definition_manager.\ + load_type_definition(\ + get_type_definition_uri('valid_type_definition',\ + 'definitions', 'invalid')) + assert str(excinfo.value) == 'Could not open/load type definition file' + + def test_invalid_load_type_definition_with_topology_template(self, type_definition_manager): + with pytest.raises(InvalidTypeDefinitionException) as excinfo: + type_definition_manager.\ + load_type_definition(\ + get_type_definition_uri(('invalid_type_definition_with_' + 'topology_template'),\ + 'definitions',\ + 'type_definitions_main.yaml')) + assert str(excinfo.value) == ("Type definition '{0}' with version '{1}' is invalid." + " It contains topology template in '{2}'.").\ + format(TYPE_DEFINITION_MAIN_FILE_NAME,\ + TYPE_DEFINITION_VERSION, 'inner_type1.yaml') + + def test_invalid_load_type_definition_with_no_metadata(self, type_definition_manager): + with pytest.raises(InvalidTypeDefinitionException) as excinfo: + type_definition_manager.\ + load_type_definition(\ + get_type_definition_uri('invalid_type_definition_with_no_metadata', + 'definitions',\ + 'type_definitions_main.yaml')) + assert str(excinfo.value) == ('Type definition is invalid.' + ' It should have metadata information') + + def test_invalid_load_type_definition_with_parsing_error(self, type_definition_manager): + with pytest.raises(ParsingError) as excinfo: + type_definition_manager.\ + load_type_definition(\ + get_type_definition_uri(('invalid_type_definition_with_' + 'parsing_error'), + 'definitions',\ + 'type_definitions_main.yaml')) + assert str(excinfo.value) == 'Failed to parse type definition' + + def test_get_type_definition(self, type_definition_manager, model, type_definitions_dir): + type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition', 'definitions', \ + 'type_definitions_main.yaml')) + type_definition = type_definition_manager.get_type_definition(TYPE_DEFINITION_NAME, \ + TYPE_DEFINITION_VERSION) + assert type_definition.name == TYPE_DEFINITION_NAME + assert type_definition.version == TYPE_DEFINITION_VERSION + assert type_definition.main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition == model.type_definition.get(type_definition.id) + type_definition_dir = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir) + assert type_definition_dir == type_definition_manager.\ + get_type_definition_dir(type_definition) + + def test_get_type_definition_not_exist(self, type_definition_manager): + with pytest.raises(NotFoundError): + type_definition_manager.get_type_definition('test', '1.0') + + def test_delete_type_definition(self, type_definition_manager, model, type_definitions_dir): + type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition', 'definitions', \ + 'type_definitions_main.yaml')) + type_definition = type_definition_manager.\ + get_type_definition(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION) + assert type_definition.name == TYPE_DEFINITION_NAME + assert type_definition.version == TYPE_DEFINITION_VERSION + assert type_definition.main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition == model.type_definition.get(type_definition.id) + type_definition_dir = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir) + assert type_definition_dir == type_definition_manager.\ + get_type_definition_dir(type_definition) + type_definition_manager.\ + delete_type_definition(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION) + with pytest.raises(NotFoundError): + type_definition_manager.get_type_definition(TYPE_DEFINITION_NAME,\ + TYPE_DEFINITION_VERSION) + + def test_delete_type_definition_not_exist(self, type_definition_manager): + with pytest.raises(TypeDefinitionNotFoundException) as excinfo: + type_definition_manager.delete_type_definition('test', '1.0') + assert str(excinfo.value) == "Type definition name 'test' version '1.0' does not exist." + + def test_list_type_definition(self, type_definition_manager, model, type_definitions_dir): + type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition', 'definitions', \ + 'type_definitions_main.yaml')) + type_definition = type_definition_manager.\ + get_type_definition(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION) + assert type_definition.name == TYPE_DEFINITION_NAME + assert type_definition.version == TYPE_DEFINITION_VERSION + assert type_definition.main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition == model.type_definition.get(type_definition.id) + type_definition_dir = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format(TYPE_DEFINITION_NAME, TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir) + assert type_definition_dir == type_definition_manager.\ + get_type_definition_dir(type_definition) + type_definition_list = type_definition_manager.\ + list_type_definition(sort_by='uploaded_at', descending=False) + assert type_definition_list[0].name == TYPE_DEFINITION_NAME + assert type_definition_list[0].version == TYPE_DEFINITION_VERSION + assert type_definition_list[0].main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition_list[0] == model.type_definition.get(type_definition.id) + type_definition_dir = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format(TYPE_DEFINITION_NAME, \ + TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir) + assert type_definition_dir == type_definition_manager.\ + get_type_definition_dir(type_definition) + + def test_list_type_definition_sort_order(self, type_definition_manager,\ + model, type_definitions_dir): + type_definition1 = type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition1', 'definitions', \ + 'type_definitions_main.yaml')) + type_definition2 = type_definition_manager.\ + load_type_definition(get_type_definition_uri('valid_type_definition2', 'definitions', \ + 'type_definitions_main.yaml')) + + type_definition_list = type_definition_manager.\ + list_type_definition(sort_by='name', descending=True) + + assert type_definition_list[0].name == 'ball' + assert type_definition_list[0].version == TYPE_DEFINITION_VERSION + assert type_definition_list[0].main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition_list[0] == model.type_definition.get(type_definition2.id) + type_definition_dir1 = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format('ball', \ + TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir1) + assert type_definition_dir1 == type_definition_manager.\ + get_type_definition_dir(type_definition2) + + assert type_definition_list[1].name == 'apple' + assert type_definition_list[1].version == TYPE_DEFINITION_VERSION + assert type_definition_list[1].main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition_list[1] == model.type_definition.get(type_definition1.id) + type_definition_dir2 = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format('apple', \ + TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir2) + assert type_definition_dir2 == type_definition_manager.\ + get_type_definition_dir(type_definition1) + + type_definition_list = type_definition_manager.\ + list_type_definition(sort_by='uploaded_at', descending=False) + + assert type_definition_list[0].name == 'apple' + assert type_definition_list[0].version == TYPE_DEFINITION_VERSION + assert type_definition_list[0].main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition_list[0] == model.type_definition.get(type_definition1.id) + type_definition_dir3 = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format('apple', \ + TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir3) + assert type_definition_dir3 == type_definition_manager.\ + get_type_definition_dir(type_definition1) + + assert type_definition_list[1].name == 'ball' + assert type_definition_list[1].version == TYPE_DEFINITION_VERSION + assert type_definition_list[1].main_file_name == TYPE_DEFINITION_MAIN_FILE_NAME + assert type_definition_list[1] == model.type_definition.get(type_definition2.id) + type_definition_dir4 = os.path.join(type_definitions_dir, '{0}-{1}'.\ + format('ball', \ + TYPE_DEFINITION_VERSION)) + assert os.path.isdir(type_definition_dir4) + assert type_definition_dir4 == type_definition_manager.\ + get_type_definition_dir(type_definition2) diff --git a/tests/topology/service_templates.py b/tests/topology/service_templates.py index 60d5ad0b..8b0dd38c 100644 --- a/tests/topology/service_templates.py +++ b/tests/topology/service_templates.py @@ -33,7 +33,7 @@ def consume_literal(literal, consumer_class_name='instance', cache=True, no_issu return context, dumper -def consume_use_case(use_case_name, consumer_class_name='instance', cache=True): +def consume_use_case(use_case_name, consumer_class_name='instance', cache=True, no_issues=True): cachedmethod.ENABLED = cache uri = get_example_uri('tosca-simple-1.0', 'use-cases', use_case_name, '{0}.yaml'.format(use_case_name)) @@ -44,7 +44,12 @@ def consume_use_case(use_case_name, consumer_class_name='instance', cache=True): consumer, dumper = create_consumer(context, consumer_class_name) consumer.consume() context.validation.dump_issues() - assert not context.validation.has_issues + + if no_issues: + assert not context.validation.has_issues + else: + assert context.validation.has_issues + return context, dumper diff --git a/tests/topology/test_end2end.py b/tests/topology/test_end2end.py index a583db55..5428bdb5 100644 --- a/tests/topology/test_end2end.py +++ b/tests/topology/test_end2end.py @@ -83,7 +83,7 @@ def test_use_case_multi_tier_1(): def test_use_case_container_1(): - consume_use_case('container-1', 'template') + consume_use_case('container-1', 'template', no_issues=False) # NodeCellar ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services