refactored and added tests
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/c3c0aa9b Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/c3c0aa9b Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/c3c0aa9b Branch: refs/heads/ARIA-9-API-for-operation-context Commit: c3c0aa9b0f597bacc792a95dd8d8a6dfe2a9e701 Parents: 1f67ebc Author: mxmrlv <[email protected]> Authored: Sun Nov 13 18:29:58 2016 +0200 Committer: mxmrlv <[email protected]> Committed: Sun Nov 13 18:29:58 2016 +0200 ---------------------------------------------------------------------- aria/context/common.py | 44 ++++--- aria/context/operation.py | 22 ++-- aria/context/toolbelt.py | 24 +--- aria/context/workflow.py | 5 +- aria/events/builtin_event_handler.py | 8 +- aria/storage/models.py | 5 +- aria/workflows/api/task.py | 10 +- aria/workflows/builtin/workflows.py | 16 +-- aria/workflows/core/task.py | 8 +- tests/context/__init__.py | 2 +- tests/context/operation.py | 125 ------------------ tests/context/test_operation.py | 129 +++++++++++++++++++ tests/context/test_toolbelt.py | 129 +++++++++++++++++++ tests/context/toolbelt.py | 118 ----------------- tests/mock/context.py | 1 + tests/mock/models.py | 17 ++- tests/storage/test_model_storage.py | 2 +- tests/storage/test_models.py | 3 + tests/workflows/api/test_task.py | 4 +- tests/workflows/core/test_task.py | 4 +- .../test_task_graph_into_exececution_graph.py | 2 +- tests/workflows/test_engine.py | 12 +- 22 files changed, 349 insertions(+), 341 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/context/common.py ---------------------------------------------------------------------- diff --git a/aria/context/common.py b/aria/context/common.py index 9f69b46..79360a3 100644 --- a/aria/context/common.py +++ b/aria/context/common.py @@ -37,26 +37,28 @@ class BaseContext(logger.LoggerMixin): super(BaseContext, self).__init__(**kwargs) self.name = name self.id = str(uuid4()) - self.model = model_storage - self.resource = resource_storage - self.deployment_id = deployment_id - self.workflow_id = workflow_id - self.execution_id = execution_id or str(uuid4()) + self._model = model_storage + self._resource = resource_storage + self._deployment_id = deployment_id + self._workflow_id = workflow_id + self._execution_id = execution_id or str(uuid4()) self.parameters = parameters or {} def __repr__(self): return ( - '{name}(deployment_id={self.deployment_id}, ' - 'workflow_id={self.workflow_id}, ' - 'execution_id={self.execution_id})'.format( - name=self.__class__.__name__, self=self)) + '{name}(name={self.name}, ' + 'deployment_id={self._deployment_id}, ' + 'workflow_id={self._workflow_id}, ' + 'execution_id={self._execution_id})' + .format(name=self.__class__.__name__, self=self)) @property - def blueprint_id(self): - """ - The blueprint id - """ - return self.deployment.blueprint_id + def model(self): + return self._model + + @property + def resource(self): + return self._resource @property @lru_cache() @@ -64,7 +66,7 @@ class BaseContext(logger.LoggerMixin): """ The blueprint model """ - return self.model.blueprint.get(self.blueprint_id) + return self.model.blueprint.get(self.deployment.blueprint_id) @property @lru_cache() @@ -72,14 +74,14 @@ class BaseContext(logger.LoggerMixin): """ The deployment model """ - return self.model.deployment.get(self.deployment_id) + return self.model.deployment.get(self._deployment_id) @property def execution(self): """ The execution model """ - return self.model.execution.get(self.execution_id) + return self.model.execution.get(self._execution_id) @execution.setter def execution(self, value): @@ -93,7 +95,7 @@ class BaseContext(logger.LoggerMixin): Download a blueprint resource from the resource storage """ return self.resource.blueprint.download( - entry_id=self.blueprint_id, + entry_id=self.blueprint.id, destination=destination, path=path) @@ -102,7 +104,7 @@ class BaseContext(logger.LoggerMixin): Download a deployment resource from the resource storage """ return self.resource.deployment.download( - entry_id=self.deployment_id, + entry_id=self._deployment_id, destination=destination, path=path) @@ -111,11 +113,11 @@ class BaseContext(logger.LoggerMixin): """ Read a deployment resource as string from the resource storage """ - return self.resource.deployment.data(entry_id=self.deployment_id, path=path) + return self.resource.deployment.data(entry_id=self._deployment_id, path=path) @lru_cache() def get_blueprint_resource_data(self, path=None): """ Read a blueprint resource as string from the resource storage """ - return self.resource.blueprint.data(entry_id=self.blueprint_id, path=path) + return self.resource.blueprint.data(entry_id=self._deployment_id, path=path) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/context/operation.py ---------------------------------------------------------------------- diff --git a/aria/context/operation.py b/aria/context/operation.py index 3508a3d..9ffcab1 100644 --- a/aria/context/operation.py +++ b/aria/context/operation.py @@ -31,14 +31,14 @@ class BaseOperationContext(BaseContext): name=name, model_storage=workflow_context.model, resource_storage=workflow_context.resource, - deployment_id=workflow_context.deployment_id, - workflow_id=workflow_context.workflow_id, - execution_id=workflow_context.execution_id, + deployment_id=workflow_context._deployment_id, + workflow_id=workflow_context._workflow_id, + execution_id=workflow_context._execution_id, parameters=workflow_context.parameters, **kwargs) self._workflow_context = workflow_context self._task_model = task - self._operation_container = self.task.operation_container + self._operation_executor = self.task.operation_executor def __repr__(self): details = ', '.join( @@ -55,22 +55,22 @@ class NodeOperationContext(BaseOperationContext): @property def node(self): - return self._operation_container.node + return self._operation_executor.node @property def node_instance(self): - return self._operation_container + return self._operation_executor class RelationshipOperationContext(BaseOperationContext): @property def node(self): - return + return self.model.node.get(self.relationship.source_id) @property def node_instance(self): - return + return self.model.node_instance.get(self.relationship_instance.source_id) @property def target_node(self): @@ -78,12 +78,12 @@ class RelationshipOperationContext(BaseOperationContext): @property def target_node_instance(self): - return self.model.node_instance.get(self._operation_container.target_id) + return self.model.node_instance.get(self._operation_executor.target_id) @property def relationship(self): - return self._operation_container.relationship + return self._operation_executor.relationship @property def relationship_instance(self): - return self._operation_container + return self._operation_executor http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/context/toolbelt.py ---------------------------------------------------------------------- diff --git a/aria/context/toolbelt.py b/aria/context/toolbelt.py index 3dfe713..0ab1b7a 100644 --- a/aria/context/toolbelt.py +++ b/aria/context/toolbelt.py @@ -14,6 +14,7 @@ # limitations under the License. from contextlib import contextmanager +from .. import exceptions from . import operation @@ -39,13 +40,6 @@ class _Toolbelt(object): class _OperationToolBelt(_Toolbelt): - @property - def node_instances_connected_to_me(self): - assert isinstance(self._op_context, operation.NodeOperationContext) - for node_instance in self._workflow_context.node_instances: - for relationship_instance in node_instance.relationship_instances: - if relationship_instance.target_id == self._op_context.node_instance.id: - yield node_instance @property def relationships_to_me(self): @@ -58,23 +52,13 @@ class _OperationToolBelt(_Toolbelt): @property def host_ip(self): assert isinstance(self._op_context, operation.NodeOperationContext) - host_id = self._op_context._operation_container.host_id + host_id = self._op_context._operation_executor.host_id host_instance = self._workflow_context.model.node_instance.get(host_id) return host_instance.runtime_properties.get('ip') class _RelationshipToolBelt(_Toolbelt): - - @property - def source_node(self): - return self.source_node_instance.node - - @property - def source_node_instance(self): - for node_instance in self._workflow_context.node_instances: - if self._op_context._operation_container in node_instance.relationship_instances: - return node_instance - + pass _operation_toolbelt = _OperationToolBelt() _relationship_toolbelt = _RelationshipToolBelt() @@ -85,3 +69,5 @@ def toolbelt(operation_context): return _operation_toolbelt.use(operation_context) elif isinstance(operation_context, operation.RelationshipOperationContext): return _relationship_toolbelt.use(operation_context) + else: + raise exceptions.TaskException("Operation context not supported") http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/context/workflow.py ---------------------------------------------------------------------- diff --git a/aria/context/workflow.py b/aria/context/workflow.py index 0b5b2a8..9b2027e 100644 --- a/aria/context/workflow.py +++ b/aria/context/workflow.py @@ -42,15 +42,14 @@ class WorkflowContext(BaseContext): """ Iterator over nodes """ - return self.model.node.iter( - filters={'blueprint_id': self.blueprint_id}) + return self.model.node.iter(filters={'blueprint_id': self.blueprint.id}) @property def node_instances(self): """ Iterator over node instances """ - return self.model.node_instance.iter(filters={'deployment_id': self.deployment_id}) + return self.model.node_instance.iter(filters={'deployment_id': self.deployment.id}) class _CurrentContext(threading.local): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/events/builtin_event_handler.py ---------------------------------------------------------------------- diff --git a/aria/events/builtin_event_handler.py b/aria/events/builtin_event_handler.py index 2abdd9f..cfcb185 100644 --- a/aria/events/builtin_event_handler.py +++ b/aria/events/builtin_event_handler.py @@ -65,10 +65,10 @@ def _task_succeeded(task, *args, **kwargs): def _workflow_started(workflow_context, *args, **kwargs): execution_cls = workflow_context.model.execution.model_cls execution = execution_cls( - id=workflow_context.execution_id, - deployment_id=workflow_context.deployment_id, - workflow_id=workflow_context.workflow_id, - blueprint_id=workflow_context.blueprint_id, + id=workflow_context._execution_id, + deployment_id=workflow_context.deployment.id, + workflow_id=workflow_context._workflow_id, + blueprint_id=workflow_context.blueprint.id, status=execution_cls.PENDING, started_at=datetime.utcnow(), parameters=workflow_context.parameters, http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/storage/models.py ---------------------------------------------------------------------- diff --git a/aria/storage/models.py b/aria/storage/models.py index 3b36818..42272e1 100644 --- a/aria/storage/models.py +++ b/aria/storage/models.py @@ -221,6 +221,7 @@ class Relationship(Model): A Model which represents a relationship """ id = Field(type=basestring, default=uuid_generator) + source_id = Field(type=basestring) target_id = Field(type=basestring) source_interfaces = Field(type=dict) source_operations = Field(type=dict) @@ -274,6 +275,8 @@ class RelationshipInstance(Instance): id = Field(type=basestring, default=uuid_generator) target_id = Field(type=basestring) target_name = Field(type=basestring) + source_id = Field(type=basestring) + source_name = Field(type=basestring) type = Field(type=basestring) relationship = PointerField(type=Relationship) @@ -405,5 +408,5 @@ class Task(Model): # Operation specific fields name = Field(type=basestring) operation_details = Field(type=dict) - operation_container = Field() + operation_executor = Field() inputs = Field(type=dict, default=lambda: {}) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/workflows/api/task.py ---------------------------------------------------------------------- diff --git a/aria/workflows/api/task.py b/aria/workflows/api/task.py index a983dce..31906ba 100644 --- a/aria/workflows/api/task.py +++ b/aria/workflows/api/task.py @@ -60,21 +60,21 @@ class OperationTask(BaseTask): def __init__(self, name, operation_details, - operation_container, + operation_executor, inputs=None): """ Creates an operation task using the name, details, node instance and any additional kwargs. :param name: the operation of the name. :param operation_details: the details for the operation. - :param operation_container: the operation host on which this operation is registered. + :param operation_executor: the operation host on which this operation is registered. :param inputs: operation inputs. """ - assert isinstance(operation_container, (storage.models.NodeInstance, - storage.models.RelationshipInstance)) + assert isinstance(operation_executor, (storage.models.NodeInstance, + storage.models.RelationshipInstance)) super(OperationTask, self).__init__() self.name = name self.operation_details = operation_details - self.operation_container = operation_container + self.operation_executor = operation_executor self.inputs = inputs or {} http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/workflows/builtin/workflows.py ---------------------------------------------------------------------- diff --git a/aria/workflows/builtin/workflows.py b/aria/workflows/builtin/workflows.py index 87afd82..ee866f0 100644 --- a/aria/workflows/builtin/workflows.py +++ b/aria/workflows/builtin/workflows.py @@ -45,17 +45,17 @@ def install_node_instance(graph, node_instance, **kwargs): create_node_instance = task.OperationTask( name='aria.interfaces.lifecycle.create.{0}'.format(node_instance.id), operation_details=node_instance.node.operations['aria.interfaces.lifecycle.create'], - operation_container=node_instance + operation_executor=node_instance ) configure_node_instance = task.OperationTask( name='aria.interfaces.lifecycle.configure.{0}'.format(node_instance.id), operation_details=node_instance.node.operations['aria.interfaces.lifecycle.configure'], - operation_container=node_instance + operation_executor=node_instance ) start_node_instance = task.OperationTask( name='aria.interfaces.lifecycle.start.{0}'.format(node_instance.id), operation_details=node_instance.node.operations['aria.interfaces.lifecycle.start'], - operation_container=node_instance + operation_executor=node_instance ) graph.sequence( @@ -126,12 +126,12 @@ def uninstall_node_instance(graph, node_instance, **kwargs): stop_node_instance = task.OperationTask( name='aria.interfaces.lifecycle.stop.{0}'.format(node_instance.id), operation_details=node_instance.node.operations['aria.interfaces.lifecycle.stop'], - operation_container=node_instance, + operation_executor=node_instance, ) delete_node_instance = task.OperationTask( name='aria.interfaces.lifecycle.delete.{0}'.format(node_instance.id), operation_details=node_instance.node.operations['aria.interfaces.lifecycle.delete'], - operation_container=node_instance + operation_executor=node_instance ) graph.sequence( @@ -180,7 +180,7 @@ def execute_operation_on_instance( return task.OperationTask( name=task_name, operation_details=node_instance.node.operations[operation], - operation_container=node_instance, + operation_executor=node_instance, inputs=operation_kwargs) @@ -228,10 +228,10 @@ def relationship_tasks(node_instance, relationship_instance, operation_name, ind ) source_operation = task.OperationTask( name=operation_name_template.format('source'), - operation_container=relationship_instance, + operation_executor=relationship_instance, operation_details=relationship_instance.relationship.source_operations[operation_name]) target_operation = task.OperationTask( name=operation_name_template.format('target'), - operation_container=relationship_instance, + operation_executor=relationship_instance, operation_details=relationship_instance.relationship.target_operations[operation_name]) return source_operation, target_operation http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/aria/workflows/core/task.py ---------------------------------------------------------------------- diff --git a/aria/workflows/core/task.py b/aria/workflows/core/task.py index 41a9968..d46c37f 100644 --- a/aria/workflows/core/task.py +++ b/aria/workflows/core/task.py @@ -108,16 +108,16 @@ class OperationTask(BaseTask): id=api_task.id, name=api_task.name, operation_details=api_task.operation_details, - operation_container=api_task.operation_container, + operation_executor=api_task.operation_executor, inputs=api_task.inputs, status=task_model.PENDING, - execution_id=self.workflow_context.execution_id, + execution_id=self.workflow_context._execution_id, max_retries=self.workflow_context.parameters.get('max_retries', 1), ) - if isinstance(api_task.operation_container, models.NodeInstance): + if isinstance(api_task.operation_executor, models.NodeInstance): context_class = operation_context.NodeOperationContext - elif isinstance(api_task.operation_container, models.RelationshipInstance): + elif isinstance(api_task.operation_executor, models.RelationshipInstance): context_class = operation_context.RelationshipOperationContext else: context_class = None http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/context/__init__.py ---------------------------------------------------------------------- diff --git a/tests/context/__init__.py b/tests/context/__init__.py index 89f55cb..c9e296f 100644 --- a/tests/context/__init__.py +++ b/tests/context/__init__.py @@ -53,4 +53,4 @@ def execute(workflow_func, workflow_context, executor): @pytest.fixture(autouse=True) def cleanup(): - global_test_holder.clear() \ No newline at end of file + global_test_holder.clear() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/context/operation.py ---------------------------------------------------------------------- diff --git a/tests/context/operation.py b/tests/context/operation.py deleted file mode 100644 index d98b248..0000000 --- a/tests/context/operation.py +++ /dev/null @@ -1,125 +0,0 @@ -# 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 sys - -from aria import workflow, operation, context -from aria.workflows import api - -from .. import mock -from . import op_path, execute, executor, workflow_context, global_test_holder - - -def test_node_operation_task_execution(workflow_context, executor): - node = mock.models.get_dependency_node() - node_instance = mock.models.get_dependency_node_instance(node) - workflow_context.model.node.store(node) - workflow_context.model.node_instance.store(node_instance) - - node_instance = workflow_context.model.node_instance.get(mock.models.DEPENDENCY_NODE_INSTANCE_ID) - name = 'op_name' - operation_details = {'operation': op_path(my_operation, module_path=sys.modules[__name__].__name__)} - inputs = {'putput': True} - - @workflow - def basic_workflow(graph, **_): - graph.add_tasks( - api.task.OperationTask( - name=name, - operation_details=operation_details, - operation_container=node_instance, - inputs=inputs - ) - ) - - execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) - - operation_value = global_test_holder[name] - - assert isinstance(operation_value, context.operation.NodeOperationContext) - - # operation container based attributes - for key, value in node_instance.fields_dict.items(): - assert getattr(operation_value.operation_container, key) == value - - # Task bases assertions - assert operation_value.task.operation_container == node_instance - assert operation_value.task.name == name - assert operation_value.task.operation_details == operation_details - assert operation_value.task.inputs == inputs - - # Context based attributes (sugaring) - assert operation_value.node == node_instance.node - assert operation_value.node_instance == node_instance - - -def test_relationship_operation_task_execution(workflow_context, executor): - dependency_node = mock.models.get_dependency_node() - dependency_node_instance = mock.models.get_dependency_node_instance() - relationship = mock.models.get_relationship(dependency_node) - relationship_instance = mock.models.get_relationship_instance(dependency_node_instance, - relationship) - dependent_node = mock.models.get_dependent_node() - dependent_node_instance = mock.models.get_dependent_node_instance(relationship_instance, - dependency_node) - workflow_context.model.node.store(dependency_node) - workflow_context.model.node_instance.store(dependency_node_instance) - workflow_context.model.relationship.store(relationship) - workflow_context.model.relationship_instance.store(relationship_instance) - workflow_context.model.node.store(dependent_node) - workflow_context.model.node_instance.store(dependent_node_instance) - - name = 'op_name' - operation_details = {'operation': op_path(my_operation, module_path=sys.modules[__name__].__name__)} - inputs = {'putput': True} - - @workflow - def basic_workflow(graph, **_): - graph.add_tasks( - api.task.OperationTask( - name=name, - operation_details=operation_details, - operation_container=relationship_instance, - inputs=inputs - ) - ) - - execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) - - operation_value = global_test_holder[name] - - assert isinstance(operation_value, context.operation.RelationshipOperationContext) - - # operation container based attributes - for key, value in relationship_instance.fields_dict.items(): - assert getattr(operation_value.operation_container, key) == value - - # Task bases assertions - assert operation_value.task.operation_container == relationship_instance - assert operation_value.task.name == name - assert operation_value.task.operation_details == operation_details - assert operation_value.task.inputs == inputs - - # Context based attributes (sugaring) - assert operation_value.target_node == dependency_node - assert operation_value.target_node_instance == dependency_node_instance - assert operation_value.relationship == relationship - assert operation_value.relationship_instance == relationship_instance - - -@operation -def my_operation(ctx, **_): - global_test_holder[ctx.name] = ctx - http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/context/test_operation.py ---------------------------------------------------------------------- diff --git a/tests/context/test_operation.py b/tests/context/test_operation.py new file mode 100644 index 0000000..a1fd2e0 --- /dev/null +++ b/tests/context/test_operation.py @@ -0,0 +1,129 @@ +# 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 sys + +from aria import workflow, operation, context +from aria.workflows import api + +from .. import mock +from . import op_path, execute, executor, workflow_context, global_test_holder + + +def test_node_operation_task_execution(workflow_context, executor): + node = mock.models.get_dependency_node() + node_instance = mock.models.get_dependency_node_instance(node) + workflow_context.model.node.store(node) + workflow_context.model.node_instance.store(node_instance) + + node_instance = workflow_context.model.node_instance.get(mock.models.DEPENDENCY_NODE_INSTANCE_ID) + name = 'op_name' + operation_details = {'operation': op_path(my_operation, module_path=sys.modules[__name__].__name__)} + inputs = {'putput': True} + + @workflow + def basic_workflow(graph, **_): + graph.add_tasks( + api.task.OperationTask( + name=name, + operation_details=operation_details, + operation_executor=node_instance, + inputs=inputs + ) + ) + + execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) + + operation_value = global_test_holder[name] + + assert isinstance(operation_value, context.operation.NodeOperationContext) + + # operation container based attributes + for key, value in node_instance.fields_dict.items(): + assert getattr(operation_value._operation_executor, key) == value + + # Task bases assertions + assert operation_value.task.operation_executor == node_instance + assert operation_value.task.name == name + assert operation_value.task.operation_details == operation_details + assert operation_value.task.inputs == inputs + + # Context based attributes (sugaring) + assert operation_value.node == node_instance.node + assert operation_value.node_instance == node_instance + + +def test_relationship_operation_task_execution(workflow_context, executor): + dependency_node = mock.models.get_dependency_node() + dependency_node_instance = mock.models.get_dependency_node_instance() + relationship = mock.models.get_relationship(target=dependency_node) + relationship_instance = mock.models.get_relationship_instance( + target_instance=dependency_node_instance, + relationship=relationship) + dependent_node = mock.models.get_dependent_node() + dependent_node_instance = mock.models.get_dependent_node_instance( + relationship_instance=relationship_instance, + dependent_node=dependency_node) + workflow_context.model.node.store(dependency_node) + workflow_context.model.node_instance.store(dependency_node_instance) + workflow_context.model.relationship.store(relationship) + workflow_context.model.relationship_instance.store(relationship_instance) + workflow_context.model.node.store(dependent_node) + workflow_context.model.node_instance.store(dependent_node_instance) + + name = 'op_name' + operation_details = {'operation': op_path(my_operation, module_path=sys.modules[__name__].__name__)} + inputs = {'putput': True} + + @workflow + def basic_workflow(graph, **_): + graph.add_tasks( + api.task.OperationTask( + name=name, + operation_details=operation_details, + operation_executor=relationship_instance, + inputs=inputs + ) + ) + + execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) + + operation_value = global_test_holder[name] + + assert isinstance(operation_value, context.operation.RelationshipOperationContext) + + # operation container based attributes + for key, value in relationship_instance.fields_dict.items(): + assert getattr(operation_value._operation_executor, key) == value + + # Task bases assertions + assert operation_value.task.operation_executor == relationship_instance + assert operation_value.task.name == name + assert operation_value.task.operation_details == operation_details + assert operation_value.task.inputs == inputs + + # Context based attributes (sugaring) + assert operation_value.target_node == dependency_node + assert operation_value.target_node_instance == dependency_node_instance + assert operation_value.relationship == relationship + assert operation_value.relationship_instance == relationship_instance + assert operation_value.node == dependent_node + assert operation_value.node_instance == dependent_node_instance + + +@operation +def my_operation(ctx, **_): + global_test_holder[ctx.name] = ctx + http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/context/test_toolbelt.py ---------------------------------------------------------------------- diff --git a/tests/context/test_toolbelt.py b/tests/context/test_toolbelt.py new file mode 100644 index 0000000..c9340d2 --- /dev/null +++ b/tests/context/test_toolbelt.py @@ -0,0 +1,129 @@ +# 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 sys + +import pytest + +from aria.workflows import api +from aria import workflow, operation, context, exceptions +from aria.context.toolbelt import _RelationshipToolBelt, _OperationToolBelt + +from .. import mock +from . import ( + op_path, + execute, + executor, + workflow_context, + global_test_holder, + cleanup +) + + +def test_operation_tool_belt(workflow_context, executor): + + dependency_node = mock.models.get_dependency_node() + dependency_node_instance = mock.models.get_dependency_node_instance() + relationship = mock.models.get_relationship(target=dependency_node) + relationship_instance = mock.models.get_relationship_instance( + target_instance=dependency_node_instance, relationship=relationship) + dependent_node = mock.models.get_dependent_node() + dependent_node_instance = mock.models.get_dependent_node_instance( + relationship_instance=relationship_instance, dependent_node=dependency_node) + workflow_context.model.node.store(dependency_node) + workflow_context.model.node_instance.store(dependency_node_instance) + workflow_context.model.relationship.store(relationship) + workflow_context.model.relationship_instance.store(relationship_instance) + workflow_context.model.node.store(dependent_node) + workflow_context.model.node_instance.store(dependent_node_instance) + + name = 'op_name' + operation_details = {'operation': op_path(node_operation, + module_path=sys.modules[__name__].__name__)} + inputs = {'putput': True} + + @workflow + def basic_workflow(graph, **_): + graph.add_tasks( + api.task.OperationTask( + name=name, + operation_details=operation_details, + operation_executor=dependency_node_instance, + inputs=inputs + ) + ) + + execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) + + assert list(global_test_holder.get('relationships_to_me', [])) == list([relationship_instance]) + assert global_test_holder.get('ip') == dependency_node_instance.runtime_properties.get('ip') + + +def test_relationship_tool_belt(workflow_context, executor): + dependency_node = mock.models.get_dependency_node() + dependency_node_instance = \ + mock.models.get_dependency_node_instance(dependency_node=dependency_node) + relationship = mock.models.get_relationship(target=dependency_node) + relationship_instance = \ + mock.models.get_relationship_instance(target_instance=dependency_node_instance, + relationship=relationship) + dependent_node = mock.models.get_dependent_node(relationship=relationship) + dependent_node_instance = \ + mock.models.get_dependent_node_instance(relationship_instance=relationship_instance, + dependent_node=dependent_node) + workflow_context.model.node.store(dependency_node) + workflow_context.model.node_instance.store(dependency_node_instance) + workflow_context.model.relationship.store(relationship) + workflow_context.model.relationship_instance.store(relationship_instance) + workflow_context.model.node.store(dependent_node) + workflow_context.model.node_instance.store(dependent_node_instance) + + name = 'op_name' + operation_details = {'operation': op_path(relationship_operation, + module_path=sys.modules[__name__].__name__)} + inputs = {'putput': True} + + @workflow + def basic_workflow(graph, **_): + graph.add_tasks( + api.task.OperationTask( + name=name, + operation_details=operation_details, + operation_executor=relationship_instance, + inputs=inputs + ) + ) + + execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) + + assert isinstance(global_test_holder.get(name), _RelationshipToolBelt) + + +def test_wrong_model_toolbelt(): + with pytest.raises(exceptions.TaskException): + context.toolbelt(None) + + +@operation(toolbelt=True) +def node_operation(toolbelt, **_): + global_test_holder['relationships_to_me'] = list(toolbelt.relationships_to_me) + global_test_holder['ip'] = toolbelt.host_ip + + +@operation(toolbelt=True) +def relationship_operation(ctx, toolbelt, **_): + global_test_holder[ctx.name] = toolbelt + + http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/context/toolbelt.py ---------------------------------------------------------------------- diff --git a/tests/context/toolbelt.py b/tests/context/toolbelt.py deleted file mode 100644 index 2cc5f90..0000000 --- a/tests/context/toolbelt.py +++ /dev/null @@ -1,118 +0,0 @@ -# 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 sys - -from aria.workflows import api -from aria import workflow, operation, context - -from .. import mock -from . import op_path, execute, executor, workflow_context, global_test_holder - - -def test_operation_tool_belt(workflow_context, executor): - - dependency_node = mock.models.get_dependency_node() - dependency_node_instance = mock.models.get_dependency_node_instance() - relationship = mock.models.get_relationship(dependency_node) - relationship_instance = mock.models.get_relationship_instance(dependency_node_instance, - relationship) - dependent_node = mock.models.get_dependent_node() - dependent_node_instance = mock.models.get_dependent_node_instance(relationship_instance, - dependency_node) - workflow_context.model.node.store(dependency_node) - workflow_context.model.node_instance.store(dependency_node_instance) - workflow_context.model.relationship.store(relationship) - workflow_context.model.relationship_instance.store(relationship_instance) - workflow_context.model.node.store(dependent_node) - workflow_context.model.node_instance.store(dependent_node_instance) - - name = 'op_name' - operation_details = {'operation': op_path(node_operation, - module_path=sys.modules[__name__].__name__)} - inputs = {'putput': True} - - @workflow - def basic_workflow(graph, **_): - graph.add_tasks( - api.task.OperationTask( - name=name, - operation_details=operation_details, - operation_container=dependency_node_instance, - inputs=inputs - ) - ) - - execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) - - assert list(global_test_holder.get('connected_to_me', [])) == list([dependent_node_instance]) - assert list(global_test_holder.get('relationships_to_me', [])) == list([relationship_instance]) - assert global_test_holder.get('ip') == dependency_node_instance.runtime_properties.get('ip') - - -def test_relationship_tool_belt(workflow_context, executor): - dependency_node = mock.models.get_dependency_node() - dependency_node_instance = \ - mock.models.get_dependency_node_instance(dependency_node=dependency_node) - relationship = mock.models.get_relationship(target=dependency_node) - relationship_instance = \ - mock.models.get_relationship_instance(target_instance=dependency_node_instance, - relationship=relationship) - dependent_node = mock.models.get_dependent_node(relationship=relationship) - dependent_node_instance = \ - mock.models.get_dependent_node_instance(relationship_instance=relationship_instance, - dependent_node=dependent_node) - workflow_context.model.node.store(dependency_node) - workflow_context.model.node_instance.store(dependency_node_instance) - workflow_context.model.relationship.store(relationship) - workflow_context.model.relationship_instance.store(relationship_instance) - workflow_context.model.node.store(dependent_node) - workflow_context.model.node_instance.store(dependent_node_instance) - - name = 'op_name' - operation_details = {'operation': op_path(relationship_operation, - module_path=sys.modules[__name__].__name__)} - inputs = {'putput': True} - - @workflow - def basic_workflow(graph, **_): - graph.add_tasks( - api.task.OperationTask( - name=name, - operation_details=operation_details, - operation_container=relationship_instance, - inputs=inputs - ) - ) - - execute(workflow_func=basic_workflow, workflow_context=workflow_context, executor=executor) - - assert global_test_holder.get('relationship_source_node') == dependent_node - assert global_test_holder.get('relationship_source_node_instance') == dependent_node_instance - - -@operation(toolbelt=True) -def node_operation(toolbelt, **_): - global_test_holder['connected_to_me'] = list(toolbelt.node_instances_connected_to_me) - global_test_holder['relationships_to_me'] = list(toolbelt.relationships_to_me) - global_test_holder['ip'] = toolbelt.host_ip - - -@operation(toolbelt=True) -def relationship_operation(toolbelt, **_): - global_test_holder['relationship_source_node'] = toolbelt.source_node - global_test_holder['relationship_source_node_instance'] = toolbelt.source_node_instance - - http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/mock/context.py ---------------------------------------------------------------------- diff --git a/tests/mock/context.py b/tests/mock/context.py index 4b1f34b..257cb3a 100644 --- a/tests/mock/context.py +++ b/tests/mock/context.py @@ -22,6 +22,7 @@ from ..storage import InMemoryModelDriver def simple(): storage = application_model_storage(InMemoryModelDriver()) storage.setup() + storage.blueprint.store(models.get_blueprint()) storage.deployment.store(models.get_deployment()) return context.workflow.WorkflowContext( name='simple_context', http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/mock/models.py ---------------------------------------------------------------------- diff --git a/tests/mock/models.py b/tests/mock/models.py index d0a9b2f..b4c9d2e 100644 --- a/tests/mock/models.py +++ b/tests/mock/models.py @@ -60,9 +60,10 @@ def get_dependency_node_instance(dependency_node=None): ) -def get_relationship(target=None): +def get_relationship(source=None, target=None): return models.Relationship( - target_id=target.id if target is not None else get_dependency_node().id, + source_id=source.id if source is not None else DEPENDENT_NODE_ID, + target_id=target.id if target is not None else DEPENDENCY_NODE_ID, source_interfaces={}, source_operations=dict((key, {}) for key in operations.RELATIONSHIP_OPERATIONS), target_interfaces={}, @@ -73,10 +74,12 @@ def get_relationship(target=None): ) -def get_relationship_instance(target_instance=None, relationship=None): +def get_relationship_instance(source_instance=None, target_instance=None, relationship=None): return models.RelationshipInstance( - target_id=target_instance.id or get_dependency_node_instance().id, + target_id=target_instance.id if target_instance else DEPENDENCY_NODE_INSTANCE_ID, target_name='test_target_name', + source_id=source_instance.id if source_instance else DEPENDENT_NODE_INSTANCE_ID, + source_name='test_source_name', type='some_type', relationship=relationship or get_relationship(target_instance.node if target_instance else None) @@ -85,8 +88,8 @@ def get_relationship_instance(target_instance=None, relationship=None): def get_dependent_node(relationship=None): return models.Node( - id=DEPENDENCY_NODE_ID, - host_id=DEPENDENCY_NODE_ID, + id=DEPENDENT_NODE_ID, + host_id=DEPENDENT_NODE_ID, blueprint_id=BLUEPRINT_ID, type='test_node_type', type_hierarchy=[], @@ -101,7 +104,7 @@ def get_dependent_node(relationship=None): ) -def get_dependent_node_instance(relationship_instance, dependent_node=None): +def get_dependent_node_instance(relationship_instance=None, dependent_node=None): return models.NodeInstance( id=DEPENDENT_NODE_INSTANCE_ID, host_id=DEPENDENT_NODE_INSTANCE_ID, http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/storage/test_model_storage.py ---------------------------------------------------------------------- diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py index 13c6600..a06cd5f 100644 --- a/tests/storage/test_model_storage.py +++ b/tests/storage/test_model_storage.py @@ -52,7 +52,7 @@ def test_model_storage(): assert [pc_from_storage for pc_from_storage in storage.provider_context] == [pc] storage.provider_context.update('id1', context={'update_key': 0}) - assert storage.provider_context.get('id1').model_context == {'update_key': 0} + assert storage.provider_context.get('id1').context == {'update_key': 0} storage.provider_context.delete('id1') with pytest.raises(StorageError): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/storage/test_models.py ---------------------------------------------------------------------- diff --git a/tests/storage/test_models.py b/tests/storage/test_models.py index fa7333b..69d8ce3 100644 --- a/tests/storage/test_models.py +++ b/tests/storage/test_models.py @@ -191,6 +191,7 @@ def _relationship(id=''): return Relationship( id='rel{0}'.format(id), target_id='target{0}'.format(id), + source_id='source{0}'.format(id), source_interfaces={}, source_operations={}, target_interfaces={}, @@ -244,6 +245,8 @@ def test_relationship_instance(): relationship_instances = [RelationshipInstance( id='rel{0}'.format(index), target_id='target_{0}'.format(index % 2), + source_id='source_{0}'.format(index % 2), + source_name='', target_name='', relationship=relationship, type='type{0}'.format(index)) for index in xrange(3)] http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/workflows/api/test_task.py ---------------------------------------------------------------------- diff --git a/tests/workflows/api/test_task.py b/tests/workflows/api/test_task.py index e694cd4..ad534ed 100644 --- a/tests/workflows/api/test_task.py +++ b/tests/workflows/api/test_task.py @@ -71,12 +71,12 @@ class TestOperationTask(object): with context.workflow.current.push(workflow_context): model_task = api.task.OperationTask(name=name, operation_details=op_details, - operation_container=node_instance, + operation_executor=node_instance, inputs=inputs) assert model_task.name == name assert model_task.operation_details == op_details - assert model_task.operation_container == node_instance + assert model_task.operation_executor == node_instance assert model_task.inputs == inputs http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/workflows/core/test_task.py ---------------------------------------------------------------------- diff --git a/tests/workflows/core/test_task.py b/tests/workflows/core/test_task.py index 451bce3..569ee70 100644 --- a/tests/workflows/core/test_task.py +++ b/tests/workflows/core/test_task.py @@ -51,7 +51,7 @@ class TestOperationTask(object): api_task = api.task.OperationTask( name='ripe', operation_details={'operations': 'aria.tests.workflows.core.test_task.foo'}, - operation_container=node_instance, + operation_executor=node_instance, ) core_task = core.task.OperationTask(api_task=api_task) @@ -66,7 +66,7 @@ class TestOperationTask(object): assert core_task.model_context == storage_task assert core_task.name == api_task.name assert core_task.operation_details == api_task.operation_details - assert core_task.operation_container == api_task.operation_container == node_instance + assert core_task.operation_executor == api_task.operation_executor == node_instance assert core_task.inputs == api_task.inputs == storage_task.inputs def test_operation_task_edit_locked_attribute(self, ctx): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/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 170fbdb..5a5b711 100644 --- a/tests/workflows/core/test_task_graph_into_exececution_graph.py +++ b/tests/workflows/core/test_task_graph_into_exececution_graph.py @@ -93,7 +93,7 @@ def _assert_execution_is_api_task(execution_task, api_task): assert execution_task.id == api_task.id assert execution_task.name == api_task.name assert execution_task.operation_details == api_task.operation_details - assert execution_task.operation_container == api_task.operation_container + assert execution_task.operation_executor == api_task.operation_executor assert execution_task.inputs == api_task.inputs http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c3c0aa9b/tests/workflows/test_engine.py ---------------------------------------------------------------------- diff --git a/tests/workflows/test_engine.py b/tests/workflows/test_engine.py index 72c70e5..f09c363 100644 --- a/tests/workflows/test_engine.py +++ b/tests/workflows/test_engine.py @@ -99,7 +99,7 @@ class TestEngine(object): name=task_name or 'task', operation_details={'operation': 'tests.workflows.test_engine.{name}'. format(name=func.__name__)}, - operation_container=ctx.model.node_instance.get('dependency_node_instance'), + operation_executor=ctx.model.node_instance.get('dependency_node_instance'), inputs=inputs ) @@ -152,13 +152,9 @@ class TestEngine(object): def workflow_context(self): model_storage = aria.application_model_storage(tests.storage.InMemoryModelDriver()) model_storage.setup() - deployment = models.Deployment( - id='d1', - blueprint_id='b1', - description=None, - created_at=datetime.now(), - updated_at=datetime.now(), - workflows={}) + blueprint = mock.models.get_blueprint() + deployment = mock.models.get_deployment() + model_storage.blueprint.store(blueprint) model_storage.deployment.store(deployment) node = mock.models.get_dependency_node() node_instance = mock.models.get_dependency_node_instance(node)
