http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/extensions/aria_extension_tosca/simple_v1_0/functions.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/functions.py b/extensions/aria_extension_tosca/simple_v1_0/functions.py index e385817..405aa8f 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/functions.py +++ b/extensions/aria_extension_tosca/simple_v1_0/functions.py @@ -19,8 +19,9 @@ from aria.utils.collections import FrozenList from aria.utils.formatting import as_raw, safe_repr from aria.parser import dsl_specification from aria.parser.exceptions import InvalidValueError -from aria.parser.modeling import (Function, CannotEvaluateFunctionException) from aria.parser.validation import Issue +from aria.modeling.exceptions import CannotEvaluateFunctionException +from aria.modeling.functions import Function # # Intrinsic @@ -139,8 +140,8 @@ class GetInput(Function): raise CannotEvaluateFunctionException() the_input = context.modeling.instance.inputs.get( self.input_property_name, - context.modeling.model.inputs.get(self.input_property_name)) - return the_input.value if the_input is not None else None + context.modeling.template.inputs.get(self.input_property_name)) + return as_raw(the_input.value) if the_input is not None else None @dsl_specification('4.4.2', 'tosca-simple-1.0') class GetProperty(Function): @@ -209,7 +210,7 @@ class GetProperty(Function): found = False break if found: - return value + return as_raw(value) raise InvalidValueError( 'function "get_property" could not find "%s" in modelable entity "%s"' \
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py ---------------------------------------------------------------------- diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py index f340954..4477732 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py +++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py @@ -13,248 +13,292 @@ # See the License for the specific language governing permissions and # limitations under the License. +""" +Creates ARIA service template models based on the TOSCA presentation. + +Relies on many helper methods in the presentation classes. +""" + import re +from types import FunctionType +from datetime import datetime -from aria.parser.modeling import (Type, RelationshipType, PolicyType, ServiceModel, NodeTemplate, +from aria.modeling.models import (Type, ServiceTemplate, NodeTemplate, RequirementTemplate, RelationshipTemplate, CapabilityTemplate, GroupTemplate, PolicyTemplate, SubstitutionTemplate, - MappingTemplate, InterfaceTemplate, OperationTemplate, - ArtifactTemplate, Metadata, Parameter) + SubstitutionTemplateMapping, InterfaceTemplate, OperationTemplate, + ArtifactTemplate, Metadata, Parameter, PluginSpecification) from ..data_types import coerce_value -from platform import node -def create_service_model(context): # pylint: disable=too-many-locals,too-many-branches - model = ServiceModel() + +def create_service_template_model(context): # pylint: disable=too-many-locals,too-many-branches + model = ServiceTemplate(created_at=datetime.now(), + main_file_name=str(context.presentation.location)) model.description = context.presentation.get('service_template', 'description', 'value') + # Metadata metadata = context.presentation.get('service_template', 'metadata') if metadata is not None: - substitution_template = Metadata() - substitution_template.values['template_name'] = metadata.template_name - substitution_template.values['template_author'] = metadata.template_author - substitution_template.values['template_version'] = metadata.template_version - custom = metadata.custom - if custom: - for name, v in custom.iteritems(): - substitution_template.values[name] = v - model.metadata = substitution_template + create_metadata_models(context, model, metadata) + # Types + model.node_types = Type(variant='node') create_types(context, - context.modeling.node_types, + model.node_types, context.presentation.get('service_template', 'node_types')) + model.group_types = Type(variant='group') create_types(context, - context.modeling.group_types, + model.group_types, context.presentation.get('service_template', 'group_types')) + model.policy_types = Type(variant='policy') create_types(context, - context.modeling.capability_types, - context.presentation.get('service_template', 'capability_types')) - create_types(context, - context.modeling.relationship_types, - context.presentation.get('service_template', 'relationship_types'), - create_relationship_type) + model.policy_types, + context.presentation.get('service_template', 'policy_types')) + model.relationship_types = Type(variant='relationship') create_types(context, - context.modeling.policy_types, - context.presentation.get('service_template', 'policy_types'), - create_policy_type) + model.relationship_types, + context.presentation.get('service_template', 'relationship_types')) + model.capability_types = Type(variant='capability') create_types(context, - context.modeling.artifact_types, - context.presentation.get('service_template', 'artifact_types')) + model.capability_types, + context.presentation.get('service_template', 'capability_types')) + model.interface_types = Type(variant='interface') create_types(context, - context.modeling.interface_types, + model.interface_types, context.presentation.get('service_template', 'interface_types')) + model.artifact_types = Type(variant='artifact') + create_types(context, + model.artifact_types, + context.presentation.get('service_template', 'artifact_types')) + # Topology template topology_template = context.presentation.get('service_template', 'topology_template') if topology_template is not None: - create_properties_from_values(model.inputs, topology_template._get_input_values(context)) - create_properties_from_values(model.outputs, topology_template._get_output_values(context)) + create_parameter_models_from_values(model.inputs, + topology_template._get_input_values(context)) + create_parameter_models_from_values(model.outputs, + topology_template._get_output_values(context)) + # Plugin specifications + policies = context.presentation.get('service_template', 'topology_template', 'policies') + if policies: + for policy in policies.itervalues(): + if model.policy_types.get_descendant(policy.type).role == 'plugin': + plugin_specification = create_plugin_specification_model(context, policy) + model.plugin_specifications[plugin_specification.name] = plugin_specification + + # Node templates node_templates = context.presentation.get('service_template', 'topology_template', 'node_templates') if node_templates: - for node_template_name, node_template in node_templates.iteritems(): - model.node_templates[node_template_name] = create_node_template(context, node_template) + for node_template in node_templates.itervalues(): + node_template_model = create_node_template_model(context, model, node_template) + model.node_templates[node_template_model.name] = node_template_model + for node_template in node_templates.itervalues(): + fix_node_template_model(context, model, node_template) + # Group templates groups = context.presentation.get('service_template', 'topology_template', 'groups') if groups: - for group_name, group in groups.iteritems(): - model.group_templates[group_name] = create_group_template(context, group) + for group in groups.itervalues(): + group_template_model = create_group_template_model(context, model, group) + model.group_templates[group_template_model.name] = group_template_model + # Policy templates policies = context.presentation.get('service_template', 'topology_template', 'policies') if policies: - for policy_name, policy in policies.iteritems(): - model.policy_templates[policy_name] = create_policy_template(context, policy) + for policy in policies.itervalues(): + policy_template_model = create_policy_template_model(context, model, policy) + model.policy_templates[policy_template_model.name] = policy_template_model + # Substitution template substitution_mappings = context.presentation.get('service_template', 'topology_template', 'substitution_mappings') - if substitution_mappings is not None: - substitution_template = SubstitutionTemplate(substitution_mappings.node_type) - capabilities = substitution_mappings.capabilities - if capabilities: - for mapped_capability_name, capability in capabilities.iteritems(): - substitution_template.capability_templates[mapped_capability_name] = \ - MappingTemplate(mapped_capability_name, capability.node_template, - capability.capability) - requirements = substitution_mappings.requirements - if requirements: - for mapped_requirement_name, requirement in requirements.iteritems(): - substitution_template.requirement_templates[mapped_requirement_name] = \ - MappingTemplate(mapped_requirement_name, requirement.node_template, - requirement.requirement) - model.substitution_template = substitution_template + if substitution_mappings: + model.substitution_template = create_substitution_template_model(context, model, + substitution_mappings) return model -def create_node_template(context, node_template): + +def create_metadata_models(context, service_template, metadata): + service_template.meta_data['template_name'] = Metadata(name='template_name', + value=metadata.template_name) + service_template.meta_data['template_author'] = Metadata(name='template_author', + value=metadata.template_author) + service_template.meta_data['template_version'] = Metadata(name='template_version', + value=metadata.template_version) + custom = metadata.custom + if custom: + for name, value in custom.iteritems(): + service_template.meta_data[name] = Metadata(name=name, + value=value) + + +def create_node_template_model(context, service_template, node_template): node_type = node_template._get_type(context) - model = NodeTemplate(name=node_template._name, type_name=node_type._name) + node_type = service_template.node_types.get_descendant(node_type._name) + model = NodeTemplate(name=node_template._name, + type=node_type) + + model.default_instances = 1 + model.min_instances = 0 if node_template.description: model.description = node_template.description.value - create_properties_from_values(model.properties, node_template._get_property_values(context)) - create_interface_templates(context, model.interface_templates, - node_template._get_interfaces(context)) + create_parameter_models_from_values(model.properties, + node_template._get_property_values(context)) + create_interface_template_models(context, service_template, model.interface_templates, + node_template._get_interfaces(context)) artifacts = node_template._get_artifacts(context) if artifacts: for artifact_name, artifact in artifacts.iteritems(): - model.artifact_templates[artifact_name] = create_artifact_template(context, artifact) - - requirements = node_template._get_requirements(context) - if requirements: - for _, requirement in requirements: - model.requirement_templates.append(create_requirement_template(context, requirement)) + model.artifact_templates[artifact_name] = \ + create_artifact_template_model(context, service_template, artifact) capabilities = node_template._get_capabilities(context) if capabilities: for capability_name, capability in capabilities.iteritems(): - model.capability_templates[capability_name] = create_capability_template(context, - capability) + model.capability_templates[capability_name] = \ + create_capability_template_model(context, service_template, capability) - create_node_filter_constraint_lambdas(context, node_template.node_filter, - model.target_node_template_constraints) + if model.target_node_template_constraints: + model.target_node_template_constraints = [] + create_node_filter_constraint_lambdas(context, node_template.node_filter, + model.target_node_template_constraints) return model -def create_interface_template(context, interface): - interface_type = interface._get_type(context) - model = InterfaceTemplate(name=interface._name, type_name=interface_type._name) - if interface_type.description: - model.description = interface_type.description.value - - inputs = interface.inputs - if inputs: - for input_name, the_input in inputs.iteritems(): - model.inputs[input_name] = Parameter(the_input.value.type, the_input.value.value, - the_input.value.description) - - operations = interface.operations - if operations: - for operation_name, operation in operations.iteritems(): - model.operation_templates[operation_name] = create_operation_template(context, - operation) +def fix_node_template_model(context, service_template, node_template): + # Requirements have to be created after all node templates have been created, because + # requirements might reference another node template + model = service_template.node_templates[node_template._name] + requirements = node_template._get_requirements(context) + if requirements: + for _, requirement in requirements: + model.requirement_templates.append(create_requirement_template_model(context, + service_template, + requirement)) - return model if model.operation_templates else None -def create_operation_template(context, operation): # pylint: disable=unused-argument - model = OperationTemplate(name=operation._name) +def create_group_template_model(context, service_template, group): + group_type = group._get_type(context) + group_type = service_template.group_types.get_descendant(group_type._name) + model = GroupTemplate(name=group._name, + type=group_type) - if operation.description: - model.description = operation.description.value + if group.description: + model.description = group.description.value - implementation = operation.implementation - if implementation is not None: - model.implementation = implementation.primary - dependencies = implementation.dependencies - if dependencies is not None: - model.dependencies = dependencies + create_parameter_models_from_values(model.properties, group._get_property_values(context)) + create_interface_template_models(context, service_template, model.interface_templates, + group._get_interfaces(context)) - inputs = operation.inputs - if inputs: - for input_name, the_input in inputs.iteritems(): - model.inputs[input_name] = Parameter(the_input.value.type, the_input.value.value, - the_input.value.description) + members = group.members + if members: + for member in members: + node_template = service_template.node_templates[member] + assert node_template + model.node_templates.append(node_template) return model -def create_artifact_template(context, artifact): - model = ArtifactTemplate(name=artifact._name, type_name=artifact.type, - source_path=artifact.file) - if artifact.description: - model.description = artifact.description.value +def create_policy_template_model(context, service_template, policy): + policy_type = policy._get_type(context) + policy_type = service_template.policy_types.get_descendant(policy_type._name) + model = PolicyTemplate(name=policy._name, + type=policy_type) - model.target_path = artifact.deploy_path + if policy.description: + model.description = policy.description.value - repository = artifact._get_repository(context) - if repository is not None: - model.repository_url = repository.url - credential = repository._get_credential(context) - if credential: - for k, v in credential.iteritems(): - model.repository_credential[k] = v + create_parameter_models_from_values(model.properties, policy._get_property_values(context)) - create_properties_from_values(model.properties, artifact._get_property_values(context)) + node_templates, groups = policy._get_targets(context) + if node_templates: + for target in node_templates: + node_template = service_template.node_templates[target._name] + assert node_template + model.node_templates.append(node_template) + if groups: + for target in groups: + group_template = service_template.group_templates[target._name] + assert group_template + model.group_templates.append(group_template) return model -def create_requirement_template(context, requirement): + +def create_requirement_template_model(context, service_template, requirement): model = {'name': requirement._name} node, node_variant = requirement._get_node(context) if node is not None: if node_variant == 'node_type': - model['target_node_type_name'] = node._name + node_type = service_template.node_types.get_descendant(node._name) + model['target_node_type'] = node_type else: - model['target_node_template_name'] = node._name + node_template = service_template.node_templates[node._name] + model['target_node_template'] = node_template capability, capability_variant = requirement._get_capability(context) if capability is not None: if capability_variant == 'capability_type': - model['target_capability_type_name'] = capability._name + capability_type = \ + service_template.capability_types.get_descendant(capability._name) + model['target_capability_type'] = capability_type else: model['target_capability_name'] = capability._name model = RequirementTemplate(**model) - create_node_filter_constraint_lambdas(context, requirement.node_filter, - model.target_node_template_constraints) + if model.target_node_template_constraints: + model.target_node_template_constraints = [] + create_node_filter_constraint_lambdas(context, requirement.node_filter, + model.target_node_template_constraints) relationship = requirement.relationship if relationship is not None: - model.relationship_template = create_relationship_template(context, relationship) + model.relationship_template = \ + create_relationship_template_model(context, service_template, relationship) + model.relationship_template.name = requirement._name return model -def create_relationship_type(context, relationship_type): # pylint: disable=unused-argument - return RelationshipType(relationship_type._name) - -def create_policy_type(context, policy_type): # pylint: disable=unused-argument - return PolicyType(policy_type._name) -def create_relationship_template(context, relationship): +def create_relationship_template_model(context, service_template, relationship): relationship_type, relationship_type_variant = relationship._get_type(context) if relationship_type_variant == 'relationship_type': - model = RelationshipTemplate(type_name=relationship_type._name) + relationship_type = service_template.relationship_types.get_descendant( + relationship_type._name) + model = RelationshipTemplate(type=relationship_type) else: relationship_template = relationship_type relationship_type = relationship_template._get_type(context) - model = RelationshipTemplate(type_name=relationship_type._name, - template_name=relationship_template._name) + relationship_type = service_template.relationship_types.get_descendant( + relationship_type._name) + model = RelationshipTemplate(type=relationship_type) if relationship_template.description: model.description = relationship_template.description.value - create_properties_from_assignments(model.properties, relationship.properties) - create_interface_templates(context, model.source_interface_templates, relationship.interfaces) + create_parameter_models_from_assignments(model.properties, relationship.properties) + create_interface_template_models(context, service_template, model.interface_templates, + relationship.interfaces) return model -def create_capability_template(context, capability): + +def create_capability_template_model(context, service_template, capability): capability_type = capability._get_type(context) - model = CapabilityTemplate(name=capability._name, type_name=capability_type._name) + capability_type = service_template.capability_types.get_descendant(capability_type._name) + model = CapabilityTemplate(name=capability._name, + type=capability_type) capability_definition = capability._get_definition(context) if capability_definition.description: @@ -267,51 +311,154 @@ def create_capability_template(context, capability): valid_source_types = capability_definition.valid_source_types if valid_source_types: - model.valid_source_node_type_names = valid_source_types + for valid_source_type in valid_source_types: + # TODO: handle shortcut type names + node_type = service_template.node_types.get_descendant(valid_source_type) + model.valid_source_node_types.append(node_type) - create_properties_from_assignments(model.properties, capability.properties) + create_parameter_models_from_assignments(model.properties, capability.properties) return model -def create_group_template(context, group): - group_type = group._get_type(context) - model = GroupTemplate(name=group._name, type_name=group_type._name) - if group.description: - model.description = group.description.value +def create_interface_template_model(context, service_template, interface): + interface_type = interface._get_type(context) + interface_type = service_template.interface_types.get_descendant(interface_type._name) + model = InterfaceTemplate(name=interface._name, + type=interface_type) - create_properties_from_values(model.properties, group._get_property_values(context)) - create_interface_templates(context, model.interface_templates, group._get_interfaces(context)) + if interface_type.description: + model.description = interface_type.description - members = group.members - if members: - for member in members: - model.member_node_template_names.append(member) + inputs = interface.inputs + if inputs: + for input_name, the_input in inputs.iteritems(): + model.inputs[input_name] = Parameter(name=input_name, + type_name=the_input.value.type, + value=the_input.value.value, + description=the_input.value.description) + + operations = interface.operations + if operations: + for operation_name, operation in operations.iteritems(): + model.operation_templates[operation_name] = \ + create_operation_template_model(context, service_template, operation) + + return model if model.operation_templates else None + + +def create_operation_template_model(context, service_template, operation): # pylint: disable=unused-argument + model = OperationTemplate(name=operation._name) + + if operation.description: + model.description = operation.description.value + + implementation = operation.implementation + if (implementation is not None) and operation.implementation.primary: + model.plugin_specification, model.implementation = \ + parse_implementation_string(context, service_template, operation.implementation.primary) + + dependencies = implementation.dependencies + if dependencies is not None: + model.dependencies = dependencies + + inputs = operation.inputs + if inputs: + for input_name, the_input in inputs.iteritems(): + model.inputs[input_name] = Parameter(name=input_name, + type_name=the_input.value.type, + value=the_input.value.value, + description=the_input.value.description) return model -def create_policy_template(context, policy): - policy_type = policy._get_type(context) - model = PolicyTemplate(name=policy._name, type_name=policy_type._name) - if policy.description: - model.description = policy.description.value +def create_artifact_template_model(context, service_template, artifact): + artifact_type = artifact._get_type(context) + artifact_type = service_template.artifact_types.get_descendant(artifact_type._name) + model = ArtifactTemplate(name=artifact._name, + type=artifact_type, + source_path=artifact.file) + + if artifact.description: + model.description = artifact.description.value - create_properties_from_values(model.properties, policy._get_property_values(context)) + model.target_path = artifact.deploy_path - node_templates, groups = policy._get_targets(context) - for node_template in node_templates: - model.target_node_template_names.append(node_template._name) - for group in groups: - model.target_group_template_names.append(group._name) + repository = artifact._get_repository(context) + if repository is not None: + model.repository_url = repository.url + credential = repository._get_credential(context) + if credential: + model.repository_credential = {} + for k, v in credential.iteritems(): + model.repository_credential[k] = v + + create_parameter_models_from_values(model.properties, artifact._get_property_values(context)) + + return model + + +def create_substitution_template_model(context, service_template, substitution_mappings): + node_type = service_template.node_types.get_descendant(substitution_mappings.node_type) + model = SubstitutionTemplate(node_type=node_type) + + capabilities = substitution_mappings.capabilities + if capabilities: + for mapped_capability_name, capability in capabilities.iteritems(): + name = 'capability.' + mapped_capability_name + node_template_model = service_template.node_templates[capability.node_template] + capability_template_model = \ + node_template_model.capability_templates[capability.capability] + model.mappings[name] = \ + SubstitutionTemplateMapping(name=name, + node_template=node_template_model, + capability_template=capability_template_model) + + requirements = substitution_mappings.requirements + if requirements: + for mapped_requirement_name, requirement in requirements.iteritems(): + name = 'requirement.' + mapped_requirement_name + node_template_model = service_template.node_templates[requirement.node_template] + requirement_template_model = None + for a_model in node_template_model.requirement_templates: + if a_model.name == requirement.requirement: + requirement_template_model = a_model + break + model.mappings[name] = \ + SubstitutionTemplateMapping(name=name, + node_template=node_template_model, + requirement_template=requirement_template_model) return model + +def create_plugin_specification_model(context, policy): + properties = policy.properties + + def get(name): + prop = properties.get(name) + return prop.value if prop is not None else None + + model = PluginSpecification(name=policy._name, + archive_name=get('archive_name') or '', + distribution=get('distribution'), + distribution_release=get('distribution_release'), + distribution_version=get('distribution_version'), + package_name=get('package_name') or '', + package_source=get('package_source'), + package_version=get('package_version'), + supported_platform=get('supported_platform'), + supported_py_versions=get('supported_py_versions')) + + return model + + # # Utils # -def create_types(context, root, types, normalize=None): +def create_types(context, root, types): if types is None: return @@ -325,39 +472,49 @@ def create_types(context, root, types, normalize=None): for name, the_type in types.iteritems(): if root.get_descendant(name) is None: parent_type = the_type._get_parent(context) - if normalize: - model = normalize(context, the_type) - else: - model = Type(the_type._name) + model = Type(name=the_type._name, + role=the_type._get_extension('role')) if the_type.description: model.description = the_type.description.value - model.role = the_type._get_extension('role') if parent_type is None: + model.parent = root + model.variant = root.variant root.children.append(model) else: container = root.get_descendant(parent_type._name) if container is not None: + model.parent = container + model.variant = container.variant container.children.append(model) -def create_properties_from_values(properties, source_properties): + +def create_parameter_models_from_values(properties, source_properties): if source_properties: for property_name, prop in source_properties.iteritems(): - properties[property_name] = Parameter(prop.type, prop.value, prop.description) + properties[property_name] = Parameter(name=property_name, + type_name=prop.type, + value=prop.value, + description=prop.description) -def create_properties_from_assignments(properties, source_properties): + +def create_parameter_models_from_assignments(properties, source_properties): if source_properties: for property_name, prop in source_properties.iteritems(): - properties[property_name] = Parameter(prop.value.type, prop.value.value, - prop.value.description) + properties[property_name] = Parameter(name=property_name, + type_name=prop.value.type, + value=prop.value.value, + description=prop.value.description) + -def create_interface_templates(context, interfaces, source_interfaces): +def create_interface_template_models(context, service_template, interfaces, source_interfaces): if source_interfaces: for interface_name, interface in source_interfaces.iteritems(): - interface = create_interface_template(context, interface) + interface = create_interface_template_model(context, service_template, interface) if interface is not None: interfaces[interface_name] = interface -def create_node_filter_constraint_lambdas(context, node_filter, node_type_constraints): + +def create_node_filter_constraint_lambdas(context, node_filter, target_node_template_constraints): if node_filter is None: return @@ -367,7 +524,7 @@ def create_node_filter_constraint_lambdas(context, node_filter, node_type_constr func = create_constraint_clause_lambda(context, node_filter, constraint_clause, property_name, None) if func is not None: - node_type_constraints.append(func) + target_node_template_constraints.append(func) capabilities = node_filter.capabilities if capabilities is not None: @@ -378,7 +535,8 @@ def create_node_filter_constraint_lambdas(context, node_filter, node_type_constr func = create_constraint_clause_lambda(context, node_filter, constraint_clause, property_name, capability_name) if func is not None: - node_type_constraints.append(func) + target_node_template_constraints.append(func) + def create_constraint_clause_lambda(context, node_filter, constraint_clause, property_name, # pylint: disable=too-many-return-statements capability_name): @@ -497,3 +655,23 @@ def create_constraint_clause_lambda(context, node_filter, constraint_clause, pro return pattern return None + + +def parse_implementation_string(context, service_template, implementation): + if not implementation: + return None, '' + + index = implementation.find('>') + if index == -1: + return None, implementation + plugin_name = implementation[:index].strip() + + if plugin_name == 'execution': + plugin_specification = None + else: + plugin_specification = service_template.plugin_specifications.get(plugin_name) + if plugin_specification is None: + raise ValueError('unknown plugin: "{0}"'.format(plugin_name)) + + implementation = implementation[index+1:].strip() + return plugin_specification, implementation http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/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 0809014..eee5769 100644 --- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py +++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py @@ -19,7 +19,7 @@ from aria.parser.presentation import Presenter from .functions import (Concat, Token, GetInput, GetProperty, GetAttribute, GetOperationOutput, GetNodesOfType, GetArtifact) -from .modeling import create_service_model +from .modeling import create_service_template_model from .templates import ServiceTemplate class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name @@ -75,5 +75,5 @@ class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name return FrozenList(import_locations) if import_locations else EMPTY_READ_ONLY_LIST @cachedmethod - def _get_service_model(self, context): # pylint: disable=no-self-use - return create_service_model(context) + 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/9841ca4a/tests/end2end/test_orchestrator.py ---------------------------------------------------------------------- diff --git a/tests/end2end/test_orchestrator.py b/tests/end2end/test_orchestrator.py index f930577..7b8dc97 100644 --- a/tests/end2end/test_orchestrator.py +++ b/tests/end2end/test_orchestrator.py @@ -17,9 +17,9 @@ import sys from aria.orchestrator.runner import Runner from aria.orchestrator.workflows.builtin import BUILTIN_WORKFLOWS -from aria.parser.modeling.storage import initialize_storage from aria.utils.imports import import_fullname from aria.utils.collections import OrderedDict +from aria.cli.dry import convert_to_dry from tests.parser.service_templates import consume_node_cellar @@ -38,23 +38,25 @@ def test_custom(): def _workflow(workflow_name): context, _ = consume_node_cellar() + convert_to_dry(context.modeling.instance) + # TODO: this logic will eventually stabilize and be part of the ARIA API, # likely somewhere in aria.orchestrator.workflows if workflow_name in BUILTIN_WORKFLOWS: workflow_fn = import_fullname('aria.orchestrator.workflows.builtin.' + workflow_name) inputs = {} else: - policy = context.modeling.instance.policies[workflow_name] - sys.path.append(policy.properties['implementation'].value) - - workflow_fn = import_fullname(policy.properties['function'].value) + workflow = context.modeling.instance.policies[workflow_name] + sys.path.append(workflow.properties['implementation'].value) + workflow_fn = import_fullname(workflow.properties['function'].value) inputs = OrderedDict([ - (k, v.value) for k, v in policy.properties.iteritems() + (k, v.value) for k, v in workflow.properties.iteritems() if k not in WORKFLOW_POLICY_INTERNAL_PROPERTIES ]) def _initialize_storage(model_storage): - initialize_storage(context, model_storage, 1) + context.modeling.store(model_storage) - runner = Runner(workflow_name, workflow_fn, inputs, _initialize_storage, 1) + runner = Runner(workflow_name, workflow_fn, inputs, _initialize_storage, + lambda: context.modeling.instance.id) runner.run() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/end2end/test_tosca_simple_v1_0.py ---------------------------------------------------------------------- diff --git a/tests/end2end/test_tosca_simple_v1_0.py b/tests/end2end/test_tosca_simple_v1_0.py index f2a41ce..4658fc3 100644 --- a/tests/end2end/test_tosca_simple_v1_0.py +++ b/tests/end2end/test_tosca_simple_v1_0.py @@ -71,7 +71,7 @@ def test_use_case_network_4(): def test_use_case_webserver_dbms_1(): - consume_use_case('webserver-dbms-1', 'model') + consume_use_case('webserver-dbms-1', 'template') def test_use_case_webserver_dbms_2(): @@ -83,7 +83,7 @@ def test_use_case_multi_tier_1(): def test_use_case_container_1(): - consume_use_case('container-1', 'model') + consume_use_case('container-1', 'template') # NodeCellar @@ -101,7 +101,7 @@ def test_node_cellar_presentation(): def test_node_cellar_model(): - consume_node_cellar('model') + consume_node_cellar('template') def test_node_cellar_types(): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/mock/context.py ---------------------------------------------------------------------- diff --git a/tests/mock/context.py b/tests/mock/context.py index cf1a32d..3de3133 100644 --- a/tests/mock/context.py +++ b/tests/mock/context.py @@ -38,13 +38,13 @@ def simple(tmpdir, inmemory=False, context_kwargs=None): api_kwargs=dict(directory=os.path.join(tmpdir, 'resources')) ) - service_instance_id = create_simple_topology_two_nodes(model_storage) + service_id = create_simple_topology_two_nodes(model_storage) final_kwargs = dict( name='simple_context', model_storage=model_storage, resource_storage=resource_storage, - service_instance_id=service_instance_id, + service_id=service_id, workflow_name=models.WORKFLOW_NAME, task_max_attempts=models.TASK_MAX_ATTEMPTS, task_retry_interval=models.TASK_RETRY_INTERVAL http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/mock/models.py ---------------------------------------------------------------------- diff --git a/tests/mock/models.py b/tests/mock/models.py index 301fc01..bf43a75 100644 --- a/tests/mock/models.py +++ b/tests/mock/models.py @@ -15,132 +15,185 @@ from datetime import datetime -from aria.storage.modeling import model +from aria.modeling import models from . import operations -DEPLOYMENT_NAME = 'test_deployment_id' -BLUEPRINT_NAME = 'test_blueprint_id' -WORKFLOW_NAME = 'test_workflow_id' -EXECUTION_NAME = 'test_execution_id' +SERVICE_NAME = 'test_service_name' +SERVICE_TEMPLATE_NAME = 'test_service_template_name' +WORKFLOW_NAME = 'test_workflow_name' +EXECUTION_NAME = 'test_execution_name' TASK_RETRY_INTERVAL = 1 TASK_MAX_ATTEMPTS = 1 +DEPENDENCY_NODE_TEMPLATE_NAME = 'dependency_node_template' DEPENDENCY_NODE_NAME = 'dependency_node' -DEPENDENCY_NODE_INSTANCE_NAME = 'dependency_node_instance' +DEPENDENT_NODE_TEMPLATE_NAME = 'dependent_node_template' DEPENDENT_NODE_NAME = 'dependent_node' -DEPENDENT_NODE_INSTANCE_NAME = 'dependent_node_instance' -RELATIONSHIP_NAME = 'relationship' -RELATIONSHIP_INSTANCE_NAME = 'relationship_instance' -def get_dependency_node(deployment): - return model.NodeTemplate( - name=DEPENDENCY_NODE_NAME, - type_name='test_node_type', - type_hierarchy=[], - default_instances=1, - min_instances=1, - max_instances=1, - service_template=deployment.service_template, +def create_service_template(): + now = datetime.now() + return models.ServiceTemplate( + name=SERVICE_TEMPLATE_NAME, + description=None, + created_at=now, + updated_at=now, + main_file_name='main_file_name', + node_types=models.Type(variant='node', name='test_node_type'), + group_types=models.Type(variant='group', name='test_group_type'), + policy_types=models.Type(variant='policy', name='test_policy_type'), + relationship_types=models.Type(variant='relationship', name='test_relationship_type'), + capability_types=models.Type(variant='capability', name='test_capability_type'), + artifact_types=models.Type(variant='artifact', name='test_artifact_type'), + interface_types=models.Type(variant='interface', name='test_interface_type') ) -def get_dependency_node_instance(dependency_node, deployment): - return model.Node( - name=DEPENDENCY_NODE_INSTANCE_NAME, - service_instance=deployment, - runtime_properties={'ip': '1.1.1.1'}, - node_template=dependency_node, - state='', - scaling_groups=[] +def create_service(service_template): + now = datetime.utcnow() + return models.Service( + name=SERVICE_NAME, + service_template=service_template, + description='', + created_at=now, + updated_at=now, + permalink='', + scaling_groups={}, ) -def get_relationship(target): - requirement_template = model.RequirementTemplate(target_node_template_name=target.name) - capability_template = model.CapabilityTemplate() - - return requirement_template, capability_template +def create_dependency_node_template(service_template): + node_type = service_template.node_types.get_descendant('test_node_type') + capability_type = service_template.capability_types.get_descendant('test_capability_type') + capability_template = models.CapabilityTemplate( + name='capability', + type=capability_type + ) -def get_relationship_instance(source_instance, target_instance): - return model.Relationship( - target_node=target_instance, - source_node=source_instance, + node_template = models.NodeTemplate( + name=DEPENDENCY_NODE_TEMPLATE_NAME, + type=node_type, + capability_templates=_dictify(capability_template), + default_instances=1, + min_instances=1, + max_instances=1, + service_template=service_template ) + service_template.node_templates[node_template.name] = node_template + return node_template -def get_dependent_node(deployment, requirement_template, capability_template): - operation_templates = [model.OperationTemplate(implementation=op, - service_template=deployment.service_template) - for op in operations.NODE_OPERATIONS] - interface_template = model.InterfaceTemplate(operation_templates=operation_templates) +def create_dependent_node_template(service_template, dependency_node_template): + the_type = service_template.node_types.get_descendant('test_node_type') - return model.NodeTemplate( - name=DEPENDENT_NODE_NAME, - type_name='test_node_type', - type_hierarchy=[], + operation_templates = dict((op, models.OperationTemplate( + name=op, + implementation='test')) + for _, op in operations.NODE_OPERATIONS) + interface_template = models.InterfaceTemplate( + type=service_template.interface_types.get_descendant('test_interface_type'), + operation_templates=operation_templates) + + requirement_template = models.RequirementTemplate( + name='requirement', + target_node_template=dependency_node_template + ) + + node_template = models.NodeTemplate( + name=DEPENDENT_NODE_TEMPLATE_NAME, + type=the_type, default_instances=1, min_instances=1, max_instances=1, - service_template=deployment.service_template, - interface_templates=[interface_template], + interface_templates=_dictify(interface_template), requirement_templates=[requirement_template], - capability_templates=[capability_template], + service_template=service_template + ) + service_template.node_templates[node_template.name] = node_template + return node_template + + +def create_dependency_node(dependency_node_template, service): + node = models.Node( + name=DEPENDENCY_NODE_NAME, + type=dependency_node_template.type, + runtime_properties={'ip': '1.1.1.1'}, + version=None, + node_template=dependency_node_template, + state='', + scaling_groups=[], + service=service ) + service.nodes[node.name] = node + return node -def get_dependent_node_instance(dependent_node, deployment): - return model.Node( - name=DEPENDENT_NODE_INSTANCE_NAME, - service_instance=deployment, +def create_dependent_node(dependent_node_template, service): + node = models.Node( + name=DEPENDENT_NODE_NAME, + type=dependent_node_template.type, runtime_properties={}, - node_template=dependent_node, + version=None, + node_template=dependent_node_template, state='', scaling_groups=[], + service=service ) + service.nodes[node.name] = node + return node -def get_blueprint(): - now = datetime.now() - return model.ServiceTemplate( - plan={}, - name=BLUEPRINT_NAME, - description=None, - created_at=now, - updated_at=now, - main_file_name='main_file_name' +def create_relationship(source, target): + return models.Relationship( + source_node=source, + target_node=target ) -def get_execution(deployment): - return model.Execution( - service_instance=deployment, - status=model.Execution.STARTED, - workflow_name=WORKFLOW_NAME, - started_at=datetime.utcnow(), - parameters=None +def create_interface_template(service_template, interface_name, operation_name, + operation_kwargs=None, interface_kwargs=None): + the_type = service_template.interface_types.get_descendant('test_interface_type') + operation_template = models.OperationTemplate( + name=operation_name, + **(operation_kwargs or {}) + ) + return models.InterfaceTemplate( + type=the_type, + operation_templates=_dictify(operation_template), + name=interface_name, + **(interface_kwargs or {}) ) -def get_deployment(blueprint): - now = datetime.utcnow() - return model.ServiceInstance( - name=DEPLOYMENT_NAME, - service_template=blueprint, - description='', - created_at=now, - updated_at=now, - workflows={}, - permalink='', - policy_triggers={}, - policy_types={}, - scaling_groups={}, +def create_interface(service, interface_name, operation_name, operation_kwargs=None, + interface_kwargs=None): + the_type = service.service_template.interface_types.get_descendant('test_interface_type') + operation = models.Operation( + name=operation_name, + **(operation_kwargs or {}) + ) + return models.Interface( + type=the_type, + operations=_dictify(operation), + name=interface_name, + **(interface_kwargs or {}) + ) + + +def create_execution(service): + return models.Execution( + service=service, + status=models.Execution.STARTED, + workflow_name=WORKFLOW_NAME, + started_at=datetime.utcnow(), + parameters=None ) -def get_plugin(package_name='package', package_version='0.1'): - return model.Plugin( +def create_plugin(package_name='package', package_version='0.1'): + return models.Plugin( + name='test_plugin', archive_name='archive_name', distribution='distribution', distribution_release='dist_release', @@ -155,26 +208,20 @@ def get_plugin(package_name='package', package_version='0.1'): ) -def get_interface_template(operation_name, operation_kwargs=None, interface_kwargs=None): - operation_template = model.OperationTemplate( - name=operation_name, - **(operation_kwargs or {}) - - ) - return model.InterfaceTemplate( - operation_templates=[operation_template], - name=operation_name.rsplit('.', 1)[0], - **(interface_kwargs or {}) +def create_plugin_specification(package_name='package', package_version='0.1'): + return models.PluginSpecification( + name='test_plugin', + archive_name='archive_name', + distribution='distribution', + distribution_release='dist_release', + distribution_version='dist_version', + package_name=package_name, + package_source='source', + package_version=package_version, + supported_platform='any', + supported_py_versions=['python27'] ) -def get_interface(operation_name, - operation_kwargs=None, - interface_kwargs=None, - edge=None): - operation = model.Operation(name=operation_name, **(operation_kwargs or {})) - interface_name = operation_name.rsplit('.', 1)[0] - return model.Interface(operations=[operation], - name=interface_name, - edge=edge, - **(interface_kwargs or {})) +def _dictify(item): + return dict(((item.name, item),)) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/mock/operations.py ---------------------------------------------------------------------- diff --git a/tests/mock/operations.py b/tests/mock/operations.py index 5495f6a..c752a8e 100644 --- a/tests/mock/operations.py +++ b/tests/mock/operations.py @@ -14,46 +14,46 @@ # limitations under the License. NODE_OPERATIONS_INSTALL = [ - 'tosca.interfaces.node.lifecycle.Standard.create', - 'tosca.interfaces.node.lifecycle.Standard.configure', - 'tosca.interfaces.node.lifecycle.Standard.start', + ('Standard', 'create'), + ('Standard', 'configure'), + ('Standard', 'start') ] NODE_OPERATIONS_UNINSTALL = [ - 'tosca.interfaces.node.lifecycle.Standard.stop', - 'tosca.interfaces.node.lifecycle.Standard.delete', + ('Standard', 'stop'), + ('Standard', 'delete') ] NODE_OPERATIONS = NODE_OPERATIONS_INSTALL + NODE_OPERATIONS_UNINSTALL RELATIONSHIP_OPERATIONS_INSTALL = [ - 'tosca.interfaces.relationship.Configure.pre_configure_source', - 'tosca.interfaces.relationship.Configure.pre_configure_target', - 'tosca.interfaces.relationship.Configure.add_source', - 'tosca.interfaces.relationship.Configure.add_target', + ('Configure', 'pre_configure_source'), + ('Configure', 'pre_configure_target'), + ('Configure', 'add_source'), + ('Configure', 'add_target') ] RELATIONSHIP_OPERATIONS_UNINSTALL = [ - 'tosca.interfaces.relationship.Configure.remove_target', - 'tosca.interfaces.relationship.Configure.target_changed', + ('Configure', 'remove_target'), + ('Configure', 'target_changed') ] RELATIONSHIP_OPERATIONS = RELATIONSHIP_OPERATIONS_INSTALL + RELATIONSHIP_OPERATIONS_UNINSTALL OPERATIONS_INSTALL = [ - 'tosca.interfaces.node.lifecycle.Standard.create', - 'tosca.interfaces.relationship.Configure.pre_configure_source', - 'tosca.interfaces.relationship.Configure.pre_configure_target', - 'tosca.interfaces.node.lifecycle.Standard.configure', - 'tosca.interfaces.node.lifecycle.Standard.start', - 'tosca.interfaces.relationship.Configure.add_source', - 'tosca.interfaces.relationship.Configure.add_target', - 'tosca.interfaces.relationship.Configure.target_changed', + ('Standard', 'create'), + ('Configure', 'pre_configure_source'), + ('Configure', 'pre_configure_target'), + ('Standard', 'configure'), + ('Standard', 'start'), + ('Configure', 'add_source'), + ('Configure', 'add_target'), + ('Configure', 'target_changed') ] OPERATIONS_UNINSTALL = [ - 'tosca.interfaces.relationship.Configure.remove_target', - 'tosca.interfaces.relationship.Configure.target_changed', - 'tosca.interfaces.node.lifecycle.Standard.stop', - 'tosca.interfaces.node.lifecycle.Standard.delete', + ('Configure', 'remove_target'), + ('Configure', 'target_changed'), + ('Standard', 'stop'), + ('Standard', 'delete') ] http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/mock/topology.py ---------------------------------------------------------------------- diff --git a/tests/mock/topology.py b/tests/mock/topology.py index d3e8b7b..7ccc885 100644 --- a/tests/mock/topology.py +++ b/tests/mock/topology.py @@ -13,74 +13,60 @@ # See the License for the specific language governing permissions and # limitations under the License. -from aria.storage.modeling import model +from aria.modeling import models as aria_models from . import models def create_simple_topology_single_node(model_storage, create_operation): - service_template = models.get_blueprint() - model_storage.service_template.put(service_template) - - service_instance = models.get_deployment(service_template) - model_storage.service_instance.put(service_instance) + service_template = models.create_service_template() + service = models.create_service(service_template) - node_template = models.get_dependency_node(service_instance) - node_template.interface_templates = [models.get_interface_template( - 'tosca.interfaces.node.lifecycle.Standard.create', + node_template = models.create_dependency_node_template(service_template) + interface_template = models.create_interface_template( + service_template, + 'Standard', 'create', operation_kwargs=dict( implementation=create_operation, - inputs=[model.Parameter(name='key', str_value='create', type='str'), - model.Parameter(name='value', str_value=str(True), type='bool')] - ) - )] - model_storage.node_template.put(node_template) + inputs={'key': aria_models.Parameter.wrap('key', 'create'), + 'value': aria_models.Parameter.wrap('value', True)}) + ) + node_template.interface_templates[interface_template.name] = interface_template # pylint: disable=unsubscriptable-object - node = models.get_dependency_node_instance(node_template, service_instance) - node.interfaces = [models.get_interface( - 'tosca.interfaces.node.lifecycle.Standard.create', + node = models.create_dependency_node(node_template, service) + interface = models.create_interface( + service, + 'Standard', 'create', operation_kwargs=dict( implementation=create_operation, - inputs=[model.Parameter(name='key', str_value='create', type='str'), - model.Parameter(name='value', str_value=str(True), type='bool')]) - )] - model_storage.node.put(node) - + inputs={'key': aria_models.Parameter.wrap('key', 'create'), + 'value': aria_models.Parameter.wrap('value', True)}) + ) + node.interfaces[interface.name] = interface # pylint: disable=unsubscriptable-object -def create_simple_topology_two_nodes(model_storage): - blueprint = models.get_blueprint() - model_storage.service_template.put(blueprint) - deployment = models.get_deployment(blueprint) - model_storage.service_instance.put(deployment) + model_storage.service_template.put(service_template) + model_storage.service.put(service) - ################################################################################# - # Creating a simple deployment with node -> node as a graph - dependency_node = models.get_dependency_node(deployment) - model_storage.node_template.put(dependency_node) - storage_dependency_node = model_storage.node_template.get(dependency_node.id) +def create_simple_topology_two_nodes(model_storage): + service_template = models.create_service_template() + service = models.create_service(service_template) - dependency_node_instance = models.get_dependency_node_instance(storage_dependency_node, - deployment) - model_storage.node.put(dependency_node_instance) - storage_dependency_node_instance = model_storage.node.get(dependency_node_instance.id) + # Creating a simple service with node -> node as a graph - req_template, cap_template = models.get_relationship(storage_dependency_node) - model_storage.requirement_template.put(req_template) - model_storage.capability_template.put(cap_template) + dependency_node_template = models.create_dependency_node_template(service_template) + dependent_node_template = models.create_dependent_node_template(service_template, + dependency_node_template) - dependent_node = models.get_dependent_node(deployment, req_template, cap_template) - model_storage.node_template.put(dependent_node) - storage_dependent_node = model_storage.node_template.get(dependent_node.id) + dependency_node = models.create_dependency_node(dependency_node_template, service) + dependent_node = models.create_dependent_node(dependent_node_template, service) - dependent_node_instance = models.get_dependent_node_instance(storage_dependent_node, deployment) - model_storage.node.put(dependent_node_instance) - storage_dependent_node_instance = model_storage.node.get(dependent_node_instance.id) + dependent_node.outbound_relationships.append(models.create_relationship( # pylint: disable=no-member + source=dependent_node, + target=dependency_node + )) - relationship_instance = models.get_relationship_instance( - target_instance=storage_dependency_node_instance, - source_instance=storage_dependent_node_instance - ) - model_storage.relationship.put(relationship_instance) + model_storage.service_template.put(service_template) + model_storage.service.put(service) - return deployment.id + return service.id http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/modeling/__init__.py ---------------------------------------------------------------------- diff --git a/tests/modeling/__init__.py b/tests/modeling/__init__.py new file mode 100644 index 0000000..072ef54 --- /dev/null +++ b/tests/modeling/__init__.py @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sqlalchemy import ( + Column, + Text, + Integer, +) + +from aria.modeling import ( + models, + types as modeling_types, + mixins +) + + +class MockModel(models.aria_declarative_base, mixins.ModelMixin): #pylint: disable=abstract-method + __tablename__ = 'mock_model' + model_dict = Column(modeling_types.Dict) + model_list = Column(modeling_types.List) + value = Column(Integer) + name = Column(Text) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/modeling/test_mixins.py ---------------------------------------------------------------------- diff --git a/tests/modeling/test_mixins.py b/tests/modeling/test_mixins.py new file mode 100644 index 0000000..7795b57 --- /dev/null +++ b/tests/modeling/test_mixins.py @@ -0,0 +1,219 @@ +# 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 + +import sqlalchemy + +from aria.storage import ( + ModelStorage, + sql_mapi +) +from aria import modeling +from aria.modeling.exceptions import ValueFormatException + +from ..storage import ( + release_sqlite_storage, + init_inmemory_model_storage +) +from . import MockModel +from ..mock import ( + models, + context as mock_context +) + + [email protected] +def storage(): + base_storage = ModelStorage(sql_mapi.SQLAlchemyModelAPI, + initiator=init_inmemory_model_storage) + base_storage.register(MockModel) + yield base_storage + release_sqlite_storage(base_storage) + + [email protected](scope='module', autouse=True) +def module_cleanup(): + modeling.models.aria_declarative_base.metadata.remove(MockModel.__table__) # pylint: disable=no-member + + [email protected] +def context(tmpdir): + ctx = mock_context.simple(str(tmpdir)) + yield ctx + release_sqlite_storage(ctx.model) + + +def test_inner_dict_update(storage): + inner_dict = {'inner_value': 1} + + mock_model = MockModel(model_dict={'inner_dict': inner_dict, 'value': 0}) + storage.mock_model.put(mock_model) + + storage_mm = storage.mock_model.get(mock_model.id) + assert storage_mm == mock_model + + storage_mm.model_dict['inner_dict']['inner_value'] = 2 + storage_mm.model_dict['value'] = -1 + storage.mock_model.update(storage_mm) + storage_mm = storage.mock_model.get(storage_mm.id) + + assert storage_mm.model_dict['inner_dict']['inner_value'] == 2 + assert storage_mm.model_dict['value'] == -1 + + +def test_inner_list_update(storage): + mock_model = MockModel(model_list=[0, [1]]) + storage.mock_model.put(mock_model) + + storage_mm = storage.mock_model.get(mock_model.id) + assert storage_mm == mock_model + + storage_mm.model_list[1][0] = 'new_inner_value' + storage_mm.model_list[0] = 'new_value' + storage.mock_model.update(storage_mm) + storage_mm = storage.mock_model.get(storage_mm.id) + + assert storage_mm.model_list[1][0] == 'new_inner_value' + assert storage_mm.model_list[0] == 'new_value' + + +def test_model_to_dict(context): + service = context.service + service = service.to_dict() + + expected_keys = [ + 'description', + 'created_at', + 'permalink', + 'scaling_groups', + 'updated_at' + ] + + for expected_key in expected_keys: + assert expected_key in service + + +def test_relationship_model_ordering(context): + service = context.model.service.get_by_name(models.SERVICE_NAME) + source_node = context.model.node.get_by_name(models.DEPENDENT_NODE_NAME) + target_node = context.model.node.get_by_name(models.DEPENDENCY_NODE_NAME) + + new_node_template = modeling.models.NodeTemplate( + name='new_node_template', + type=source_node.type, + default_instances=1, + min_instances=1, + max_instances=1, + service_template=service.service_template + ) + + new_node = modeling.models.Node( + name='new_node', + type=source_node.type, + runtime_properties={}, + service=service, + version=None, + node_template=new_node_template, + state='', + scaling_groups=[] + ) + + source_node.outbound_relationships.append(modeling.models.Relationship( + source_node=source_node, + target_node=new_node, + )) + + new_node.outbound_relationships.append(modeling.models.Relationship( # pylint: disable=no-member + source_node=new_node, + target_node=target_node, + )) + + context.model.node_template.put(new_node_template) + context.model.node.put(new_node) + context.model.node.refresh(source_node) + context.model.node.refresh(target_node) + + def flip_and_assert(node, direction): + """ + Reversed the order of relationships and assert effects took place. + :param node: the node instance to operate on + :param direction: the type of relationships to flip (inbound/outbound) + :return: + """ + assert direction in ('inbound', 'outbound') + + relationships = getattr(node, direction + '_relationships') + assert len(relationships) == 2 + + reversed_relationship = list(reversed(relationships)) + assert relationships != reversed_relationship + + relationships[:] = reversed_relationship + context.model.node.update(node) + assert relationships == reversed_relationship + + flip_and_assert(source_node, 'outbound') + flip_and_assert(target_node, 'inbound') + + +class StrictClass(modeling.models.aria_declarative_base, modeling.mixins.ModelMixin): + __tablename__ = 'strict_class' + + strict_dict = sqlalchemy.Column(modeling.types.StrictDict(basestring, basestring)) + strict_list = sqlalchemy.Column(modeling.types.StrictList(basestring)) + + +def test_strict_dict(): + + strict_class = StrictClass() + + def assert_strict(sc): + with pytest.raises(ValueFormatException): + sc.strict_dict = {'key': 1} + + with pytest.raises(ValueFormatException): + sc.strict_dict = {1: 'value'} + + with pytest.raises(ValueFormatException): + sc.strict_dict = {1: 1} + + assert_strict(strict_class) + strict_class.strict_dict = {'key': 'value'} + assert strict_class.strict_dict == {'key': 'value'} + + assert_strict(strict_class) + with pytest.raises(ValueFormatException): + strict_class.strict_dict['key'] = 1 + with pytest.raises(ValueFormatException): + strict_class.strict_dict[1] = 'value' + with pytest.raises(ValueFormatException): + strict_class.strict_dict[1] = 1 + + +def test_strict_list(): + strict_class = StrictClass() + + def assert_strict(sc): + with pytest.raises(ValueFormatException): + sc.strict_list = [1] + + assert_strict(strict_class) + strict_class.strict_list = ['item'] + assert strict_class.strict_list == ['item'] + + assert_strict(strict_class) + with pytest.raises(ValueFormatException): + strict_class.strict_list[0] = 1 http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9841ca4a/tests/modeling/test_model_storage.py ---------------------------------------------------------------------- diff --git a/tests/modeling/test_model_storage.py b/tests/modeling/test_model_storage.py new file mode 100644 index 0000000..bb778d4 --- /dev/null +++ b/tests/modeling/test_model_storage.py @@ -0,0 +1,102 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from aria.storage import ( + ModelStorage, + exceptions, + sql_mapi +) +from aria import (application_model_storage, modeling) +from ..storage import (release_sqlite_storage, init_inmemory_model_storage) + +from . import MockModel + + [email protected] +def storage(): + base_storage = ModelStorage(sql_mapi.SQLAlchemyModelAPI, + initiator=init_inmemory_model_storage) + base_storage.register(MockModel) + yield base_storage + release_sqlite_storage(base_storage) + + [email protected](scope='module', autouse=True) +def module_cleanup(): + modeling.models.aria_declarative_base.metadata.remove(MockModel.__table__) #pylint: disable=no-member + + +def test_storage_base(storage): + with pytest.raises(AttributeError): + storage.non_existent_attribute() + + +def test_model_storage(storage): + mock_model = MockModel(value=0, name='model_name') + storage.mock_model.put(mock_model) + + assert storage.mock_model.get_by_name('model_name') == mock_model + + assert [mm_from_storage for mm_from_storage in storage.mock_model.iter()] == [mock_model] + assert [mm_from_storage for mm_from_storage in storage.mock_model] == [mock_model] + + storage.mock_model.delete(mock_model) + with pytest.raises(exceptions.StorageError): + storage.mock_model.get(mock_model.id) + + +def test_application_storage_factory(): + storage = application_model_storage(sql_mapi.SQLAlchemyModelAPI, + initiator=init_inmemory_model_storage) + + assert storage.service_template + assert storage.node_template + assert storage.group_template + assert storage.policy_template + assert storage.substitution_template + assert storage.substitution_template_mapping + assert storage.requirement_template + assert storage.relationship_template + assert storage.capability_template + assert storage.interface_template + assert storage.operation_template + assert storage.artifact_template + + assert storage.service + assert storage.node + assert storage.group + assert storage.policy + assert storage.substitution + assert storage.substitution_mapping + assert storage.relationship + assert storage.capability + assert storage.interface + assert storage.operation + assert storage.artifact + + assert storage.execution + assert storage.service_update + assert storage.service_update_step + assert storage.service_modification + assert storage.plugin + assert storage.task + + assert storage.parameter + assert storage.type + assert storage.metadata + + release_sqlite_storage(storage)
