You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by ra...@apache.org on 2016/10/30 07:05:34 UTC
[2/5] incubator-ariatosca git commit:
ARIA-5-Adapt-workflow-API-users-to-modified-API
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/85c61a61
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/85c61a61
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/85c61a61
Branch: refs/heads/ARIA-3-api-for-creating-workflows
Commit: 85c61a61ca27229bafb7c4aafcd18fddca00a9e2
Parents: 107c972
Author: mxmrlv <mx...@gmail.com>
Authored: Sun Oct 23 20:13:44 2016 +0300
Committer: Ran Ziv <ra...@gigaspaces.com>
Committed: Sun Oct 30 08:51:19 2016 +0200
----------------------------------------------------------------------
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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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/85c61a61/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