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)


Reply via email to