You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/03/28 08:54:02 UTC
[2/4] incubator-ariatosca git commit:
ARIA-120-Builtin-workflows-relationship-operations-execution-order
ARIA-120-Builtin-workflows-relationship-operations-execution-order
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/07cbfcda
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/07cbfcda
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/07cbfcda
Branch: refs/heads/ARIA-132-Models-cascading-deletion-raises-constraint-errors
Commit: 07cbfcdabc207452acda33fa9f1ababf97e5d260
Parents: 0e10793
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon Mar 13 16:35:10 2017 +0200
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Tue Mar 28 11:18:19 2017 +0300
----------------------------------------------------------------------
aria/modeling/relationship.py | 2 +-
aria/orchestrator/workflows/api/task.py | 29 +++--
aria/orchestrator/workflows/builtin/utils.py | 60 +++++++--
.../orchestrator/workflows/builtin/workflows.py | 102 +++++----------
.../workflows/core/events_handler.py | 7 +-
aria/orchestrator/workflows/core/task.py | 2 +
tests/mock/context.py | 7 +-
tests/mock/models.py | 123 ++++++++++++++-----
tests/mock/topology.py | 41 +++++--
tests/modeling/test_models.py | 30 +++--
.../orchestrator/workflows/builtin/__init__.py | 65 ++++++++--
.../orchestrator/workflows/builtin/test_heal.py | 7 +-
.../workflows/builtin/test_install.py | 15 ++-
.../workflows/builtin/test_uninstall.py | 15 ++-
.../workflows/executor/test_executor.py | 2 +
.../workflows/executor/test_process_executor.py | 2 +
16 files changed, 323 insertions(+), 186 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/modeling/relationship.py
----------------------------------------------------------------------
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index ef2bcdd..70691b3 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -308,7 +308,7 @@ def many_to_many(model_class,
if prefix is not None:
secondary_table = '{0}_{1}'.format(prefix, secondary_table)
if other_property is None:
- other_property = '{0}_{1}'.format(prefix, this_table)
+ other_property = '{0}_{1}'.format(prefix, formatting.pluralize(this_table))
backref_kwargs = backref_kwargs or {}
backref_kwargs.setdefault('uselist', True)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/orchestrator/workflows/api/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/api/task.py b/aria/orchestrator/workflows/api/task.py
index 009b81c..f49ec2e 100644
--- a/aria/orchestrator/workflows/api/task.py
+++ b/aria/orchestrator/workflows/api/task.py
@@ -90,6 +90,8 @@ class OperationTask(BaseTask):
self.ignore_failure = (self.workflow_context._task_ignore_failure
if ignore_failure is None else ignore_failure)
self.runs_on = runs_on
+ self.interface_name = interface_name
+ self.operation_name = operation_name
# Wrap inputs
inputs = copy.deepcopy(inputs) if inputs else {}
@@ -101,11 +103,11 @@ class OperationTask(BaseTask):
# model, because they are different from the operation inputs. If we do this, then the two
# kinds of inputs should *not* be merged here.
- operation = self._get_operation(interface_name, operation_name)
+ operation = self._get_operation()
if operation is None:
raise exceptions.OperationNotFoundException(
'Could not find operation "{0}" on interface "{1}" for {2} "{3}"'
- .format(operation_name, interface_name, actor_type, actor.name))
+ .format(self.operation_name, self.interface_name, actor_type, actor.name))
self.plugin = None
if operation.plugin_specification:
@@ -113,15 +115,26 @@ class OperationTask(BaseTask):
if self.plugin is None:
raise exceptions.PluginNotFoundException(
'Could not find plugin of operation "{0}" on interface "{1}" for {2} "{3}"'
- .format(operation_name, interface_name, actor_type, actor.name))
+ .format(self.operation_name, self.interface_name, actor_type, actor.name))
self.implementation = operation.implementation
self.inputs = OperationTask._merge_inputs(operation.inputs, inputs)
self.name = OperationTask.NAME_FORMAT.format(type=actor_type,
name=actor.name,
- interface=interface_name,
- operation=operation_name)
+ interface=self.interface_name,
+ operation=self.operation_name)
+
+ def __repr__(self):
+ return self.name
+
+ def _get_operation(self):
+ interface = self.actor.interfaces.get(self.interface_name)
+ if interface:
+ return interface.operations.get(self.operation_name)
+ return None
+
+
@classmethod
def for_node(cls,
@@ -198,12 +211,6 @@ class OperationTask(BaseTask):
ignore_failure=ignore_failure,
inputs=inputs)
- def _get_operation(self, interface_name, operation_name):
- interface = self.actor.interfaces.get(interface_name)
- if interface is not None:
- return interface.operations.get(operation_name)
- return None
-
@staticmethod
def _find_plugin(plugin_specification):
workflow_context = context.workflow.current.get()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/orchestrator/workflows/builtin/utils.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/builtin/utils.py b/aria/orchestrator/workflows/builtin/utils.py
index 8efa889..d79318f 100644
--- a/aria/orchestrator/workflows/builtin/utils.py
+++ b/aria/orchestrator/workflows/builtin/utils.py
@@ -12,12 +12,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
from ..api.task import OperationTask
from .. import exceptions
-def create_node_task(interface_name, operation_name, node):
+def create_node_task(node, interface_name, operation_name):
"""
Returns a new operation task if the operation exists in the node, otherwise returns None.
"""
@@ -31,24 +30,59 @@ def create_node_task(interface_name, operation_name, node):
return None
-def create_relationship_tasks(interface_name, operation_name, runs_on, node):
+def create_relationships_tasks(
+ node, interface_name, source_operation_name=None, target_operation_name=None):
"""
- Returns a list of operation tasks for each outbound relationship of the node if the operation
- exists there.
+ Creates a relationship task (source and target) for all of a node_instance relationships.
+ :param basestring source_operation_name: the relationship operation name.
+ :param basestring interface_name: the name of the interface.
+ :param source_operation_name:
+ :param target_operation_name:
+ :param NodeInstance node: the source_node
+ :return:
"""
-
- sequence = []
+ sub_tasks = []
for relationship in node.outbound_relationships:
try:
- sequence.append(
- OperationTask.for_relationship(relationship=relationship,
- interface_name=interface_name,
- operation_name=operation_name,
- runs_on=runs_on))
+ relationship_operations = relationship_tasks(
+ relationship,
+ interface_name,
+ source_operation_name=source_operation_name,
+ target_operation_name=target_operation_name)
+ sub_tasks.append(relationship_operations)
except exceptions.OperationNotFoundException:
# We will skip relationships which do not have the operation
pass
- return sequence
+ return sub_tasks
+
+
+def relationship_tasks(
+ relationship, interface_name, source_operation_name=None, target_operation_name=None):
+ """
+ Creates a relationship task source and target.
+ :param Relationship relationship: the relationship instance itself
+ :param source_operation_name:
+ :param target_operation_name:
+
+ :return:
+ """
+ operations = []
+ if source_operation_name:
+ operations.append(
+ OperationTask.for_relationship(relationship=relationship,
+ interface_name=interface_name,
+ operation_name=source_operation_name,
+ runs_on='source')
+ )
+ if target_operation_name:
+ operations.append(
+ OperationTask.for_relationship(relationship=relationship,
+ interface_name=interface_name,
+ operation_name=target_operation_name,
+ runs_on='target')
+ )
+
+ return operations
def create_node_task_dependencies(graph, tasks_and_nodes, reverse=False):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/orchestrator/workflows/builtin/workflows.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/builtin/workflows.py b/aria/orchestrator/workflows/builtin/workflows.py
index 6065343..60f14ed 100644
--- a/aria/orchestrator/workflows/builtin/workflows.py
+++ b/aria/orchestrator/workflows/builtin/workflows.py
@@ -18,19 +18,21 @@ TSOCA normative lifecycle workflows.
"""
from ... import workflow
-from ....modeling.models import Task
-from .utils import (create_node_task, create_relationship_tasks)
+from .utils import (
+ create_node_task,
+ create_relationships_tasks
+)
NORMATIVE_STANDARD_INTERFACE = 'Standard' # 'tosca.interfaces.node.lifecycle.Standard'
NORMATIVE_CONFIGURE_INTERFACE = 'Configure' # 'tosca.interfaces.relationship.Configure'
NORMATIVE_CREATE = 'create'
+NORMATIVE_CONFIGURE = 'configure'
NORMATIVE_START = 'start'
NORMATIVE_STOP = 'stop'
NORMATIVE_DELETE = 'delete'
-NORMATIVE_CONFIGURE = 'configure'
NORMATIVE_PRE_CONFIGURE_SOURCE = 'pre_configure_source'
NORMATIVE_PRE_CONFIGURE_TARGET = 'pre_configure_target'
NORMATIVE_POST_CONFIGURE_SOURCE = 'post_configure_source'
@@ -39,6 +41,7 @@ NORMATIVE_POST_CONFIGURE_TARGET = 'post_configure_target'
NORMATIVE_ADD_SOURCE = 'add_source'
NORMATIVE_ADD_TARGET = 'add_target'
NORMATIVE_REMOVE_TARGET = 'remove_target'
+NORMATIVE_REMOVE_SOURCE = 'remove_source'
NORMATIVE_TARGET_CHANGED = 'target_changed'
@@ -56,6 +59,7 @@ __all__ = (
'NORMATIVE_POST_CONFIGURE_TARGET',
'NORMATIVE_ADD_SOURCE',
'NORMATIVE_ADD_TARGET',
+ 'NORMATIVE_REMOVE_SOURCE',
'NORMATIVE_REMOVE_TARGET',
'NORMATIVE_TARGET_CHANGED',
'install_node',
@@ -67,40 +71,20 @@ __all__ = (
@workflow(suffix_template='{node.name}')
def install_node(graph, node, **kwargs):
- sequence = []
-
# Create
- sequence.append(
- create_node_task(
- NORMATIVE_STANDARD_INTERFACE, NORMATIVE_CREATE,
- node))
+ sequence = [create_node_task(node,
+ NORMATIVE_STANDARD_INTERFACE, NORMATIVE_CREATE)]
# Configure
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_PRE_CONFIGURE_SOURCE,
- Task.RUNS_ON_SOURCE,
- node)
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_PRE_CONFIGURE_TARGET,
- Task.RUNS_ON_TARGET,
- node)
- sequence.append(
- create_node_task(
- NORMATIVE_STANDARD_INTERFACE, NORMATIVE_CONFIGURE,
- node))
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_POST_CONFIGURE_SOURCE,
- Task.RUNS_ON_SOURCE,
- node)
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_POST_CONFIGURE_TARGET,
- Task.RUNS_ON_TARGET,
- node)
-
+ sequence += create_relationships_tasks(node,
+ NORMATIVE_CONFIGURE_INTERFACE,
+ NORMATIVE_PRE_CONFIGURE_SOURCE,
+ NORMATIVE_PRE_CONFIGURE_TARGET)
+ sequence.append(create_node_task(node, NORMATIVE_STANDARD_INTERFACE, NORMATIVE_CONFIGURE))
+ sequence += create_relationships_tasks(node,
+ NORMATIVE_CONFIGURE_INTERFACE,
+ NORMATIVE_POST_CONFIGURE_SOURCE,
+ NORMATIVE_POST_CONFIGURE_TARGET)
# Start
sequence += _create_start_tasks(node)
@@ -113,10 +97,9 @@ def uninstall_node(graph, node, **kwargs):
sequence = _create_stop_tasks(node)
# Delete
- sequence.append(
- create_node_task(
- NORMATIVE_STANDARD_INTERFACE, NORMATIVE_DELETE,
- node))
+ sequence.append(create_node_task(node,
+ NORMATIVE_STANDARD_INTERFACE,
+ NORMATIVE_DELETE))
graph.sequence(*sequence)
@@ -132,43 +115,16 @@ def stop_node(graph, node, **kwargs):
def _create_start_tasks(node):
- sequence = []
- sequence.append(
- create_node_task(
- NORMATIVE_STANDARD_INTERFACE, NORMATIVE_START,
- node))
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_ADD_SOURCE,
- Task.RUNS_ON_SOURCE,
- node)
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_ADD_TARGET,
- Task.RUNS_ON_TARGET,
- node)
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_TARGET_CHANGED,
- Task.RUNS_ON_TARGET,
- node)
+ sequence = [create_node_task(node, NORMATIVE_STANDARD_INTERFACE, NORMATIVE_START)]
+ sequence += create_relationships_tasks(node,
+ NORMATIVE_CONFIGURE_INTERFACE,
+ NORMATIVE_ADD_SOURCE, NORMATIVE_ADD_TARGET)
return sequence
def _create_stop_tasks(node):
- sequence = []
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_REMOVE_TARGET,
- Task.RUNS_ON_TARGET,
- node)
- sequence += \
- create_relationship_tasks(
- NORMATIVE_CONFIGURE_INTERFACE, NORMATIVE_TARGET_CHANGED,
- Task.RUNS_ON_TARGET,
- node)
- sequence.append(
- create_node_task(
- NORMATIVE_STANDARD_INTERFACE, NORMATIVE_STOP,
- node))
+ sequence = [create_node_task(node, NORMATIVE_STANDARD_INTERFACE, NORMATIVE_STOP)]
+ sequence += create_relationships_tasks(node,
+ NORMATIVE_CONFIGURE_INTERFACE,
+ NORMATIVE_REMOVE_SOURCE, NORMATIVE_REMOVE_TARGET)
return sequence
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/orchestrator/workflows/core/events_handler.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/core/events_handler.py b/aria/orchestrator/workflows/core/events_handler.py
index 4ac4b64..8534aae 100644
--- a/aria/orchestrator/workflows/core/events_handler.py
+++ b/aria/orchestrator/workflows/core/events_handler.py
@@ -20,7 +20,6 @@ Path: aria.events.storage_event_handler
Implementation of storage handlers for workflow and operation events.
"""
-import re
from datetime import (
datetime,
timedelta,
@@ -126,11 +125,9 @@ def _workflow_cancelling(workflow_context, *args, **kwargs):
def _update_node_state_if_necessary(task, is_transitional=False):
- match = re.search(r'^(?:tosca.interfaces.node.lifecycle.Standard|Standard):(\S+)@node',
- task.name)
- if match:
+ if task.interface_name in ['tosca.interfaces.node.lifecycle.Standard', 'Standard']:
node = task.runs_on
- state = node.determine_state(op_name=match.group(1), is_transitional=is_transitional)
+ state = node.determine_state(op_name=task.operation_name, is_transitional=is_transitional)
if state:
node.state = state
task.context.model.node.update(node)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/aria/orchestrator/workflows/core/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/core/task.py b/aria/orchestrator/workflows/core/task.py
index f23312d..1e13588 100644
--- a/aria/orchestrator/workflows/core/task.py
+++ b/aria/orchestrator/workflows/core/task.py
@@ -106,6 +106,8 @@ class OperationTask(BaseTask):
def __init__(self, api_task, *args, **kwargs):
super(OperationTask, self).__init__(id=api_task.id, **kwargs)
self._workflow_context = api_task._workflow_context
+ self.interface_name = api_task.interface_name
+ self.operation_name = api_task.operation_name
model_storage = api_task._workflow_context.model
plugin = api_task.plugin
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/mock/context.py
----------------------------------------------------------------------
diff --git a/tests/mock/context.py b/tests/mock/context.py
index 3de3133..f943d7e 100644
--- a/tests/mock/context.py
+++ b/tests/mock/context.py
@@ -27,9 +27,10 @@ from ..storage import init_inmemory_model_storage
from .topology import create_simple_topology_two_nodes
-def simple(tmpdir, inmemory=False, context_kwargs=None):
+def simple(tmpdir, inmemory=False, context_kwargs=None, topology=None):
initiator = init_inmemory_model_storage if inmemory else None
initiator_kwargs = {} if inmemory else dict(base_dir=tmpdir)
+ topology = topology or create_simple_topology_two_nodes
model_storage = aria.application_model_storage(
sql_mapi.SQLAlchemyModelAPI, initiator=initiator, initiator_kwargs=initiator_kwargs)
@@ -38,13 +39,11 @@ def simple(tmpdir, inmemory=False, context_kwargs=None):
api_kwargs=dict(directory=os.path.join(tmpdir, 'resources'))
)
- service_id = create_simple_topology_two_nodes(model_storage)
-
final_kwargs = dict(
name='simple_context',
model_storage=model_storage,
resource_storage=resource_storage,
- service_id=service_id,
+ service_id=topology(model_storage),
workflow_name=models.WORKFLOW_NAME,
task_max_attempts=models.TASK_MAX_ATTEMPTS,
task_retry_interval=models.TASK_RETRY_INTERVAL
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index 9ae2815..457e7cb 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -16,7 +16,26 @@
from datetime import datetime
from aria.modeling import models
-from . import operations
+from aria.orchestrator import decorators
+from aria.orchestrator.workflows.builtin.workflows import (
+ NORMATIVE_STANDARD_INTERFACE,
+ NORMATIVE_CREATE,
+ NORMATIVE_START,
+ NORMATIVE_STOP,
+ NORMATIVE_DELETE,
+ NORMATIVE_CONFIGURE,
+
+ NORMATIVE_CONFIGURE_INTERFACE,
+ NORMATIVE_PRE_CONFIGURE_SOURCE,
+ NORMATIVE_PRE_CONFIGURE_TARGET,
+ NORMATIVE_POST_CONFIGURE_SOURCE,
+ NORMATIVE_POST_CONFIGURE_TARGET,
+
+ NORMATIVE_ADD_SOURCE,
+ NORMATIVE_ADD_TARGET,
+ NORMATIVE_REMOVE_TARGET,
+ NORMATIVE_REMOVE_SOURCE
+)
SERVICE_NAME = 'test_service_name'
SERVICE_TEMPLATE_NAME = 'test_service_template_name'
@@ -62,7 +81,7 @@ def create_service(service_template):
)
-def create_dependency_node_template(service_template):
+def create_dependency_node_template(name, service_template):
node_type = service_template.node_types.get_descendant('test_node_type')
capability_type = service_template.capability_types.get_descendant('test_capability_type')
@@ -72,7 +91,7 @@ def create_dependency_node_template(service_template):
)
node_template = models.NodeTemplate(
- name=DEPENDENCY_NODE_TEMPLATE_NAME,
+ name=name,
type=node_type,
capability_templates=_dictify(capability_template),
default_instances=1,
@@ -84,29 +103,21 @@ def create_dependency_node_template(service_template):
return node_template
-def create_dependent_node_template(service_template, dependency_node_template):
+def create_dependent_node_template(name, service_template, dependency_node_template):
the_type = service_template.node_types.get_descendant('test_node_type')
- operation_templates = dict((op, models.OperationTemplate(
- name=op,
- implementation='test'))
- for _, op in operations.NODE_OPERATIONS)
- interface_template = models.InterfaceTemplate(
- type=service_template.interface_types.get_descendant('test_interface_type'),
- operation_templates=operation_templates)
-
requirement_template = models.RequirementTemplate(
name='requirement',
target_node_template=dependency_node_template
)
node_template = models.NodeTemplate(
- name=DEPENDENT_NODE_TEMPLATE_NAME,
+ name=name,
type=the_type,
default_instances=1,
min_instances=1,
max_instances=1,
- interface_templates=_dictify(interface_template),
+ interface_templates=_dictify(get_standard_interface_template(service_template)),
requirement_templates=[requirement_template],
service_template=service_template
)
@@ -114,31 +125,17 @@ def create_dependent_node_template(service_template, dependency_node_template):
return node_template
-def create_dependency_node(dependency_node_template, service):
+def create_node(name, dependency_node_template, service):
node = models.Node(
- name=DEPENDENCY_NODE_NAME,
+ name=name,
type=dependency_node_template.type,
runtime_properties={'ip': '1.1.1.1'},
version=None,
node_template=dependency_node_template,
state=models.Node.INITIAL,
scaling_groups=[],
- service=service
- )
- service.nodes[node.name] = node
- return node
-
-
-def create_dependent_node(dependent_node_template, service):
- node = models.Node(
- name=DEPENDENT_NODE_NAME,
- type=dependent_node_template.type,
- runtime_properties={},
- version=None,
- node_template=dependent_node_template,
- state=models.Node.INITIAL,
- scaling_groups=[],
- service=service
+ service=service,
+ interfaces=get_standard_interface(service),
)
service.nodes[node.name] = node
return node
@@ -147,7 +144,8 @@ def create_dependent_node(dependent_node_template, service):
def create_relationship(source, target):
return models.Relationship(
source_node=source,
- target_node=target
+ target_node=target,
+ interfaces=get_configure_interfaces(service=source.service),
)
@@ -217,3 +215,62 @@ def create_plugin_specification(name='test_plugin', version='0.1'):
def _dictify(item):
return dict(((item.name, item),))
+
+
+def get_standard_interface_template(service_template):
+ the_type = service_template.interface_types.get_descendant('test_interface_type')
+
+ op_templates = dict(
+ (op_name, models.OperationTemplate(
+ name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
+ for op_name in [NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
+ NORMATIVE_STOP, NORMATIVE_DELETE]
+ )
+ return models.InterfaceTemplate(name=NORMATIVE_STANDARD_INTERFACE,
+ operation_templates=op_templates,
+ type=the_type)
+
+
+def get_standard_interface(service):
+ the_type = service.service_template.interface_types.get_descendant('test_interface_type')
+
+ ops = dict(
+ (op_name, models.Operation(
+ name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
+ for op_name in [NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
+ NORMATIVE_STOP, NORMATIVE_DELETE]
+ )
+ return {
+ NORMATIVE_STANDARD_INTERFACE:
+ models.Interface(name=NORMATIVE_STANDARD_INTERFACE, operations=ops, type=the_type)
+ }
+
+
+def get_configure_interfaces(service):
+ the_type = service.service_template.interface_types.get_descendant('test_interface_type')
+
+ operations = dict(
+ (op_name, models.Operation(
+ name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
+ for op_name in [NORMATIVE_PRE_CONFIGURE_SOURCE,
+ NORMATIVE_POST_CONFIGURE_SOURCE,
+ NORMATIVE_ADD_SOURCE,
+ NORMATIVE_REMOVE_SOURCE,
+
+ NORMATIVE_PRE_CONFIGURE_TARGET,
+ NORMATIVE_POST_CONFIGURE_TARGET,
+ NORMATIVE_ADD_TARGET,
+ NORMATIVE_REMOVE_TARGET
+ ]
+ )
+ interface = {
+ NORMATIVE_CONFIGURE_INTERFACE: models.Interface(
+ name=NORMATIVE_CONFIGURE_INTERFACE, operations=operations, type=the_type)
+ }
+
+ return interface
+
+
+@decorators.operation
+def mock_operation(*args, **kwargs):
+ pass
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/mock/topology.py
----------------------------------------------------------------------
diff --git a/tests/mock/topology.py b/tests/mock/topology.py
index 7ccc885..edf6b7d 100644
--- a/tests/mock/topology.py
+++ b/tests/mock/topology.py
@@ -22,7 +22,8 @@ def create_simple_topology_single_node(model_storage, create_operation):
service_template = models.create_service_template()
service = models.create_service(service_template)
- node_template = models.create_dependency_node_template(service_template)
+ node_template = models.create_dependency_node_template(
+ models.DEPENDENCY_NODE_TEMPLATE_NAME, service_template)
interface_template = models.create_interface_template(
service_template,
'Standard', 'create',
@@ -33,7 +34,7 @@ def create_simple_topology_single_node(model_storage, create_operation):
)
node_template.interface_templates[interface_template.name] = interface_template # pylint: disable=unsubscriptable-object
- node = models.create_dependency_node(node_template, service)
+ node = models.create_node(models.DEPENDENCY_NODE_NAME, node_template, service)
interface = models.create_interface(
service,
'Standard', 'create',
@@ -54,12 +55,15 @@ def create_simple_topology_two_nodes(model_storage):
# Creating a simple service with node -> node as a graph
- dependency_node_template = models.create_dependency_node_template(service_template)
- dependent_node_template = models.create_dependent_node_template(service_template,
- dependency_node_template)
+ dependency_node_template = models.create_dependency_node_template(
+ models.DEPENDENCY_NODE_TEMPLATE_NAME, service_template)
+ dependent_node_template = models.create_dependent_node_template(
+ models.DEPENDENT_NODE_TEMPLATE_NAME, service_template, dependency_node_template)
- dependency_node = models.create_dependency_node(dependency_node_template, service)
- dependent_node = models.create_dependent_node(dependent_node_template, service)
+ dependency_node = models.create_node(
+ models.DEPENDENCY_NODE_NAME, dependency_node_template, service)
+ dependent_node = models.create_node(
+ models.DEPENDENT_NODE_NAME, dependent_node_template, service)
dependent_node.outbound_relationships.append(models.create_relationship( # pylint: disable=no-member
source=dependent_node,
@@ -70,3 +74,26 @@ def create_simple_topology_two_nodes(model_storage):
model_storage.service.put(service)
return service.id
+
+
+def create_simple_topology_three_nodes(model_storage):
+ #################################################################################
+ # Creating a simple deployment with the following topology:
+ # node1 <----|
+ # | <- node0
+ # node2 <----|
+ # meaning node0 has two relationships: node1 and node2 (one each).
+
+ service_id = create_simple_topology_two_nodes(model_storage)
+ service = model_storage.service.get(service_id)
+ third_node_template = models.create_dependency_node_template(
+ 'another_dependency_node_template', service.service_template)
+ third_node = models.create_node(
+ 'another_dependency_node', third_node_template, service)
+ new_relationship = models.create_relationship(
+ source=model_storage.node.get_by_name(models.DEPENDENT_NODE_NAME),
+ target=third_node,
+ )
+ model_storage.relationship.put(new_relationship)
+
+ return service_id
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/modeling/test_models.py
----------------------------------------------------------------------
diff --git a/tests/modeling/test_models.py b/tests/modeling/test_models.py
index 84200d5..35ae09f 100644
--- a/tests/modeling/test_models.py
+++ b/tests/modeling/test_models.py
@@ -89,21 +89,27 @@ def _service_update_storage():
def _node_template_storage():
storage = _service_storage()
service_template = storage.service_template.list()[0]
- dependency_node_template = mock.models.create_dependency_node_template(service_template)
- mock.models.create_dependent_node_template(service_template, dependency_node_template)
+ dependency_node_template = mock.models.create_dependency_node_template(
+ mock.models.DEPENDENCY_NODE_TEMPLATE_NAME, service_template)
+ mock.models.create_dependent_node_template(
+ mock.models.DEPENDENCY_NODE_NAME, service_template, dependency_node_template)
storage.service_template.update(service_template)
return storage
-def _node_storage():
+def _nodes_storage():
storage = _node_template_storage()
service = storage.service.get_by_name(mock.models.SERVICE_NAME)
dependency_node_template = storage.node_template.get_by_name(
mock.models.DEPENDENCY_NODE_TEMPLATE_NAME)
- dependent_node_template = storage.node_template.get_by_name(
- mock.models.DEPENDENT_NODE_TEMPLATE_NAME)
- mock.models.create_dependency_node(dependency_node_template, service)
- mock.models.create_dependent_node(dependent_node_template, service)
+ mock.models.create_node(mock.models.DEPENDENCY_NODE_NAME, dependency_node_template, service)
+
+ dependent_node_template = \
+ mock.models.create_dependent_node_template(mock.models.DEPENDENT_NODE_TEMPLATE_NAME,
+ service.service_template,
+ dependency_node_template)
+
+ mock.models.create_node(mock.models.DEPENDENT_NODE_NAME, dependent_node_template, service)
storage.service.update(service)
return storage
@@ -148,8 +154,8 @@ def node_template_storage():
@pytest.fixture
-def node_storage():
- with sql_storage(_node_storage) as storage:
+def nodes_storage():
+ with sql_storage(_nodes_storage) as storage:
yield storage
@@ -671,13 +677,13 @@ class TestRelationship(object):
(True, 0, None),
]
)
- def test_relationship_model_creation(self, node_storage, is_valid, source_position,
+ def test_relationship_model_creation(self, nodes_storage, is_valid, source_position,
target_position):
- nodes = node_storage.node
+ nodes = nodes_storage.node
source_node = nodes.get_by_name(mock.models.DEPENDENT_NODE_NAME)
target_node = nodes.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
_test_model(is_valid=is_valid,
- storage=node_storage,
+ storage=nodes_storage,
model_cls=Relationship,
model_kwargs=dict(
source_node=source_node,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/builtin/__init__.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/builtin/__init__.py b/tests/orchestrator/workflows/builtin/__init__.py
index 9f60e55..8a67247 100644
--- a/tests/orchestrator/workflows/builtin/__init__.py
+++ b/tests/orchestrator/workflows/builtin/__init__.py
@@ -13,18 +13,61 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from tests import mock
+from aria.orchestrator.workflows.builtin import workflows
-def assert_node_install_operations(operations, with_relationships=False):
- all_operations = mock.operations.OPERATIONS_INSTALL if with_relationships else \
- mock.operations.NODE_OPERATIONS_INSTALL
- for i, operation in enumerate(operations):
- assert operation.name.startswith(all_operations[i] + '.')
+def _assert_relationships(operations, expected_op_full_name, relationships=0):
+ """
+ :param operations: and iterable of operations
+ :param expected_op_full_name: Note that source/target doesn't really matter since they are
+ dropped
+ :param relationships: the number of relationships
+ :return:
+ """
+ expected_op_name = expected_op_full_name.rsplit('_', 1)[0]
+ for _ in xrange(relationships):
+ # Since the target and source operations start of the same way, we only need to retrieve the
+ # suffix once
+ operation = next(operations)
+ relationship_id_1 = operation.actor.id
+ edge1 = operation.runs_on
+ _assert_cfg_interface_op(operation, expected_op_name)
-def assert_node_uninstall_operations(operations, with_relationships=False):
- all_operations = mock.operations.OPERATIONS_UNINSTALL if with_relationships else \
- mock.operations.NODE_OPERATIONS_UNINSTALL
- for i, operation in enumerate(operations):
- assert operation.name.startswith(all_operations[i] + '.')
+ operation = next(operations)
+ relationship_id_2 = operation.actor.id
+ edge2 = operation.runs_on
+ _assert_cfg_interface_op(operation, expected_op_name)
+
+ assert relationship_id_1 == relationship_id_2
+ assert edge1 != edge2
+
+
+def assert_node_install_operations(operations, relationships=0):
+ operations = iter(operations)
+
+ _assert_std_interface_op(next(operations), workflows.NORMATIVE_CREATE)
+ _assert_relationships(operations, workflows.NORMATIVE_PRE_CONFIGURE_SOURCE, relationships)
+ _assert_std_interface_op(next(operations), workflows.NORMATIVE_CONFIGURE)
+ _assert_relationships(operations, workflows.NORMATIVE_POST_CONFIGURE_SOURCE, relationships)
+ _assert_std_interface_op(next(operations), workflows.NORMATIVE_START)
+ _assert_relationships(operations, workflows.NORMATIVE_ADD_SOURCE, relationships)
+
+
+def assert_node_uninstall_operations(operations, relationships=0):
+ operations = iter(operations)
+
+ _assert_std_interface_op(next(operations), workflows.NORMATIVE_STOP)
+ _assert_relationships(operations, workflows.NORMATIVE_REMOVE_SOURCE, relationships)
+ _assert_std_interface_op(next(operations), workflows.NORMATIVE_DELETE)
+
+
+def _assert_cfg_interface_op(op, operation_name):
+ # We need to remove the source/target
+ assert op.operation_name.rsplit('_', 1)[0] == operation_name
+ assert op.interface_name == workflows.NORMATIVE_CONFIGURE_INTERFACE
+
+
+def _assert_std_interface_op(op, operation_name):
+ assert op.operation_name == operation_name
+ assert op.interface_name == workflows.NORMATIVE_STANDARD_INTERFACE
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/builtin/test_heal.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/builtin/test_heal.py b/tests/orchestrator/workflows/builtin/test_heal.py
index 92fa7ea..0a422bd 100644
--- a/tests/orchestrator/workflows/builtin/test_heal.py
+++ b/tests/orchestrator/workflows/builtin/test_heal.py
@@ -20,8 +20,7 @@ from aria.orchestrator.workflows.builtin.heal import heal
from tests import mock, storage
-from . import (assert_node_install_operations,
- assert_node_uninstall_operations)
+from . import (assert_node_install_operations, assert_node_uninstall_operations)
@pytest.fixture
@@ -57,8 +56,8 @@ def test_heal_dependent_node(ctx):
list(dependent_node_subgraph_install.topological_order(reverse=True))
assert isinstance(dependency_node_subgraph_install, task.StubTask)
- assert_node_uninstall_operations(dependent_node_uninstall_tasks, with_relationships=True)
- assert_node_install_operations(dependent_node_install_tasks, with_relationships=True)
+ assert_node_uninstall_operations(dependent_node_uninstall_tasks, relationships=1)
+ assert_node_install_operations(dependent_node_install_tasks, relationships=1)
@pytest.mark.skip(reason='heal is not implemented for now')
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/builtin/test_install.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/builtin/test_install.py b/tests/orchestrator/workflows/builtin/test_install.py
index 1791719..1a4e1f9 100644
--- a/tests/orchestrator/workflows/builtin/test_install.py
+++ b/tests/orchestrator/workflows/builtin/test_install.py
@@ -25,7 +25,8 @@ from . import assert_node_install_operations
@pytest.fixture
def ctx(tmpdir):
- context = mock.context.simple(str(tmpdir))
+ context = mock.context.simple(str(tmpdir),
+ topology=mock.topology.create_simple_topology_three_nodes)
yield context
storage.release_sqlite_storage(context.model)
@@ -34,10 +35,12 @@ def test_install(ctx):
install_tasks = list(task.WorkflowTask(install, ctx=ctx).topological_order(True))
- assert len(install_tasks) == 2
- dependency_node_subgraph, dependent_node_subgraph = install_tasks
+ assert len(install_tasks) == 3
+ dependency_node_subgraph1, dependency_node_subgraph2, dependent_node_subgraph = install_tasks
dependent_node_tasks = list(dependent_node_subgraph.topological_order(reverse=True))
- dependency_node_tasks = list(dependency_node_subgraph.topological_order(reverse=True))
+ dependency_node1_tasks = list(dependency_node_subgraph1.topological_order(reverse=True))
+ dependency_node2_tasks = list(dependency_node_subgraph2.topological_order(reverse=True))
- assert_node_install_operations(dependency_node_tasks)
- assert_node_install_operations(dependent_node_tasks, with_relationships=True)
+ assert_node_install_operations(dependency_node1_tasks)
+ assert_node_install_operations(dependency_node2_tasks)
+ assert_node_install_operations(dependent_node_tasks, relationships=2)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/builtin/test_uninstall.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/builtin/test_uninstall.py b/tests/orchestrator/workflows/builtin/test_uninstall.py
index 791291f..aa04c38 100644
--- a/tests/orchestrator/workflows/builtin/test_uninstall.py
+++ b/tests/orchestrator/workflows/builtin/test_uninstall.py
@@ -26,7 +26,8 @@ from . import assert_node_uninstall_operations
@pytest.fixture
def ctx(tmpdir):
- context = mock.context.simple(str(tmpdir))
+ context = mock.context.simple(str(tmpdir),
+ topology=mock.topology.create_simple_topology_three_nodes)
yield context
storage.release_sqlite_storage(context.model)
@@ -35,10 +36,12 @@ def test_uninstall(ctx):
uninstall_tasks = list(task.WorkflowTask(uninstall, ctx=ctx).topological_order(True))
- assert len(uninstall_tasks) == 2
- dependent_node_subgraph, dependency_node_subgraph = uninstall_tasks
+ assert len(uninstall_tasks) == 3
+ dependent_node_subgraph, dependency_node_subgraph1, dependency_node_subgraph2 = uninstall_tasks
dependent_node_tasks = list(dependent_node_subgraph.topological_order(reverse=True))
- dependency_node_tasks = list(dependency_node_subgraph.topological_order(reverse=True))
+ dependency_node1_tasks = list(dependency_node_subgraph1.topological_order(reverse=True))
+ dependency_node2_tasks = list(dependency_node_subgraph2.topological_order(reverse=True))
- assert_node_uninstall_operations(operations=dependency_node_tasks)
- assert_node_uninstall_operations(operations=dependent_node_tasks, with_relationships=True)
+ assert_node_uninstall_operations(operations=dependency_node1_tasks)
+ assert_node_uninstall_operations(operations=dependency_node2_tasks)
+ assert_node_uninstall_operations(operations=dependent_node_tasks, relationships=2)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/executor/test_executor.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_executor.py b/tests/orchestrator/workflows/executor/test_executor.py
index 0a2280d..9dde1ce 100644
--- a/tests/orchestrator/workflows/executor/test_executor.py
+++ b/tests/orchestrator/workflows/executor/test_executor.py
@@ -118,6 +118,8 @@ class MockTask(object):
self.max_attempts = 1
self.plugin_fk = None
self.ignore_failure = False
+ self.interface_name = 'interface_name'
+ self.operation_name = 'operation_name'
for state in models.Task.STATES:
setattr(self, state.upper(), state)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/07cbfcda/tests/orchestrator/workflows/executor/test_process_executor.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_process_executor.py b/tests/orchestrator/workflows/executor/test_process_executor.py
index 3cd1c47..0edd0a5 100644
--- a/tests/orchestrator/workflows/executor/test_process_executor.py
+++ b/tests/orchestrator/workflows/executor/test_process_executor.py
@@ -140,6 +140,8 @@ class MockTask(object):
self.plugin_fk = plugin.id
self.plugin = plugin
self.ignore_failure = False
+ self.interface_name = 'interface_name'
+ self.operation_name = 'operation_name'
for state in aria_models.Task.STATES:
setattr(self, state.upper(), state)