Files
rally/tests/unit/task/test_context.py
Andrey Kurilin b086b2cd50 Use unittests.mock instead of mock lib
Change-Id: I07400c7fd829dea86774f3f695c8a976550c6baf
2020-03-21 18:13:40 +02:00

404 lines
14 KiB
Python

# Copyright 2014: Mirantis Inc.
# All Rights Reserved.
#
# 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 unittest import mock
import ddt
from rally import exceptions
from rally.task import context
from tests.unit import fakes
from tests.unit import test
@ddt.ddt
class BaseContextTestCase(test.TestCase):
@ddt.data({"config": {"bar": "spam"}, "expected": {"bar": "spam"}},
{"config": {"bar": "spam"}, "expected": {"bar": "spam"}},
{"config": {}, "expected": {}},
{"config": None, "expected": None},
{"config": 42, "expected": 42},
{"config": "foo str", "expected": "foo str"},
{"config": [], "expected": ()},
{"config": [11, 22, 33], "expected": (11, 22, 33)})
@ddt.unpack
def test_init(self, config, expected):
ctx = {"config": {"foo": 42, "fake": config}, "task": "foo_task"}
ins = fakes.FakeContext(ctx)
self.assertEqual(expected, ins.config)
self.assertEqual("foo_task", ins.task)
self.assertEqual(ctx, ins.context)
def test_init_with_default_config(self):
@context.configure(name="foo", order=1)
class FooContext(fakes.FakeContext):
DEFAULT_CONFIG = {"alpha": "beta", "delta": "gamma"}
self.addCleanup(FooContext.unregister)
ctx = {"config": {"foo": {"ab": "cd"}, "bar": 42}, "task": "foo_task"}
ins = FooContext(ctx)
self.assertEqual({"ab": "cd", "alpha": "beta", "delta": "gamma"},
ins.config)
def test_init_empty_context(self):
ctx0 = {
"task": mock.MagicMock(),
"config": {"fake": {"foo": 42}}
}
ctx = fakes.FakeContext(ctx0)
self.assertEqual(ctx0["config"]["fake"], ctx.config)
self.assertEqual(ctx0["task"], ctx.task)
self.assertEqual(ctx0, ctx.context)
@ddt.data(({"test": 2}, True), ({"nonexisting": 2}, False))
@ddt.unpack
def test_validate(self, config, valid):
results = context.Context.validate("fake", None, None, config)
if valid:
self.assertEqual(results, [])
else:
self.assertEqual(1, len(results))
def test_setup_is_abstract(self):
@context.configure("test_abstract_setup", 0)
class A(context.Context):
def cleanup(self):
pass
self.addCleanup(A.unregister)
self.assertRaises(TypeError, A)
def test_cleanup_is_abstract(self):
@context.configure("test_abstract_cleanup", 0)
class A(context.Context):
def setup(self):
pass
self.addCleanup(A.unregister)
self.assertRaises(TypeError, A)
def test_with_statement(self):
ctx0 = {
"task": mock.MagicMock()
}
ctx = fakes.FakeContext(ctx0)
ctx.setup = mock.MagicMock()
ctx.cleanup = mock.MagicMock()
with ctx as entered_ctx:
self.assertEqual(ctx, entered_ctx)
ctx.cleanup.assert_called_once_with()
def test_get_owner_id_from_task(self):
ctx = {"config": {"fake": {"test": 10}}, "task": {"uuid": "task_uuid"}}
ins = fakes.FakeContext(ctx)
self.assertEqual("task_uuid", ins.get_owner_id())
def test_get_owner_id(self):
ctx = {"config": {"fake": {"test": 10}}, "task": {"uuid": "task_uuid"},
"owner_id": "foo_uuid"}
ins = fakes.FakeContext(ctx)
self.assertEqual("foo_uuid", ins.get_owner_id())
def test___eq__(self):
@context.configure(name="bar", order=1)
class BarContext(fakes.FakeContext):
pass
foo_context = fakes.FakeContext()
bar_context = BarContext()
self.assertTrue(foo_context == bar_context)
def test___lt__(self):
@context.configure(name="barlt", order=2)
class BarContext(fakes.FakeContext):
pass
foo_context = fakes.FakeContext()
bar_context = BarContext()
self.assertTrue(foo_context < bar_context)
def test___gt__(self):
@context.configure(name="bargt", order=0)
class BarContext(fakes.FakeContext):
pass
foo_context = fakes.FakeContext()
bar_context = BarContext()
self.assertTrue(foo_context > bar_context)
def test___le__(self):
@context.configure(name="barle", order=1)
class BarContext(fakes.FakeContext):
pass
@context.configure(name="bazle", order=2)
class BazContext(fakes.FakeContext):
pass
foo_context = fakes.FakeContext()
bar_context = BarContext()
baz_context = BazContext()
self.assertTrue(foo_context <= bar_context)
self.assertTrue(foo_context <= baz_context)
def test___ge__(self):
@context.configure(name="barge", order=0)
class BarContext(fakes.FakeContext):
pass
@context.configure(name="bazge", order=-1)
class BazContext(fakes.FakeContext):
pass
foo_context = fakes.FakeContext()
bar_context = BarContext()
baz_context = BazContext()
self.assertTrue(foo_context >= bar_context)
self.assertTrue(foo_context >= baz_context)
class ContextManagerTestCase(test.TestCase):
@mock.patch("rally.task.context.ContextManager._get_sorted_context_lst")
def test_setup(self, mock__get_sorted_context_lst):
foo_context = mock.MagicMock()
bar_context = mock.MagicMock()
mock__get_sorted_context_lst.return_value = [foo_context, bar_context]
ctx_object = {"config": {"a": [], "b": []}, "task": {"uuid": "uuid"}}
manager = context.ContextManager(ctx_object)
result = manager.setup()
self.assertEqual(result, ctx_object)
foo_context.setup.assert_called_once_with()
bar_context.setup.assert_called_once_with()
self.assertEqual([
{
"plugin_cfg": foo_context.config,
"plugin_name": foo_context.get_fullname.return_value,
"setup": {
"atomic_actions": foo_context.atomic_actions.return_value,
"error": None,
"started_at": mock.ANY,
"finished_at": mock.ANY
},
"cleanup": {
"atomic_actions": None,
"error": None,
"started_at": None,
"finished_at": None}
},
{
"plugin_cfg": bar_context.config,
"plugin_name": bar_context.get_fullname.return_value,
"setup": {
"atomic_actions": bar_context.atomic_actions.return_value,
"error": None,
"started_at": mock.ANY,
"finished_at": mock.ANY
},
"cleanup": {
"atomic_actions": None,
"error": None,
"started_at": None,
"finished_at": None}
}], manager.contexts_results())
@mock.patch("rally.task.context.task_utils.format_exc")
@mock.patch("rally.task.context.ContextManager._get_sorted_context_lst")
def test_setup_fails(self, mock__get_sorted_context_lst, mock_format_exc):
special_exc = KeyError("Oops")
foo_context = mock.MagicMock()
foo_context.setup.side_effect = special_exc
bar_context = mock.MagicMock()
mock__get_sorted_context_lst.return_value = [foo_context, bar_context]
ctx_object = {"config": {"a": [], "b": []}, "task": {"uuid": "uuid"}}
manager = context.ContextManager(ctx_object)
e = self.assertRaises(KeyError, manager.setup)
self.assertEqual(special_exc, e)
foo_context.setup.assert_called_once_with()
self.assertFalse(bar_context.setup.called)
self.assertEqual([
{
"plugin_cfg": foo_context.config,
"plugin_name": foo_context.get_fullname.return_value,
"setup": {
"atomic_actions": foo_context.atomic_actions.return_value,
"error": mock_format_exc.return_value,
"started_at": mock.ANY,
"finished_at": mock.ANY
},
"cleanup": {
"atomic_actions": None,
"error": None,
"started_at": None,
"finished_at": None}
}], manager.contexts_results())
mock_format_exc.assert_called_once_with(special_exc)
def test_get_sorted_context_lst(self):
@context.configure("foo", order=1)
class A(context.Context):
def setup(self):
pass
def cleanup(self):
pass
@context.configure("foo", platform="foo", order=0)
class B(A):
pass
@context.configure("boo", platform="foo", order=2)
class C(A):
pass
self.addCleanup(A.unregister)
self.addCleanup(B.unregister)
self.addCleanup(C.unregister)
ctx_obj = {"config": {"foo@default": [], "boo": [], "foo@foo": []}}
ctx_insts = context.ContextManager(ctx_obj)._get_sorted_context_lst()
self.assertEqual(3, len(ctx_insts))
self.assertIsInstance(ctx_insts[0], B)
self.assertIsInstance(ctx_insts[1], A)
self.assertIsInstance(ctx_insts[2], C)
@mock.patch("rally.task.context.Context.get_all")
def test_get_sorted_context_lst_fails(self, mock_context_get_all):
ctx_object = {"config": {"foo": "bar"}}
mock_context_get_all.return_value = []
manager = context.ContextManager(ctx_object)
self.assertRaises(exceptions.PluginNotFound,
manager._get_sorted_context_lst)
mock_context_get_all.assert_called_once_with(
name="foo", platform=None, allow_hidden=True)
def test_cleanup(self):
mock_obj = mock.MagicMock()
@context.configure("a", platform="foo", order=1)
class A(context.Context):
def setup(self):
pass
def cleanup(self):
mock_obj("a@foo")
self.addCleanup(A.unregister)
@context.configure("b", platform="foo", order=2)
class B(context.Context):
def setup(self):
pass
def cleanup(self):
mock_obj("b@foo")
ctx_object = {
"config": {"a@foo": [], "b@foo": []},
"task": {"uuid": "uuid"}
}
context.ContextManager(ctx_object).cleanup()
mock_obj.assert_has_calls([mock.call("b@foo"), mock.call("a@foo")])
@mock.patch("rally.task.context.task_utils.format_exc")
@mock.patch("rally.task.context.LOG.exception")
def test_cleanup_exception(self, mock_log_exception, mock_format_exc):
mock_obj = mock.MagicMock()
exc = Exception("So Sad")
@context.configure("a", platform="foo", order=1)
class A(context.Context):
def setup(self):
pass
def cleanup(self):
mock_obj("a@foo")
raise exc
self.addCleanup(A.unregister)
ctx_object = {"config": {"a@foo": []}, "task": {"uuid": "uuid"}}
ctx_manager = context.ContextManager(ctx_object)
ctx_manager._data[A.get_fullname()] = {
"cleanup": {"atomic_actions": None,
"started_at": None,
"finished_at": None,
"error": None}}
ctx_manager.cleanup()
mock_obj.assert_called_once_with("a@foo")
mock_log_exception.assert_called_once_with(mock.ANY)
mock_format_exc.assert_called_once_with(exc)
self.assertEqual([{
"cleanup": {
"atomic_actions": [],
"error": mock_format_exc.return_value,
"started_at": mock.ANY,
"finished_at": mock.ANY}}],
ctx_manager.contexts_results())
@mock.patch("rally.task.context.ContextManager.cleanup")
@mock.patch("rally.task.context.ContextManager.setup")
def test_with_statement(
self, mock_context_manager_setup, mock_context_manager_cleanup):
with context.ContextManager(mock.MagicMock()):
mock_context_manager_setup.assert_called_once_with()
mock_context_manager_setup.reset_mock()
self.assertFalse(mock_context_manager_cleanup.called)
self.assertFalse(mock_context_manager_setup.called)
mock_context_manager_cleanup.assert_called_once_with()
@mock.patch("rally.task.context.ContextManager.cleanup")
@mock.patch("rally.task.context.ContextManager.setup")
def test_with_statement_exception_during_setup(
self, mock_context_manager_setup, mock_context_manager_cleanup):
mock_context_manager_setup.side_effect = Exception("abcdef")
try:
with context.ContextManager(mock.MagicMock()):
pass
except Exception:
pass
finally:
mock_context_manager_setup.assert_called_once_with()
mock_context_manager_cleanup.assert_called_once_with()