Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-3-api-for-creating-workflows c4c7a0fd4 -> d4247cf0d
ARIA-5-Adapt-workflow-API-users-to-modified-API(added tests and code fixes) Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/d4247cf0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/d4247cf0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/d4247cf0 Branch: refs/heads/ARIA-3-api-for-creating-workflows Commit: d4247cf0dd91b6fa6f77b251f7e96c808eb642c0 Parents: c4c7a0f Author: mxmrlv <mxm...@gmail.com> Authored: Wed Oct 26 12:07:53 2016 +0300 Committer: mxmrlv <mxm...@gmail.com> Committed: Wed Oct 26 12:46:16 2016 +0300 ---------------------------------------------------------------------- aria/workflows/api/task_graph.py | 2 +- aria/workflows/builtin/execute_operation.py | 7 +- aria/workflows/builtin/heal.py | 88 ++++----- aria/workflows/builtin/install.py | 8 +- aria/workflows/builtin/workflows.py | 73 ++++---- aria/workflows/core/translation.py | 2 +- tests/workflows/builtin/__init__.py | 177 +++++++++++++++++++ .../workflows/builtin/test_execute_operation.py | 45 +++++ tests/workflows/builtin/test_heal.py | 82 +++++++++ tests/workflows/builtin/test_install.py | 36 ++++ tests/workflows/builtin/test_uninstall.py | 36 ++++ 11 files changed, 458 insertions(+), 98 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/api/task_graph.py ---------------------------------------------------------------------- diff --git a/aria/workflows/api/task_graph.py b/aria/workflows/api/task_graph.py index ec0c4a5..9c138e0 100644 --- a/aria/workflows/api/task_graph.py +++ b/aria/workflows/api/task_graph.py @@ -63,7 +63,7 @@ class TaskGraph(object): """ return self._id - def topological_sort(self, reverse=False): + def topological_order(self, reverse=False): """ Returns topological sort on the graph :param reverse: whether to reverse the sort http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/builtin/execute_operation.py ---------------------------------------------------------------------- diff --git a/aria/workflows/builtin/execute_operation.py b/aria/workflows/builtin/execute_operation.py index 9e87c30..a664904 100644 --- a/aria/workflows/builtin/execute_operation.py +++ b/aria/workflows/builtin/execute_operation.py @@ -67,14 +67,13 @@ def execute_operation( # registering actual tasks to sequences for node_instance in filtered_node_instances: - node_instance_sub_workflow = execute_operation_on_instance( + execute_operation_on_instance( context=context, graph=graph, node_instance=node_instance, operation=operation, operation_kwargs=operation_kwargs, allow_kwargs_override=allow_kwargs_override) - subgraphs[node_instance.id] = node_instance_sub_workflow for _, node_instance_sub_workflow in subgraphs.items(): graph.add_task(node_instance_sub_workflow) @@ -83,8 +82,8 @@ def execute_operation( if run_by_dependency_order: for node_instance in context.node_instances: for relationship_instance in node_instance.relationship_instances: - graph.dependency(source_task=subgraphs[node_instance.id], - after=[subgraphs[relationship_instance.target_id]]) + graph.add_dependency(source_task=subgraphs[node_instance.id], + after=[subgraphs[relationship_instance.target_id]]) def _filter_node_instances(context, node_ids=(), node_instance_ids=(), type_names=()): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/builtin/heal.py ---------------------------------------------------------------------- diff --git a/aria/workflows/builtin/heal.py b/aria/workflows/builtin/heal.py index 9a31fd6..b9c7f8e 100644 --- a/aria/workflows/builtin/heal.py +++ b/aria/workflows/builtin/heal.py @@ -34,28 +34,27 @@ def heal(context, graph, node_instance_id): :param node_instance_id: the id of the node instance to heal :return: """ - failing_node = context.storage.node_instance.get(node_instance_id) - host_node = context.storage.node_instance.get(failing_node.host_id) + failing_node = context.model.node_instance.get(node_instance_id) + host_node = context.model.node_instance.get(failing_node.host_id) failed_node_instance_subgraph = _get_contained_subgraph(context, host_node) failed_node_instance_ids = list(n.id for n in failed_node_instance_subgraph) - targeted_node_instances = [ - context.storage.node_instance.get(relationship_instance.target_id) - for node_instance in failed_node_instance_subgraph - for relationship_instance in node_instance.relationship_instances - if relationship_instance.target_id not in failed_node_instance_ids - ] - - graph.add_dependency( - heal_uninstall( - context=context, - failing_node_instances=failed_node_instance_subgraph, - targeted_node_instances=targeted_node_instances), - heal_install( - context=context, - failing_node_instances=failed_node_instance_subgraph, - targeted_node_instances=targeted_node_instances) - ) + targeted_node_instances = [node_instance for node_instance in context.node_instances + if node_instance.id not in failed_node_instance_ids] + + uninstall_subgraph = heal_uninstall( + context=context, + failing_node_instances=failed_node_instance_subgraph, + targeted_node_instances=targeted_node_instances) + + install_subgraph = heal_install( + context=context, + failing_node_instances=failed_node_instance_subgraph, + targeted_node_instances=targeted_node_instances) + + graph.add_task(uninstall_subgraph) + graph.add_task(install_subgraph) + graph.add_dependency(install_subgraph, uninstall_subgraph) @workflow(suffix_template='{failing_node_instances}') @@ -85,27 +84,22 @@ def heal_uninstall(context, graph, failing_node_instances, targeted_node_instanc node_instances=failing_node_instances, node_instance_sub_workflows=node_instance_sub_workflows) - # Add operations for intact nodes depending on a node instance - # belonging to node_instances + # Add operations for intact nodes depending on a node instance belonging to node_instances for node_instance in targeted_node_instances: node_instance_sub_workflow = node_instance_sub_workflows[node_instance.id] for relationship_instance in reversed(node_instance.relationship_instances): - target_node_instance = context.storage.node_instance.get( - relationship_instance.target_id) - if target_node_instance in failing_node_instances: - target_node_instances = [node_instance_sub_workflows[relationship.target_id] - for relationship in node_instance.relationship_instances] - dependency = graph.parallel(*target_node_instances) + target_node_instance = context.model.node_instance.get(relationship_instance.target_id) + target_node_instance_subgraph = node_instance_sub_workflows[target_node_instance.id] + graph.add_dependency(target_node_instance_subgraph, node_instance_sub_workflow) - elif target_node_instance in targeted_node_instances: - dependency = relationship_tasks( + if target_node_instance in failing_node_instances: + dependency = graph.parallel(*relationship_tasks( node_instance=node_instance, relationship_instance=relationship_instance, context=context, - operation_name='aria.interfaces.relationship_lifecycle.unlink') + operation_name='aria.interfaces.relationship_lifecycle.unlink')) - if dependency: graph.add_dependency(node_instance_sub_workflow, dependency) @@ -142,36 +136,32 @@ def heal_install(context, graph, failing_node_instances, targeted_node_instances node_instance_sub_workflow = node_instance_sub_workflows[node_instance.id] for relationship_instance in node_instance.relationship_instances: - target_node_instance = context.storage.node_instance.get( - relationship_instance.target_id) - if target_node_instance in failing_node_instances: - target_node_instances = [node_instance_sub_workflows[relationship.target_id] - for relationship in node_instance.relationship_instances] - dependency = graph.parallel(*target_node_instances) + target_node_instance = context.model.node_instance.get(relationship_instance.target_id) + target_node_instance_subgraph = node_instance_sub_workflows[target_node_instance.id] + graph.add_dependency(node_instance_sub_workflow, target_node_instance_subgraph) - elif target_node_instance in targeted_node_instances: - dependency = relationship_tasks( + if target_node_instance in failing_node_instances: + dependent = graph.parallel(*relationship_tasks( node_instance=node_instance, relationship_instance=relationship_instance, context=context, - operation_name='aria.interfaces.relationship_lifecycle.establish') + operation_name='aria.interfaces.relationship_lifecycle.establish')) - if dependency: - graph.dependency(node_instance_sub_workflow, dependency) + graph.add_dependency(dependent, node_instance_sub_workflow) def _get_contained_subgraph(context, host_node_instance): - contained_instances = set(node_instance - for node_instance in context.node_instances - if node_instance.host_id == host_node_instance.id and - node_instance.id != node_instance.host_id) - result = {host_node_instance} + contained_instances = [node_instance + for node_instance in context.node_instances + if node_instance.host_id == host_node_instance.id and + node_instance.id != node_instance.host_id] + result = [host_node_instance] if not contained_instances: return result - result.update(contained_instances) + result.extend(contained_instances) for node_instance in contained_instances: - result.update(_get_contained_subgraph(context, node_instance)) + result.extend(_get_contained_subgraph(context, node_instance)) return result http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/builtin/install.py ---------------------------------------------------------------------- diff --git a/aria/workflows/builtin/install.py b/aria/workflows/builtin/install.py index 3e3ab33..552af90 100644 --- a/aria/workflows/builtin/install.py +++ b/aria/workflows/builtin/install.py @@ -47,6 +47,8 @@ def install(context, graph, node_instances=(), node_instance_sub_workflows=None) # create dependencies between the node instance sub workflow for node_instance in node_instances: node_instance_sub_workflow = node_instance_sub_workflows[node_instance.id] - dependencies = graph.parallel([node_instance_sub_workflows[relationship.target_id] - for relationship in node_instance.relationship_instances]) - graph.add_dependency(node_instance_sub_workflow, dependencies) + if node_instance.relationship_instances: + dependencies = \ + graph.parallel(*(node_instance_sub_workflows[relationship.target_id] + for relationship in node_instance.relationship_instances)) + graph.add_dependency(node_instance_sub_workflow, dependencies) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/builtin/workflows.py ---------------------------------------------------------------------- diff --git a/aria/workflows/builtin/workflows.py b/aria/workflows/builtin/workflows.py index 32c4ee6..5fc9ec8 100644 --- a/aria/workflows/builtin/workflows.py +++ b/aria/workflows/builtin/workflows.py @@ -57,16 +57,21 @@ def install_node_instance(context, graph, node_instance): 'aria.interfaces.lifecycle.start'], node_instance=node_instance ) - graph.sequence(create_node_instance, - preconfigure_relationship(context=context, node_instance=node_instance), - configure_node_instance, - postconfigure_relationship(context=context, node_instance=node_instance), - start_node_instance, - establish_relationship(context=context, node_instance=node_instance)) + preconfigure_operations = preconfigure_relationship(context, node_instance) + postconfigure_operations = postconfigure_relationship(context, node_instance) + establish_operations = establish_relationship(context, node_instance) + install_sequence = [create_node_instance] + install_sequence.extend(preconfigure_operations) + install_sequence.append(configure_node_instance) + install_sequence.extend(postconfigure_operations) + install_sequence.append(start_node_instance) + install_sequence.extend(establish_operations) -@workflow(suffix_template='{node_instance.id}') -def preconfigure_relationship(context, graph, node_instance): + graph.sequence(*install_sequence) + + +def preconfigure_relationship(context, node_instance): """ :param context: @@ -74,14 +79,13 @@ def preconfigure_relationship(context, graph, node_instance): :param node_instance: :return: """ - graph.sequence(*relationships_tasks( + return relationships_tasks( operation_name='aria.interfaces.relationship_lifecycle.preconfigure', context=context, - node_instance=node_instance)) + node_instance=node_instance) -@workflow(suffix_template='{node_instance.id}') -def postconfigure_relationship(context, graph, node_instance): +def postconfigure_relationship(context, node_instance): """ :param context: @@ -89,14 +93,13 @@ def postconfigure_relationship(context, graph, node_instance): :param node_instance: :return: """ - graph.sequence(*relationships_tasks( + return relationships_tasks( operation_name='aria.interfaces.relationship_lifecycle.postconfigure', context=context, - node_instance=node_instance)) + node_instance=node_instance) -@workflow(suffix_template='{node_instance.id}') -def establish_relationship(context, graph, node_instance): +def establish_relationship(context, node_instance): """ :param context: @@ -104,10 +107,10 @@ def establish_relationship(context, graph, node_instance): :param node_instance: :return: """ - graph.sequence(*relationships_tasks( + return relationships_tasks( operation_name='aria.interfaces.relationship_lifecycle.establish', context=context, - node_instance=node_instance)) + node_instance=node_instance) # Uninstall node instance workflow and subworkflows @@ -133,14 +136,15 @@ def uninstall_node_instance(graph, context, node_instance): 'aria.interfaces.lifecycle.delete'], node_instance=node_instance ) + unlink_operations = unlink_relationship(context, node_instance) - graph.sequence(stop_node_instance, - unlink_relationship(context=context, node_instance=node_instance), - delete_node_instance) + uninstall_sequence = [stop_node_instance] + uninstall_sequence.extend(unlink_operations) + uninstall_sequence.append(delete_node_instance) + graph.sequence(*uninstall_sequence) -@workflow(suffix_template='{node_instance.id}') -def unlink_relationship(context, graph, node_instance): +def unlink_relationship(context, node_instance): """ :param context: @@ -148,13 +152,11 @@ def unlink_relationship(context, graph, node_instance): :param node_instance: :return: """ - tasks = relationships_tasks( + return relationships_tasks( operation_name='aria.interfaces.relationship_lifecycle.unlink', context=context, node_instance=node_instance ) - graph.sequence(*tasks) - return tasks @workflow(suffix_template='{node_instance.id}.{operation}') @@ -188,7 +190,7 @@ def execute_operation_on_instance( name=task_name, operation_details=node_instance.node.operations[operation], node_instance=node_instance, - parameters=operation_kwargs) + inputs=operation_kwargs) ) @@ -207,13 +209,13 @@ def relationships_tasks(operation_name, context, node_instance): sub_tasks = [] for index, (_, relationship_group) in enumerate(relationships_groups): for relationship_instance in relationship_group: - relationship_subgraph = relationship_tasks( + relationship_operations = relationship_tasks( node_instance=node_instance, relationship_instance=relationship_instance, context=context, operation_name=operation_name, index=index) - sub_tasks.append(relationship_subgraph) + sub_tasks.extend(relationship_operations) return sub_tasks @@ -228,11 +230,6 @@ def relationship_tasks(node_instance, relationship_instance, context, operation_ :return: """ index = index or node_instance.relationship_instances.index(relationship_instance) - sub_workflow_name = '{name}.{index}.{node_instance.id}'.format( - name=operation_name, - index=index, - node_instance=node_instance, - ) operation_name_template = '{name}.{index}.{{0}}.<{source_id}, {target_id}>'.format( name=operation_name, index=index, @@ -246,11 +243,7 @@ def relationship_tasks(node_instance, relationship_instance, context, operation_ operation_name]) target_operation = context.operation( name=operation_name_template.format('target'), - node_instance=context.storage.node_instance.get( - relationship_instance.target_id), + node_instance=context.model.node_instance.get(relationship_instance.target_id), operation_details=relationship_instance.relationship.target_operations[ operation_name]) - sub_graph = context.task_graph(name=sub_workflow_name) - sub_graph.add_task(source_operation) - sub_graph.add_task(target_operation) - return sub_graph + return source_operation, target_operation http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/aria/workflows/core/translation.py ---------------------------------------------------------------------- diff --git a/aria/workflows/core/translation.py b/aria/workflows/core/translation.py index 307c782..451e4e3 100644 --- a/aria/workflows/core/translation.py +++ b/aria/workflows/core/translation.py @@ -44,7 +44,7 @@ def build_execution_graph( context=workflow_context) _add_task_and_dependencies(execution_graph, start_task, depends_on) - for task in task_graph.topological_sort(reverse=True): + for task in task_graph.topological_order(reverse=True): dependencies = task_graph.get_task_dependencies(task) operation_dependencies = _get_tasks_from_dependencies( execution_graph, http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/tests/workflows/builtin/__init__.py ---------------------------------------------------------------------- diff --git a/tests/workflows/builtin/__init__.py b/tests/workflows/builtin/__init__.py new file mode 100644 index 0000000..d73d6ee --- /dev/null +++ b/tests/workflows/builtin/__init__.py @@ -0,0 +1,177 @@ +# 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 import contexts +from aria.storage import ModelStorage, models + +from ...storage import InMemoryModelDriver + +NODE_OPERATIONS_INSTALL = [ + 'aria.interfaces.lifecycle.create', + 'aria.interfaces.lifecycle.configure', + 'aria.interfaces.lifecycle.start', + ] +NODE_OPERATIONS_UNINSTALL = [ + 'aria.interfaces.lifecycle.stop', + 'aria.interfaces.lifecycle.delete', +] +NODE_OPERATIONS = NODE_OPERATIONS_INSTALL + NODE_OPERATIONS_UNINSTALL + +RELATIONSHIP_OPERATIONS_INSTALL = [ + 'aria.interfaces.relationship_lifecycle.preconfigure', + 'aria.interfaces.relationship_lifecycle.postconfigure', + 'aria.interfaces.relationship_lifecycle.establish', + ] +RELATIONSHIP_OPERATIONS_UNINSTALL = ['aria.interfaces.relationship_lifecycle.unlink'] +RELATIONSHIP_OPERATIONS = RELATIONSHIP_OPERATIONS_INSTALL + RELATIONSHIP_OPERATIONS_UNINSTALL + + +def simple_context(): + """ + Create the following graph in storage: + dependency_node <------ dependent_node + :return: + """ + + storage = ModelStorage(InMemoryModelDriver(), + model_classes=[models.NodeInstance, + models.Node, + models.Relationship, + models.RelationshipInstance]) + storage.setup() + + dependency_node = models.Node( + id='dependency_node', + host_id='dependency_node', + blueprint_id='test_blueprint_id', + type='test_node_type', + type_hierarchy=[], + number_of_instances=1, + planned_number_of_instances=1, + deploy_number_of_instances=1, + properties={}, + operations=dict((key, None) for key in NODE_OPERATIONS), + relationships=[], + min_number_of_instances=1, + max_number_of_instances=1, + ) + + dependency_node_instance = models.NodeInstance( + id='dependency_node_instance', + host_id='dependency_node_instance', + deployment_id='test_deployment_id', + runtime_properties={}, + version=None, + relationship_instances=[], + node=dependency_node + ) + + relationship = models.Relationship( + target_id=dependency_node.id, + source_interfaces={}, + source_operations=dict((key, None) for key in RELATIONSHIP_OPERATIONS), + target_interfaces={}, + target_operations=dict((key, None) for key in RELATIONSHIP_OPERATIONS), + type='rel_type', + type_hierarchy=[], + properties={}, + ) + + relationship_instance = models.RelationshipInstance( + target_id=dependency_node_instance.id, + target_name='test_target_name', + type='some_type', + relationship=relationship, + + ) + + dependent_node = models.Node( + id='dependent_node', + host_id='dependent_node', + blueprint_id='test_blueprint_id', + type='test_node_type', + type_hierarchy=[], + number_of_instances=1, + planned_number_of_instances=1, + deploy_number_of_instances=1, + properties={}, + operations=dict((key, None) for key in NODE_OPERATIONS), + relationships=[relationship], + min_number_of_instances=1, + max_number_of_instances=1, + ) + + dependent_node_instance = models.NodeInstance( + id='dependent_node_instance', + host_id='dependent_node_instance', + deployment_id='test_deployment_id', + runtime_properties={}, + version=None, + relationship_instances=[relationship_instance], + node=dependent_node + ) + + storage.node.store(dependency_node) + storage.node.store(dependent_node) + storage.node_instance.store(dependency_node_instance) + storage.node_instance.store(dependent_node_instance) + storage.relationship.store(relationship) + storage.relationship_instance.store(relationship_instance) + + wf_context = contexts.WorkflowContext(name='test_context', + model_storage=storage, + resource_storage=None, + deployment_id='test_deployment_id', + workflow_id='test_workflow_id') + return wf_context + + +def assert_node_install_operations(operations, with_operations=False): + if with_operations: + all_operations = [ + 'aria.interfaces.lifecycle.create', + 'aria.interfaces.relationship_lifecycle.preconfigure.0.source', + 'aria.interfaces.relationship_lifecycle.preconfigure.0.target', + 'aria.interfaces.lifecycle.configure', + 'aria.interfaces.relationship_lifecycle.postconfigure.0.source', + 'aria.interfaces.relationship_lifecycle.postconfigure.0.target', + 'aria.interfaces.lifecycle.start', + 'aria.interfaces.relationship_lifecycle.establish.0.source', + 'aria.interfaces.relationship_lifecycle.establish.0.target', + ] + + for i, operation in enumerate(operations): + assert operation.name.startswith(all_operations[i]) + else: + for i, operation in enumerate(operations): + assert operation.name.startswith(NODE_OPERATIONS_INSTALL[i]) + + +def assert_node_uninstall_operations(operations, with_relationships=False): + if with_relationships: + all_operations = [ + 'aria.interfaces.lifecycle.stop', + 'aria.interfaces.relationship_lifecycle.unlink.0.source', + 'aria.interfaces.relationship_lifecycle.unlink.0.target', + 'aria.interfaces.lifecycle.delete', + ] + + for i, operation in enumerate(operations): + assert operation.name.startswith(all_operations[i]) + else: + for i, operation in enumerate(operations): + assert operation.name.startswith(NODE_OPERATIONS_UNINSTALL[i]) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/tests/workflows/builtin/test_execute_operation.py ---------------------------------------------------------------------- diff --git a/tests/workflows/builtin/test_execute_operation.py b/tests/workflows/builtin/test_execute_operation.py new file mode 100644 index 0000000..457a569 --- /dev/null +++ b/tests/workflows/builtin/test_execute_operation.py @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from aria.workflows.builtin.execute_operation import execute_operation + +from . import simple_context, NODE_OPERATIONS_INSTALL + + +@pytest.fixture +def context(): + return simple_context() + + +def test_execute_operation(context): + operation_name = NODE_OPERATIONS_INSTALL[0] + node_instance_id = 'dependency_node_instance' + execute_operations = list(execute_operation( + context=context, + operation=operation_name, + operation_kwargs={}, + allow_kwargs_override=False, + run_by_dependency_order=False, + type_names=[], + node_ids=[], + node_instance_ids=[node_instance_id] + ).topological_order()) + + assert len(execute_operations) == 1 + assert execute_operations[0].name == '{0}.{1}'.format(node_instance_id, operation_name) + +# TODO: add more scenarios http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/tests/workflows/builtin/test_heal.py ---------------------------------------------------------------------- diff --git a/tests/workflows/builtin/test_heal.py b/tests/workflows/builtin/test_heal.py new file mode 100644 index 0000000..8cea941 --- /dev/null +++ b/tests/workflows/builtin/test_heal.py @@ -0,0 +1,82 @@ +# 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.workflows.builtin.heal import heal + +from . import (simple_context, + assert_node_install_operations, + assert_node_uninstall_operations) + + +@pytest.fixture +def context(): + return simple_context() + + +def test_heal_dependent_node(context): + heal_graph = heal(context=context, node_instance_id='dependent_node_instance') + uninstall_subgraph, install_subgraph = list(heal_graph.topological_order(reverse=True)) + dependent_node_subgraph_uninstall, dependency_node_subgraph_uninstall = \ + list(uninstall_subgraph.topological_order(reverse=True)) + dependency_node_subgraph_install, dependent_node_subgraph_install = \ + list(install_subgraph.topological_order(reverse=True)) + + dependent_node_uninstall_operations = \ + list(dependent_node_subgraph_uninstall.topological_order(reverse=True)) + dependency_node_uninstall_operations = \ + list(dependency_node_subgraph_uninstall.topological_order(reverse=True)) + dependent_node_install_operations = \ + list(dependent_node_subgraph_install.topological_order(reverse=True)) + dependency_node_install_operations = \ + list(dependency_node_subgraph_install.topological_order(reverse=True)) + + assert_node_uninstall_operations(dependent_node_uninstall_operations, with_relationships=True) + assert len(dependency_node_uninstall_operations) == 0 + + assert len(dependency_node_install_operations) == 0 + assert_node_install_operations(dependent_node_install_operations, with_operations=True) + + +def test_heal_dependency_node(context): + heal_graph = heal(context=context, node_instance_id='dependency_node_instance') + uninstall_subgraph, install_subgraph = list(heal_graph.topological_order(reverse=True)) + + uninstall_operations = list(uninstall_subgraph.topological_order(reverse=True)) + unlink_source, unlink_target = uninstall_operations[:2] + dependent_node_subgraph_uninstall, dependency_node_subgraph_uninstall = uninstall_operations[2:] + + install_operations = list(install_subgraph.topological_order(reverse=True)) + dependency_node_subgraph_install, dependent_node_subgraph_install = install_operations[:2] + establish_source, establish_target = install_operations[2:] + + assert len(list(dependent_node_subgraph_uninstall.tasks)) == 0 + dependency_node_uninstall_operations = \ + list(dependency_node_subgraph_uninstall.topological_order(reverse=True)) + assert len(list(dependent_node_subgraph_install.tasks)) == 0 + dependency_node_install_operations = \ + list(dependency_node_subgraph_install.topological_order(reverse=True)) + + assert unlink_source.name.startswith('aria.interfaces.relationship_lifecycle.unlink') + assert unlink_target.name.startswith('aria.interfaces.relationship_lifecycle.unlink') + assert_node_uninstall_operations(dependency_node_uninstall_operations) + + assert_node_install_operations(dependency_node_install_operations) + assert establish_source.name.startswith('aria.interfaces.relationship_lifecycle.establish') + assert establish_target.name.startswith('aria.interfaces.relationship_lifecycle.establish') + + +# TODO: add tests for contained in scenario http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/tests/workflows/builtin/test_install.py ---------------------------------------------------------------------- diff --git a/tests/workflows/builtin/test_install.py b/tests/workflows/builtin/test_install.py new file mode 100644 index 0000000..4cbc1dc --- /dev/null +++ b/tests/workflows/builtin/test_install.py @@ -0,0 +1,36 @@ +# 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.workflows.builtin.install import install + +from . import simple_context, assert_node_install_operations + + +@pytest.fixture +def context(): + return simple_context() + + +def test_install(context): + install_operations = install(context=context).topological_order(reverse=True) + + dependency_node_subgraph, dependent_node_subgraph = list(install_operations) + dependent_node_operations = list(dependent_node_subgraph.topological_order(reverse=True)) + dependency_node_operations = list(dependency_node_subgraph.topological_order(reverse=True)) + + assert_node_install_operations(dependency_node_operations) + assert_node_install_operations(dependent_node_operations, with_operations=True) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/d4247cf0/tests/workflows/builtin/test_uninstall.py ---------------------------------------------------------------------- diff --git a/tests/workflows/builtin/test_uninstall.py b/tests/workflows/builtin/test_uninstall.py new file mode 100644 index 0000000..ed4666d --- /dev/null +++ b/tests/workflows/builtin/test_uninstall.py @@ -0,0 +1,36 @@ +# 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.workflows.builtin.uninstall import uninstall + +from . import simple_context, assert_node_uninstall_operations + + +@pytest.fixture +def context(): + return simple_context() + + +def test_uninstall(context): + uninstall_operations = uninstall(context=context).topological_order(reverse=True) + + dependent_node_subgraph, dependency_node_subgraph = list(uninstall_operations) + dependent_node_operations = list(dependent_node_subgraph.topological_order(reverse=True)) + dependency_node_operations = list(dependency_node_subgraph.topological_order(reverse=True)) + + assert_node_uninstall_operations(operations=dependency_node_operations) + assert_node_uninstall_operations(operations=dependent_node_operations, with_relationships=True)