Add MockContextManager

It is used in murano-test-runner.

Mocks are inserted into new context, that is created
from the current context:
If mock for the current object exist, new linked context
   (``murano.dsl.linked_context.LinkedContext``) will be returned. It links
   existing context with the new context, where mock definition is presented.
   So if mocked function will be called, context will contain two
   definitions with that function: mock and original one, but mock will have
   higher priority.

If there is no mock for the current object or class, existing context
   will be returned. If there is no existing context, *None* will be returned.

Targets blueprint mock-context-manager

Depends-On: I9eccdf3af1802c731bfdfb93df92c4ad902a4d34
Change-Id: I9a55d07188ff06bdf98248f011a700c297e33417
This commit is contained in:
Ekaterina Chernova 2015-12-03 17:22:20 +03:00
parent a20d03fb0f
commit fd59720b1b
3 changed files with 131 additions and 2 deletions

View File

@ -34,8 +34,10 @@ from murano.dsl import executor
from murano.dsl import helpers
from murano.engine import client_manager
from murano.engine import environment
from murano.engine import mock_context_manager
from murano.engine import package_loader
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
options.set_defaults(CONF)
@ -220,12 +222,13 @@ class MuranoTestRunner(object):
murano_client_factory, client.tenant_id) as pkg_loader:
engine.get_plugin_loader().register_in_loader(pkg_loader)
exc = executor.MuranoDslExecutor(
pkg_loader, engine.ContextManager(), test_env)
pkg_loader,
mock_context_manager.MockContextManager(),
test_env)
package = self._load_package(pkg_loader, provided_pkg_name)
class_to_methods, class_to_obj = self._get_all_test_methods(
exc, package)
run_set = self._get_methods_to_run(package,
tests_to_run,
class_to_methods)

View File

@ -0,0 +1,70 @@
# Copyright (c) 2015 Mirantis Inc.
#
# Licensed 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.
from murano.common import engine
from murano.dsl import linked_context
from murano.dsl import yaql_integration
class MockContextManager(engine.ContextManager):
def __init__(self):
# { object_id: [mock_function_definitions] }
self.obj_mock_ctx = {}
# { class_name: [mock_function_definitions] }
self.class_mock_ctx = {}
def _create_new_ctx(self, mock_funcs):
mock_context = yaql_integration.create_empty_context()
for mock_func in mock_funcs:
mock_context.register_function(mock_func)
return mock_context
def _create_new_ctx_for_class(self, name):
new_context = None
if name in self.class_mock_ctx:
new_context = self._create_new_ctx(self.class_mock_ctx[name])
return new_context
def _create_new_ctx_for_obj(self, obj_id):
new_context = None
if obj_id in self.obj_mock_ctx:
new_context = self._create_new_ctx(self.obj_mock_ctx[obj_id])
return new_context
def create_class_context(self, murano_class):
original_context = super(MockContextManager,
self).create_class_context(murano_class)
mock_context = self._create_new_ctx_for_class(murano_class.name)
if mock_context:
result_context = linked_context.link(
original_context, mock_context).create_child_context()
else:
result_context = original_context
return result_context
def create_object_context(self, murano_obj):
original_context = super(MockContextManager,
self).create_object_context(murano_obj)
mock_context = self._create_new_ctx_for_obj(murano_obj.type.name)
if mock_context:
result_context = linked_context.link(
original_context, mock_context).create_child_context()
else:
result_context = original_context
return result_context

View File

@ -0,0 +1,56 @@
# Licensed 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 mock
from yaql import contexts
from yaql import specs
from murano.dsl import murano_class
from murano.engine import mock_context_manager
from murano.tests.unit import base
FIXTURE_CLASS = 'io.murano.system.Agent'
FIXTURE_FUNC = 'call'
def _get_fd(set_to_extract):
return list(set_to_extract)[0]
class TestMockManager(base.MuranoTestCase):
def test_create_class_context(self):
mock_manager = mock_context_manager.MockContextManager()
mock_murano_class = mock.MagicMock(spec=murano_class.MuranoClass)
mock_murano_class.name = FIXTURE_CLASS
original_function = mock.MagicMock(spec=specs.FunctionDefinition)
original_function.is_method = True
original_function.name = FIXTURE_FUNC
original_context = contexts.Context()
p = mock.patch("inspect.getargspec", new=mock.MagicMock())
p.start()
original_context.register_function(original_function)
mock_murano_class.context = original_context
p.stop()
mock_function = mock.MagicMock(spec=specs.FunctionDefinition)
mock_function.is_method = True
mock_function.name = FIXTURE_FUNC
mock_manager.class_mock_ctx[FIXTURE_CLASS] = [mock_function]
result_context = mock_manager.create_class_context(mock_murano_class)
all_functions = result_context.collect_functions(FIXTURE_FUNC)
# Mock function should go first, but result context should contain both
self.assertIs(mock_function, _get_fd(all_functions[0]))
self.assertIs(original_function, _get_fd(all_functions[1]))