http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/api/test_task.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/api/test_task.py b/tests/orchestrator/workflows/api/test_task.py index 8536902..1a90338 100644 --- a/tests/orchestrator/workflows/api/test_task.py +++ b/tests/orchestrator/workflows/api/test_task.py @@ -19,61 +19,38 @@ import pytest from aria.orchestrator import context from aria.orchestrator.workflows import api -from tests import mock +from tests import mock, storage [email protected]() [email protected] def ctx(): """ Create the following graph in storage: dependency_node <------ dependent_node :return: """ - simple_context = mock.context.simple() - 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(dependency_node) - relationship_instance = mock.models.get_relationship_instance( - relationship=relationship, - target_instance=dependency_node_instance - ) - - dependent_node = mock.models.get_dependent_node(relationship) - dependent_node_instance = mock.models.get_dependent_node_instance( - dependent_node=dependent_node, - relationship_instance=relationship_instance - ) - - simple_context.model.node.store(dependent_node) - simple_context.model.node.store(dependency_node) - simple_context.model.node_instance.store(dependent_node_instance) - simple_context.model.node_instance.store(dependency_node_instance) - simple_context.model.relationship.store(relationship) - simple_context.model.relationship_instance.store(relationship_instance) - simple_context.model.execution.store(mock.models.get_execution()) - simple_context.model.deployment.store(mock.models.get_deployment()) - - return simple_context + simple_context = mock.context.simple(storage.get_sqlite_api_kwargs()) + simple_context.model.execution.put(mock.models.get_execution(simple_context.deployment)) + yield simple_context + storage.release_sqlite_storage(simple_context.model) class TestOperationTask(object): - def test_node_operation_task_creation(self): - workflow_context = mock.context.simple() - + def test_node_operation_task_creation(self, ctx): operation_name = 'aria.interfaces.lifecycle.create' op_details = {'operation': True} - node = mock.models.get_dependency_node() + node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME) node.operations[operation_name] = op_details - node_instance = mock.models.get_dependency_node_instance(dependency_node=node) + ctx.model.node.update(node) + node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENT_NODE_INSTANCE_NAME) inputs = {'inputs': True} max_attempts = 10 retry_interval = 10 ignore_failure = True - with context.workflow.current.push(workflow_context): + with context.workflow.current.push(ctx): api_task = api.task.OperationTask.node_instance( name=operation_name, instance=node_instance, @@ -90,19 +67,17 @@ class TestOperationTask(object): assert api_task.max_attempts == max_attempts assert api_task.ignore_failure == ignore_failure - def test_relationship_operation_task_creation(self): - workflow_context = mock.context.simple() - + def test_relationship_operation_task_creation(self, ctx): operation_name = 'aria.interfaces.relationship_lifecycle.preconfigure' op_details = {'operation': True} - relationship = mock.models.get_relationship() + relationship = ctx.model.relationship.list()[0] relationship.source_operations[operation_name] = op_details - relationship_instance = mock.models.get_relationship_instance(relationship=relationship) + relationship_instance = ctx.model.relationship_instance.list()[0] inputs = {'inputs': True} max_attempts = 10 retry_interval = 10 - with context.workflow.current.push(workflow_context): + with context.workflow.current.push(ctx): api_task = api.task.OperationTask.relationship_instance( name=operation_name, instance=relationship_instance, @@ -118,18 +93,19 @@ class TestOperationTask(object): assert api_task.retry_interval == retry_interval assert api_task.max_attempts == max_attempts - def test_operation_task_default_values(self): - workflow_context = mock.context.simple(task_ignore_failure=True) - with context.workflow.current.push(workflow_context): - model_task = api.task.OperationTask( + def test_operation_task_default_values(self, ctx): + dependency_node_instance = ctx.model.node_instance.get_by_name( + mock.models.DEPENDENCY_NODE_INSTANCE_NAME) + with context.workflow.current.push(ctx): + task = api.task.OperationTask( name='stub', operation_mapping='', - actor=mock.models.get_dependency_node_instance()) + actor=dependency_node_instance) - assert model_task.inputs == {} - assert model_task.retry_interval == workflow_context._task_retry_interval - assert model_task.max_attempts == workflow_context._task_max_attempts - assert model_task.ignore_failure == workflow_context._task_ignore_failure + assert task.inputs == {} + assert task.retry_interval == ctx._task_retry_interval + assert task.max_attempts == ctx._task_max_attempts + assert task.ignore_failure == ctx._task_ignore_failure class TestWorkflowTask(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/builtin/__init__.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/builtin/__init__.py b/tests/orchestrator/workflows/builtin/__init__.py index e100432..26ba82f 100644 --- a/tests/orchestrator/workflows/builtin/__init__.py +++ b/tests/orchestrator/workflows/builtin/__init__.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. - from tests import mock + def assert_node_install_operations(operations, with_relationships=False): if with_relationships: all_operations = [ @@ -51,36 +51,3 @@ def assert_node_uninstall_operations(operations, with_relationships=False): else: for i, operation in enumerate(operations): assert operation.name.startswith(mock.operations.NODE_OPERATIONS_UNINSTALL[i]) - - -def ctx_with_basic_graph(): - """ - Create the following graph in storage: - dependency_node <------ dependent_node - :return: - """ - simple_context = mock.context.simple() - 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(dependency_node) - relationship_instance = mock.models.get_relationship_instance( - relationship=relationship, - target_instance=dependency_node_instance - ) - - dependent_node = mock.models.get_dependent_node(relationship) - dependent_node_instance = mock.models.get_dependent_node_instance( - dependent_node=dependent_node, - relationship_instance=relationship_instance - ) - - simple_context.model.node.store(dependent_node) - simple_context.model.node.store(dependency_node) - simple_context.model.node_instance.store(dependent_node_instance) - simple_context.model.node_instance.store(dependency_node_instance) - simple_context.model.relationship.store(relationship) - simple_context.model.relationship_instance.store(relationship_instance) - - return simple_context http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/builtin/test_execute_operation.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/builtin/test_execute_operation.py b/tests/orchestrator/workflows/builtin/test_execute_operation.py index 83e0d4d..b7e5678 100644 --- a/tests/orchestrator/workflows/builtin/test_execute_operation.py +++ b/tests/orchestrator/workflows/builtin/test_execute_operation.py @@ -19,17 +19,20 @@ from aria.orchestrator.workflows.api import task from aria.orchestrator.workflows.builtin.execute_operation import execute_operation from tests import mock -from . import ctx_with_basic_graph +from tests import storage @pytest.fixture -def ctx(): - return ctx_with_basic_graph() +def ctx(tmpdir): + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + yield context + storage.release_sqlite_storage(context.model) def test_execute_operation(ctx): + node_instance = ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) + operation_name = mock.operations.NODE_OPERATIONS_INSTALL[0] - node_instance_id = 'dependency_node_instance' execute_tasks = list( task.WorkflowTask( @@ -41,11 +44,13 @@ def test_execute_operation(ctx): run_by_dependency_order=False, type_names=[], node_ids=[], - node_instance_ids=[node_instance_id] + node_instance_ids=[node_instance.id] ).topological_order() ) assert len(execute_tasks) == 1 - assert execute_tasks[0].name == '{0}.{1}'.format(operation_name, node_instance_id) + assert execute_tasks[0].name == '{0}.{1}'.format(operation_name, node_instance.id) + + # TODO: add more scenarios http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/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 940194b..97121b9 100644 --- a/tests/orchestrator/workflows/builtin/test_heal.py +++ b/tests/orchestrator/workflows/builtin/test_heal.py @@ -18,18 +18,25 @@ import pytest from aria.orchestrator.workflows.api import task from aria.orchestrator.workflows.builtin.heal import heal +from tests import mock, storage + from . import (assert_node_install_operations, - assert_node_uninstall_operations, - ctx_with_basic_graph) + assert_node_uninstall_operations) @pytest.fixture -def ctx(): - return ctx_with_basic_graph() +def ctx(tmpdir): + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + yield context + storage.release_sqlite_storage(context.model) def test_heal_dependent_node(ctx): - heal_graph = task.WorkflowTask(heal, ctx=ctx, node_instance_id='dependent_node_instance') + dependent_node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENT_NODE_INSTANCE_NAME) + dependent_node_instance.host_id = dependent_node_instance.id + ctx.model.node_instance.update(dependent_node_instance) + heal_graph = task.WorkflowTask(heal, ctx=ctx, node_instance_id=dependent_node_instance.id) assert len(list(heal_graph.tasks)) == 2 uninstall_subgraph, install_subgraph = list(heal_graph.topological_order(reverse=True)) @@ -54,7 +61,11 @@ def test_heal_dependent_node(ctx): def test_heal_dependency_node(ctx): - heal_graph = task.WorkflowTask(heal, ctx=ctx, node_instance_id='dependency_node_instance') + dependency_node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) + dependency_node_instance.host_id = dependency_node_instance.id + ctx.model.node_instance.update(dependency_node_instance) + heal_graph = task.WorkflowTask(heal, ctx=ctx, node_instance_id=dependency_node_instance.id) # both subgraphs should contain un\install for both the dependent and the dependency assert len(list(heal_graph.tasks)) == 2 uninstall_subgraph, install_subgraph = list(heal_graph.topological_order(reverse=True)) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/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 3b23c5a..789a161 100644 --- a/tests/orchestrator/workflows/builtin/test_install.py +++ b/tests/orchestrator/workflows/builtin/test_install.py @@ -12,22 +12,26 @@ # 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.orchestrator.workflows.builtin.install import install from aria.orchestrator.workflows.api import task +from aria.orchestrator.workflows.builtin.install import install -from . import (assert_node_install_operations, - ctx_with_basic_graph) +from tests import mock +from tests import storage + +from . import assert_node_install_operations @pytest.fixture -def ctx(): - return ctx_with_basic_graph() +def ctx(tmpdir): + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + yield context + storage.release_sqlite_storage(context.model) def test_install(ctx): + install_tasks = list(task.WorkflowTask(install, ctx=ctx).topological_order(True)) assert len(install_tasks) == 2 http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/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 889e1d2..126c4cf 100644 --- a/tests/orchestrator/workflows/builtin/test_uninstall.py +++ b/tests/orchestrator/workflows/builtin/test_uninstall.py @@ -18,16 +18,21 @@ import pytest from aria.orchestrator.workflows.api import task from aria.orchestrator.workflows.builtin.uninstall import uninstall -from . import (assert_node_uninstall_operations, - ctx_with_basic_graph) +from tests import mock +from tests import storage + +from . import assert_node_uninstall_operations @pytest.fixture -def ctx(): - return ctx_with_basic_graph() +def ctx(tmpdir): + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + yield context + storage.release_sqlite_storage(context.model) def test_uninstall(ctx): + uninstall_tasks = list(task.WorkflowTask(uninstall, ctx=ctx).topological_order(True)) assert len(uninstall_tasks) == 2 http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/core/test_engine.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/core/test_engine.py b/tests/orchestrator/workflows/core/test_engine.py index 1b00bf6..baded7f 100644 --- a/tests/orchestrator/workflows/core/test_engine.py +++ b/tests/orchestrator/workflows/core/test_engine.py @@ -12,19 +12,16 @@ # 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 time import threading from datetime import datetime import pytest -import aria from aria.orchestrator import ( events, workflow, operation, - context ) from aria.storage import models from aria.orchestrator.workflows import ( @@ -34,9 +31,7 @@ from aria.orchestrator.workflows import ( from aria.orchestrator.workflows.core import engine from aria.orchestrator.workflows.executor import thread - -import tests.storage -from tests import mock +from tests import mock, storage global_test_holder = {} @@ -65,11 +60,11 @@ class BaseTest(object): max_attempts=None, retry_interval=None, ignore_failure=None): - node_instance = ctx.model.node_instance.get('dependency_node_instance') + node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) node_instance.node.operations['aria.interfaces.lifecycle.create'] = { 'operation': '{name}.{func.__name__}'.format(name=__name__, func=func) } - ctx.model.node_instance.store(node_instance) return api.task.OperationTask.node_instance( instance=node_instance, name='aria.interfaces.lifecycle.create', @@ -79,14 +74,14 @@ class BaseTest(object): ignore_failure=ignore_failure ) - @pytest.fixture(scope='function', autouse=True) + @pytest.fixture(autouse=True) def globals_cleanup(self): try: yield finally: global_test_holder.clear() - @pytest.fixture(scope='function', autouse=True) + @pytest.fixture(autouse=True) def signals_registration(self, ): def sent_task_handler(*args, **kwargs): calls = global_test_holder.setdefault('sent_task_signal_calls', 0) @@ -119,7 +114,7 @@ class BaseTest(object): events.on_cancelled_workflow_signal.disconnect(cancel_workflow_handler) events.sent_task_signal.disconnect(sent_task_handler) - @pytest.fixture(scope='function') + @pytest.fixture def executor(self): result = thread.ThreadExecutor() try: @@ -127,27 +122,13 @@ class BaseTest(object): finally: result.close() - @pytest.fixture(scope='function') - def workflow_context(self): - model_storage = aria.application_model_storage(tests.storage.InMemoryModelDriver()) - model_storage.setup() - 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) - model_storage.node.store(node) - model_storage.node_instance.store(node_instance) - result = context.workflow.WorkflowContext( - name='test', - model_storage=model_storage, - resource_storage=None, - deployment_id=deployment.id, - workflow_id='name') - result.states = [] - result.exception = None - return result + @pytest.fixture + def workflow_context(self, tmpdir): + workflow_context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + workflow_context.states = [] + workflow_context.exception = None + yield workflow_context + storage.release_sqlite_storage(workflow_context.model) class TestEngine(BaseTest): @@ -245,7 +226,7 @@ class TestCancel(BaseTest): executor=executor) t = threading.Thread(target=eng.execute) t.start() - time.sleep(1) + time.sleep(10) eng.cancel_execution() t.join(timeout=30) assert workflow_context.states == ['start', 'cancel'] http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/core/test_task.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/core/test_task.py b/tests/orchestrator/workflows/core/test_task.py index 6a4c8ac..c572501 100644 --- a/tests/orchestrator/workflows/core/test_task.py +++ b/tests/orchestrator/workflows/core/test_task.py @@ -26,26 +26,14 @@ from aria.orchestrator.workflows import ( exceptions, ) -from tests import mock +from tests import mock, storage @pytest.fixture -def ctx(): - simple_context = mock.context.simple() - - blueprint = mock.models.get_blueprint() - deployment = mock.models.get_deployment() - node = mock.models.get_dependency_node() - node_instance = mock.models.get_dependency_node_instance(node) - execution = mock.models.get_execution() - - simple_context.model.blueprint.store(blueprint) - simple_context.model.deployment.store(deployment) - simple_context.model.node.store(node) - simple_context.model.node_instance.store(node_instance) - simple_context.model.execution.store(execution) - - return simple_context +def ctx(tmpdir): + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + yield context + storage.release_sqlite_storage(context.model) class TestOperationTask(object): @@ -62,9 +50,10 @@ class TestOperationTask(object): return api_task, core_task def test_operation_task_creation(self, ctx): - node_instance = ctx.model.node_instance.get(mock.models.DEPENDENCY_NODE_INSTANCE_ID) + node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) api_task, core_task = self._create_operation_task(ctx, node_instance) - storage_task = ctx.model.task.get(core_task.id) + storage_task = ctx.model.task.get_by_name(core_task.name) assert core_task.model_task == storage_task assert core_task.name == api_task.name @@ -73,7 +62,8 @@ class TestOperationTask(object): assert core_task.inputs == api_task.inputs == storage_task.inputs def test_operation_task_edit_locked_attribute(self, ctx): - node_instance = ctx.model.node_instance.get(mock.models.DEPENDENCY_NODE_INSTANCE_ID) + node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) _, core_task = self._create_operation_task(ctx, node_instance) now = datetime.utcnow() @@ -89,7 +79,8 @@ class TestOperationTask(object): core_task.due_at = now def test_operation_task_edit_attributes(self, ctx): - node_instance = ctx.model.node_instance.get(mock.models.DEPENDENCY_NODE_INSTANCE_ID) + node_instance = \ + ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) _, core_task = self._create_operation_task(ctx, node_instance) future_time = datetime.utcnow() + timedelta(seconds=3) @@ -99,7 +90,7 @@ class TestOperationTask(object): core_task.started_at = future_time core_task.ended_at = future_time core_task.retry_count = 2 - core_task.eta = future_time + core_task.due_at = future_time assert core_task.status != core_task.STARTED assert core_task.started_at != future_time assert core_task.ended_at != future_time @@ -110,4 +101,4 @@ class TestOperationTask(object): assert core_task.started_at == future_time assert core_task.ended_at == future_time assert core_task.retry_count == 2 - assert core_task.eta == future_time + assert core_task.due_at == future_time http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/orchestrator/workflows/core/test_task_graph_into_exececution_graph.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/workflows/core/test_task_graph_into_exececution_graph.py b/tests/orchestrator/workflows/core/test_task_graph_into_exececution_graph.py index a179e49..18540f4 100644 --- a/tests/orchestrator/workflows/core/test_task_graph_into_exececution_graph.py +++ b/tests/orchestrator/workflows/core/test_task_graph_into_exececution_graph.py @@ -19,20 +19,14 @@ from aria.orchestrator import context from aria.orchestrator.workflows import api, core from tests import mock +from tests import storage def test_task_graph_into_execution_graph(): operation_name = 'aria.interfaces.lifecycle.create' - task_context = mock.context.simple() - node = mock.models.get_dependency_node() - node_instance = mock.models.get_dependency_node_instance() - deployment = mock.models.get_deployment() - execution = mock.models.get_execution() - task_context.model.node.store(node) - task_context.model.node_instance.store(node_instance) - task_context.model.deployment.store(deployment) - task_context.model.execution.store(execution) - + task_context = mock.context.simple(storage.get_sqlite_api_kwargs()) + node_instance = \ + task_context.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) def sub_workflow(name, **_): return api.task_graph.TaskGraph(name) @@ -91,6 +85,7 @@ def test_task_graph_into_execution_graph(): simple_after_task) assert isinstance(_get_task_by_name(execution_tasks[6], execution_graph), core.task.EndWorkflowTask) + storage.release_sqlite_storage(task_context.model) def _assert_execution_is_api_task(execution_task, api_task): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/requirements.txt ---------------------------------------------------------------------- diff --git a/tests/requirements.txt b/tests/requirements.txt index cda295a..0e4740f 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -15,4 +15,4 @@ mock==1.0.1 pylint==1.6.4 pytest==3.0.2 pytest-cov==2.3.1 -pytest-mock==1.2 +pytest-mock==1.2 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/storage/__init__.py ---------------------------------------------------------------------- diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py index 9bf48cc..edff982 100644 --- a/tests/storage/__init__.py +++ b/tests/storage/__init__.py @@ -12,42 +12,69 @@ # 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 os +import platform from tempfile import mkdtemp from shutil import rmtree -from aria.storage import ModelDriver +from sqlalchemy import ( + create_engine, + orm) +from sqlalchemy.orm import scoped_session +from sqlalchemy.pool import StaticPool + +from aria.storage import structures -class InMemoryModelDriver(ModelDriver): - def __init__(self, **kwargs): - super(InMemoryModelDriver, self).__init__(**kwargs) - self.storage = {} +class TestFileSystem(object): - def create(self, name, *args, **kwargs): - self.storage[name] = {} + def setup_method(self): + self.path = mkdtemp('{0}'.format(self.__class__.__name__)) - def get(self, name, entry_id, **kwargs): - return self.storage[name][entry_id].copy() + def teardown_method(self): + rmtree(self.path, ignore_errors=True) - def store(self, name, entry_id, entry, **kwargs): - self.storage[name][entry_id] = entry - def delete(self, name, entry_id, **kwargs): - self.storage[name].pop(entry_id) +def get_sqlite_api_kwargs(base_dir=None, filename='db.sqlite'): + """ + Create sql params. works in in-memory and in filesystem mode. + If base_dir is passed, the mode will be filesystem mode. while the default mode is in-memory. + :param str base_dir: The base dir for the filesystem memory file. + :param str filename: the file name - defaults to 'db.sqlite'. + :return: + """ + if base_dir is not None: + uri = 'sqlite:///{platform_char}{path}'.format( + # Handles the windows behavior where there is not root, but drivers. + # Thus behaving as relative path. + platform_char='' if 'Windows' in platform.system() else '/', - def iter(self, name, **kwargs): - for item in self.storage[name].itervalues(): - yield item.copy() + path=os.path.join(base_dir, filename)) + engine_kwargs = {} + else: + uri = 'sqlite:///:memory:' + engine_kwargs = dict(connect_args={'check_same_thread': False}, + poolclass=StaticPool) - def update(self, name, entry_id, **kwargs): - self.storage[name][entry_id].update(**kwargs) + engine = create_engine(uri, **engine_kwargs) + session_factory = orm.sessionmaker(bind=engine) + session = scoped_session(session_factory=session_factory) if base_dir else session_factory() + structures.Model.metadata.create_all(engine) + return dict(engine=engine, session=session) -class TestFileSystem(object): - def setup_method(self): - self.path = mkdtemp('{0}'.format(self.__class__.__name__)) +def release_sqlite_storage(storage): + """ + Drops the tables and clears the session + :param storage: + :return: + """ + mapis = storage.registered.values() - def teardown_method(self): - rmtree(self.path, ignore_errors=True) + if mapis: + for session in set(mapi._session for mapi in mapis): + session.rollback() + session.close() + for engine in set(mapi._engine for mapi in mapis): + structures.Model.metadata.drop_all(engine) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/storage/test_drivers.py ---------------------------------------------------------------------- diff --git a/tests/storage/test_drivers.py b/tests/storage/test_drivers.py deleted file mode 100644 index dccbe98..0000000 --- a/tests/storage/test_drivers.py +++ /dev/null @@ -1,135 +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 os -import pytest - -from aria.storage.drivers import FileSystemModelDriver, Driver, ModelDriver, ResourceDriver -from aria.storage.exceptions import StorageError - -from . import InMemoryModelDriver, TestFileSystem - - -def test_base_storage_driver(): - driver = Driver() - driver.connect() - driver.disconnect() - driver.create('name') - with driver as connection: - assert driver is connection - with pytest.raises(StorageError): - with driver: - raise StorageError() - - -def test_model_base_driver(): - driver = ModelDriver() - with pytest.raises(NotImplementedError): - driver.get('name', 'id') - with pytest.raises(NotImplementedError): - driver.store('name', entry={}, entry_id=None) - with pytest.raises(NotImplementedError): - driver.update('name', 'id', update_field=1) - with pytest.raises(NotImplementedError): - driver.delete('name', 'id') - with pytest.raises(NotImplementedError): - driver.iter('name') - - -def test_resource_base_driver(): - driver = ResourceDriver() - with pytest.raises(NotImplementedError): - driver.download('name', 'id', destination='dest') - with pytest.raises(NotImplementedError): - driver.upload('name', 'id', source='') - with pytest.raises(NotImplementedError): - driver.data('name', 'id') - - -def test_custom_driver(): - entry_dict = { - 'id': 'entry_id', - 'entry_value': 'entry_value' - } - - with InMemoryModelDriver() as driver: - driver.create('entry') - assert driver.storage['entry'] == {} - - driver.store(name='entry', entry=entry_dict, entry_id=entry_dict['id']) - assert driver.get(name='entry', entry_id='entry_id') == entry_dict - - assert list(node for node in driver.iter('entry')) == [entry_dict] - - driver.update(name='entry', entry_id=entry_dict['id'], entry_value='new_value') - assert driver.get(name='entry', entry_id='entry_id') == entry_dict - - driver.delete(name='entry', entry_id='entry_id') - - with pytest.raises(KeyError): - driver.get(name='entry', entry_id='entry_id') - - -class TestFileSystemDriver(TestFileSystem): - - def setup_method(self): - super(TestFileSystemDriver, self).setup_method() - self.driver = FileSystemModelDriver(directory=self.path) - - def test_name(self): - assert repr(self.driver) == ( - 'FileSystemModelDriver(directory={self.path})'.format(self=self)) - - def test_create(self): - self.driver.create(name='node') - assert os.path.exists(os.path.join(self.path, 'node')) - - def test_store(self): - self.test_create() - self.driver.store(name='node', entry_id='test_id', entry={'test': 'test'}) - assert os.path.exists(os.path.join(self.path, 'node', 'test_id')) - - def test_update(self): - self.test_store() - self.driver.update(name='node', entry_id='test_id', test='updated_test') - entry = self.driver.get(name='node', entry_id='test_id') - assert entry == {'test': 'updated_test'} - - def test_get(self): - self.test_store() - entry = self.driver.get(name='node', entry_id='test_id') - assert entry == {'test': 'test'} - - def test_delete(self): - self.test_store() - self.driver.delete(name='node', entry_id='test_id') - assert not os.path.exists(os.path.join(self.path, 'node', 'test_id')) - - def test_iter(self): - self.test_create() - entries = [ - {'test': 'test0'}, - {'test': 'test1'}, - {'test': 'test2'}, - {'test': 'test3'}, - {'test': 'test4'}, - ] - for entry_id, entry in enumerate(entries): - self.driver.store('node', str(entry_id), entry) - - for entry in self.driver.iter('node'): - entries.pop(entries.index(entry)) - - assert not entries http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/storage/test_field.py ---------------------------------------------------------------------- diff --git a/tests/storage/test_field.py b/tests/storage/test_field.py deleted file mode 100644 index cab218f..0000000 --- a/tests/storage/test_field.py +++ /dev/null @@ -1,124 +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 pytest - -from aria.storage.structures import ( - Field, - IterField, - PointerField, - IterPointerField, - Model, -) - - -def model_factory(): - class TestModel(Model): - id = Field(default='test_id') - return TestModel() - - -def test_base_field(): - field = Field() - assert vars(field) == vars(Field(type=None, choices=(), default=Field.NO_DEFAULT)) - - -def test_type_check(): - field = Field(type=int) - assert vars(field) == vars(Field(type=int, choices=(), default=Field.NO_DEFAULT)) - with pytest.raises(TypeError): - field.validate_instance('field', 'any_value', int) - field.validate_instance('field', 1, int) - - -def test_field_choices(): - field = Field(choices=[1, 2]) - assert vars(field) == vars(Field(type=None, choices=[1, 2], default=Field.NO_DEFAULT)) - field.validate_in_choice('field', 1, field.choices) - - with pytest.raises(TypeError): - field.validate_in_choice('field', 'value', field.choices) - - -def test_field_without_default(): - class Test(object): - field = Field() - test = Test() - with pytest.raises(AttributeError, message="'Test' object has no attribute 'field'"): - assert test.field - - -def test_field_default_func(): - def true_func(): - return True - - field = Field(default=true_func) - assert vars(field) == vars(Field(type=None, choices=(), default=true_func)) - assert field.default - - -def test_field_default(): - field = Field(default='value') - assert vars(field) == vars(Field(type=None, choices=(), default='value')) - - -def test_iterable_field(): - iter_field = IterField(type=int) - assert vars(iter_field) == vars(Field(type=int, default=Field.NO_DEFAULT)) - iter_field.validate_value('iter_field', [1, 2]) - with pytest.raises(TypeError): - iter_field.validate_value('iter_field', ['a', 1]) - - -def test_pointer_field(): - test_model = model_factory() - - pointer_field = PointerField(type=Model) - assert vars(pointer_field) == \ - vars(PointerField(type=Model, choices=(), default=Field.NO_DEFAULT)) - with pytest.raises(AssertionError): - PointerField(type=list) - pointer_field.validate_value('pointer_field', test_model, None) - with pytest.raises(TypeError): - pointer_field.validate_value('pointer_field', int, None) - - -def test_iterable_pointer_field(): - test_model = model_factory() - iter_pointer_field = IterPointerField(type=Model) - assert vars(iter_pointer_field) == \ - vars(IterPointerField(type=Model, default=Field.NO_DEFAULT)) - with pytest.raises(AssertionError): - IterPointerField(type=list) - - iter_pointer_field.validate_value('iter_pointer_field', [test_model, test_model], None) - with pytest.raises(TypeError): - iter_pointer_field.validate_value('iter_pointer_field', [int, test_model], None) - - -def test_custom_field_validation(): - def validation_func(name, value, instance): - assert name == 'id' - assert value == 'value' - assert isinstance(instance, TestModel) - - class TestModel(Model): - id = Field(default='_', validation_func=validation_func) - - obj = TestModel() - obj.id = 'value' - - with pytest.raises(AssertionError): - obj.id = 'not_value' http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c6c92ae5/tests/storage/test_model_storage.py ---------------------------------------------------------------------- diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py index 17e11ae..48cd02c 100644 --- a/tests/storage/test_model_storage.py +++ b/tests/storage/test_model_storage.py @@ -16,78 +16,72 @@ import pytest from aria.storage import ( - Storage, ModelStorage, models, + exceptions, + sql_mapi, ) -from aria.storage import structures -from aria.storage.exceptions import StorageError -from aria.storage.structures import Model, Field, PointerField from aria import application_model_storage +from tests.storage import get_sqlite_api_kwargs, release_sqlite_storage -from . import InMemoryModelDriver [email protected] +def storage(): + base_storage = ModelStorage(sql_mapi.SQLAlchemyModelAPI, api_kwargs=get_sqlite_api_kwargs()) + yield base_storage + release_sqlite_storage(base_storage) -def test_storage_base(): - driver = InMemoryModelDriver() - storage = Storage(driver) - - assert storage.driver == driver +def test_storage_base(storage): with pytest.raises(AttributeError): storage.non_existent_attribute() -def test_model_storage(): - storage = ModelStorage(InMemoryModelDriver()) +def test_model_storage(storage): storage.register(models.ProviderContext) - storage.setup() - pc = models.ProviderContext(context={}, name='context_name', id='id1') - storage.provider_context.store(pc) + pc = models.ProviderContext(context={}, name='context_name') + storage.provider_context.put(pc) - assert storage.provider_context.get('id1') == pc + assert storage.provider_context.get_by_name('context_name') == pc assert [pc_from_storage for pc_from_storage in storage.provider_context.iter()] == [pc] 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').context == {'update_key': 0} + new_context = {'update_key': 0} + pc.context = new_context + storage.provider_context.update(pc) + assert storage.provider_context.get(pc.id).context == new_context - storage.provider_context.delete('id1') - with pytest.raises(StorageError): - storage.provider_context.get('id1') + storage.provider_context.delete(pc) + with pytest.raises(exceptions.StorageError): + storage.provider_context.get(pc.id) -def test_storage_driver(): - storage = ModelStorage(InMemoryModelDriver()) +def test_storage_driver(storage): storage.register(models.ProviderContext) - storage.setup() - pc = models.ProviderContext(context={}, name='context_name', id='id2') - storage.driver.store(name='provider_context', entry=pc.fields_dict, entry_id=pc.id) - assert storage.driver.get( - name='provider_context', - entry_id='id2', - model_cls=models.ProviderContext) == pc.fields_dict + pc = models.ProviderContext(context={}, name='context_name') + storage.registered['provider_context'].put(entry=pc) + + assert storage.registered['provider_context'].get_by_name('context_name') == pc - assert [i for i in storage.driver.iter(name='provider_context')] == [pc.fields_dict] + assert next(i for i in storage.registered['provider_context'].iter()) == pc assert [i for i in storage.provider_context] == [pc] - storage.provider_context.delete('id2') + storage.registered['provider_context'].delete(pc) - with pytest.raises(StorageError): - storage.provider_context.get('id2') + with pytest.raises(exceptions.StorageError): + storage.registered['provider_context'].get(pc.id) def test_application_storage_factory(): - driver = InMemoryModelDriver() - storage = application_model_storage(driver) + storage = application_model_storage(sql_mapi.SQLAlchemyModelAPI, + api_kwargs=get_sqlite_api_kwargs()) assert storage.node assert storage.node_instance assert storage.plugin assert storage.blueprint - assert storage.snapshot assert storage.deployment assert storage.deployment_update assert storage.deployment_update_step @@ -95,68 +89,4 @@ def test_application_storage_factory(): assert storage.execution assert storage.provider_context - reused_storage = application_model_storage(driver) - assert reused_storage == storage - - -def test_storage_pointers(): - class PointedModel(Model): - id = Field() - - class PointingModel(Model): - id = Field() - pointing_field = PointerField(type=PointedModel) - - storage = ModelStorage(InMemoryModelDriver(), model_classes=[PointingModel]) - storage.setup() - - assert storage.pointed_model - assert storage.pointing_model - - pointed_model = PointedModel(id='pointed_id') - - pointing_model = PointingModel(id='pointing_id', pointing_field=pointed_model) - storage.pointing_model.store(pointing_model) - - assert storage.pointed_model.get('pointed_id') == pointed_model - assert storage.pointing_model.get('pointing_id') == pointing_model - - storage.pointing_model.delete('pointing_id') - - with pytest.raises(StorageError): - assert storage.pointed_model.get('pointed_id') - assert storage.pointing_model.get('pointing_id') - - -def test_storage_iter_pointers(): - class PointedIterModel(models.Model): - id = structures.Field() - - class PointingIterModel(models.Model): - id = models.Field() - pointing_field = structures.IterPointerField(type=PointedIterModel) - - storage = ModelStorage(InMemoryModelDriver(), model_classes=[PointingIterModel]) - storage.setup() - - assert storage.pointed_iter_model - assert storage.pointing_iter_model - - pointed_iter_model1 = PointedIterModel(id='pointed_id1') - pointed_iter_model2 = PointedIterModel(id='pointed_id2') - - pointing_iter_model = PointingIterModel( - id='pointing_id', - pointing_field=[pointed_iter_model1, pointed_iter_model2]) - storage.pointing_iter_model.store(pointing_iter_model) - - assert storage.pointed_iter_model.get('pointed_id1') == pointed_iter_model1 - assert storage.pointed_iter_model.get('pointed_id2') == pointed_iter_model2 - assert storage.pointing_iter_model.get('pointing_id') == pointing_iter_model - - storage.pointing_iter_model.delete('pointing_id') - - with pytest.raises(StorageError): - assert storage.pointed_iter_model.get('pointed_id1') - assert storage.pointed_iter_model.get('pointed_id2') - assert storage.pointing_iter_model.get('pointing_id') + release_sqlite_storage(storage)
