Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-3-api-for-creating-workflows d4247cf0d -> 137e80cb3 (forced 
update)


ARIA-5-Adapt-workflow-API-users-to-modified-API


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/137e80cb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/137e80cb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/137e80cb

Branch: refs/heads/ARIA-3-api-for-creating-workflows
Commit: 137e80cb3fb00ce2a670b3cf0769ae1aa5789d5f
Parents: 0bdfbcb
Author: mxmrlv <mxm...@gmail.com>
Authored: Sun Oct 23 20:13:44 2016 +0300
Committer: mxmrlv <mxm...@gmail.com>
Committed: Wed Oct 26 12:56:44 2016 +0300

----------------------------------------------------------------------
 aria/workflows/api/task_graph.py                |  19 +-
 aria/workflows/builtin/execute_operation.py     |   7 +-
 aria/workflows/builtin/heal.py                  |  88 +++++----
 aria/workflows/builtin/install.py               |  10 +-
 aria/workflows/builtin/uninstall.py             |   5 +-
 aria/workflows/builtin/workflows.py             |  77 ++++----
 aria/workflows/core/translation.py              |  19 +-
 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 ++++
 .../test_task_graph_into_exececution_graph.py   |  18 +-
 13 files changed, 498 insertions(+), 121 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/137e80cb/aria/workflows/api/task_graph.py
----------------------------------------------------------------------
diff --git a/aria/workflows/api/task_graph.py b/aria/workflows/api/task_graph.py
index fdc4e2b..9c138e0 100644
--- a/aria/workflows/api/task_graph.py
+++ b/aria/workflows/api/task_graph.py
@@ -19,7 +19,7 @@ Task graph. Used by users to build workflows
 
 from uuid import uuid4
 
-from networkx import DiGraph
+from networkx import DiGraph, topological_sort
 
 
 class TaskNotInGraphError(Exception):
@@ -55,6 +55,23 @@ class TaskGraph(object):
         for _, data in self._graph.nodes_iter(data=True):
             yield data['task']
 
+    @property
+    def id(self):
+        """
+        Represents the id of the graph
+        :return: graph id
+        """
+        return self._id
+
+    def topological_order(self, reverse=False):
+        """
+        Returns topological sort on the graph
+        :param reverse: whether to reverse the sort
+        :return: a list which represents the topological sort
+        """
+        for task_id in topological_sort(self._graph, reverse=reverse):
+            yield self.get_task(task_id)
+
     def get_task_dependencies(self, dependent_task):
         """
         Iterates over the task's dependencies

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/137e80cb/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/137e80cb/aria/workflows/builtin/heal.py
----------------------------------------------------------------------
diff --git a/aria/workflows/builtin/heal.py b/aria/workflows/builtin/heal.py
index cab2e6e..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.chain([
-        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,23 @@ 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:
-                after_tasks = 
[node_instance_sub_workflows[relationship.target_id]
-                               for relationship in 
node_instance.relationship_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:
-                after_tasks = [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 after_tasks:
-                graph.dependency(source_task=node_instance_sub_workflow, 
after=after_tasks)
+                graph.add_dependency(node_instance_sub_workflow, dependency)
 
 
 @workflow(suffix_template='{failing_node_instances}')
@@ -141,35 +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:
-                after_tasks = 
[node_instance_sub_workflows[relationship.target_id]
-                               for relationship in 
node_instance.relationship_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:
-                after_tasks = [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 after_tasks:
-                graph.dependency(source_task=node_instance_sub_workflow, 
after=after_tasks)
+                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/137e80cb/aria/workflows/builtin/install.py
----------------------------------------------------------------------
diff --git a/aria/workflows/builtin/install.py 
b/aria/workflows/builtin/install.py
index 35d2968..552af90 100644
--- a/aria/workflows/builtin/install.py
+++ b/aria/workflows/builtin/install.py
@@ -47,8 +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]
-        graph.dependency(
-            source_task=node_instance_sub_workflow,
-            after=[
-                node_instance_sub_workflows[relationship.target_id]
-                for relationship in node_instance.relationship_instances])
+        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/137e80cb/aria/workflows/builtin/uninstall.py
----------------------------------------------------------------------
diff --git a/aria/workflows/builtin/uninstall.py 
b/aria/workflows/builtin/uninstall.py
index 47c8259..9659cb9 100644
--- a/aria/workflows/builtin/uninstall.py
+++ b/aria/workflows/builtin/uninstall.py
@@ -48,6 +48,5 @@ def uninstall(context, graph, node_instances=(), 
node_instance_sub_workflows=Non
     for node_instance in node_instances:
         node_instance_sub_workflow = 
node_instance_sub_workflows[node_instance.id]
         for relationship_instance in 
reversed(node_instance.relationship_instances):
-            graph.dependency(
-                
source_task=node_instance_sub_workflows[relationship_instance.target_id],
-                after=[node_instance_sub_workflow])
+            
graph.add_dependency(node_instance_sub_workflows[relationship_instance.target_id],
+                                 node_instance_sub_workflow)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/137e80cb/aria/workflows/builtin/workflows.py
----------------------------------------------------------------------
diff --git a/aria/workflows/builtin/workflows.py 
b/aria/workflows/builtin/workflows.py
index b6fbb94..5fc9ec8 100644
--- a/aria/workflows/builtin/workflows.py
+++ b/aria/workflows/builtin/workflows.py
@@ -57,18 +57,21 @@ def install_node_instance(context, graph, node_instance):
             'aria.interfaces.lifecycle.start'],
         node_instance=node_instance
     )
-    graph.chain(tasks=[
-        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:
@@ -76,14 +79,13 @@ def preconfigure_relationship(context, graph, 
node_instance):
     :param node_instance:
     :return:
     """
-    graph.chain(tasks=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:
@@ -91,14 +93,13 @@ def postconfigure_relationship(context, graph, 
node_instance):
     :param node_instance:
     :return:
     """
-    graph.chain(tasks=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:
@@ -106,10 +107,10 @@ def establish_relationship(context, graph, node_instance):
     :param node_instance:
     :return:
     """
-    graph.chain(tasks=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
@@ -135,16 +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.chain(tasks=[
-        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:
@@ -152,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.chain(tasks=tasks)
-    return tasks
 
 
 @workflow(suffix_template='{node_instance.id}.{operation}')
@@ -192,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)
     )
 
 
@@ -211,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
 
 
@@ -232,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,
@@ -250,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/137e80cb/aria/workflows/core/translation.py
----------------------------------------------------------------------
diff --git a/aria/workflows/core/translation.py 
b/aria/workflows/core/translation.py
index dc483c6..451e4e3 100644
--- a/aria/workflows/core/translation.py
+++ b/aria/workflows/core/translation.py
@@ -44,22 +44,21 @@ def build_execution_graph(
                            context=workflow_context)
     _add_task_and_dependencies(execution_graph, start_task, depends_on)
 
-    for operation_or_workflow, dependencies in 
task_graph.task_tree(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,
             dependencies,
             default=[start_task])
 
-        if _is_operation(operation_or_workflow):
+        if _is_operation(task):
             # Add the task an the dependencies
-            operation_task = tasks.OperationTask(id=operation_or_workflow.id,
-                                                 
name=operation_or_workflow.name,
-                                                 context=operation_or_workflow)
+            operation_task = tasks.OperationTask(id=task.id, name=task.name, 
context=task)
             _add_task_and_dependencies(execution_graph, operation_task, 
operation_dependencies)
         else:
             # Built the graph recursively while adding start and end markers
             build_execution_graph(
-                task_graph=operation_or_workflow,
+                task_graph=task,
                 workflow_context=workflow_context,
                 execution_graph=execution_graph,
                 start_cls=tasks.StartSubWorkflowTask,
@@ -70,7 +69,7 @@ def build_execution_graph(
     # Insert end marker
     workflow_dependencies = _get_tasks_from_dependencies(
         execution_graph,
-        task_graph.leaf_tasks,
+        _get_non_dependency_tasks(task_graph),
         default=[start_task])
     end_task = end_cls(
         id=_end_graph_suffix(task_graph.id),
@@ -104,3 +103,9 @@ def _start_graph_suffix(id):
 
 def _end_graph_suffix(id):
     return '{0}-End'.format(id)
+
+
+def _get_non_dependency_tasks(graph):
+    for task in graph.tasks:
+        if len(list(graph.get_task_dependents(task))) == 0:
+            yield task

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/137e80cb/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/137e80cb/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/137e80cb/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/137e80cb/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/137e80cb/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)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/137e80cb/tests/workflows/core/test_task_graph_into_exececution_graph.py
----------------------------------------------------------------------
diff --git a/tests/workflows/core/test_task_graph_into_exececution_graph.py 
b/tests/workflows/core/test_task_graph_into_exececution_graph.py
index deab4a3..c6ccda6 100644
--- a/tests/workflows/core/test_task_graph_into_exececution_graph.py
+++ b/tests/workflows/core/test_task_graph_into_exececution_graph.py
@@ -28,7 +28,7 @@ def no_storage(monkeypatch):
 
 
 def test_task_graph_into_execution_graph():
-    task_graph = task_graph.TaskGraph('test_task_graph')
+    test_task_graph = task_graph.TaskGraph('test_task_graph')
     simple_before_task = contexts.OperationContext('test_simple_before_task', 
{}, {}, None)
     simple_after_task = contexts.OperationContext('test_simple_after_task', 
{}, {}, None)
 
@@ -36,15 +36,15 @@ def test_task_graph_into_execution_graph():
     inner_task = contexts.OperationContext('test_inner_task', {}, {}, None)
     inner_task_graph.add_task(inner_task)
 
-    task_graph.add_task(simple_before_task)
-    task_graph.add_task(simple_after_task)
-    task_graph.add_task(inner_task_graph)
-    task_graph.dependency(inner_task_graph, [simple_before_task])
-    task_graph.dependency(simple_after_task, [inner_task_graph])
+    test_task_graph.add_task(simple_before_task)
+    test_task_graph.add_task(simple_after_task)
+    test_task_graph.add_task(inner_task_graph)
+    test_task_graph.add_dependency(inner_task_graph, simple_before_task)
+    test_task_graph.add_dependency(simple_after_task, inner_task_graph)
 
     # Direct check
     execution_graph = DiGraph()
-    translation.build_execution_graph(task_graph=task_graph,
+    translation.build_execution_graph(task_graph=test_task_graph,
                                       workflow_context=None,
                                       execution_graph=execution_graph)
     execution_tasks = topological_sort(execution_graph)
@@ -52,13 +52,13 @@ def test_task_graph_into_execution_graph():
     assert len(execution_tasks) == 7
 
     expected_tasks_names = [
-        '{0}-Start'.format(task_graph.id),
+        '{0}-Start'.format(test_task_graph.id),
         simple_before_task.id,
         '{0}-Start'.format(inner_task_graph.id),
         inner_task.id,
         '{0}-End'.format(inner_task_graph.id),
         simple_after_task.id,
-        '{0}-End'.format(task_graph.id)
+        '{0}-End'.format(test_task_graph.id)
     ]
 
     assert expected_tasks_names == execution_tasks


Reply via email to