From 923965db74c343e3e789c870c464ab27a2a44883 Mon Sep 17 00:00:00 2001 From: Pavel Boldin Date: Tue, 29 Sep 2015 21:06:08 +0300 Subject: [PATCH] tests: add ContextTestCase that mocks clients Add tests.unit.test.ContextTestCase class that can be inherited by all context-related TestCases and provides a ScenarioTestCase-similar API with self.clients and self.admin_clients. Usage: class MyContextTestCase(tests.unit.test.ContextTestCase): def test_something(self): mock_list = self.admin_client("nova").hypervisors.list mock_list.return_value = [10, 20, 30] #... Change-Id: I95d001acc28e499e386abe6f2e40de7baec74084 --- tests/unit/test.py | 71 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/tests/unit/test.py b/tests/unit/test.py index 00eaf999..b48a69fb 100644 --- a/tests/unit/test.py +++ b/tests/unit/test.py @@ -99,6 +99,18 @@ class ScenarioTestCase(TestCase): key = (client_type, version, admin) return key in self._clients + def get_client_mocks(self): + base_path = "rally.plugins.openstack" + + return [ + mock.patch( + "%s.scenario.OpenStackScenario.clients" % base_path, + mock.Mock(side_effect=self.clients)), + mock.patch( + "%s.scenario.OpenStackScenario.admin_clients" % base_path, + mock.Mock(side_effect=self.admin_clients)) + ] + def setUp(self): super(ScenarioTestCase, self).setUp() if self.patch_benchmark_utils: @@ -122,15 +134,8 @@ class ScenarioTestCase(TestCase): self.useFixture(self.mock_sleep) self._clients = {} - base_path = "rally.plugins.openstack" - self._client_mocks = [ - mock.patch( - "%s.scenario.OpenStackScenario.clients" % base_path, - mock.Mock(side_effect=self.clients)), - mock.patch( - "%s.scenario.OpenStackScenario.admin_clients" % base_path, - mock.Mock(side_effect=self.admin_clients)) - ] + self._client_mocks = self.get_client_mocks() + for patcher in self._client_mocks: patcher.start() @@ -142,6 +147,54 @@ class ScenarioTestCase(TestCase): super(ScenarioTestCase, self).tearDown() +class ContextClientAdapter(object): + def __init__(self, endpoint, clients): + self.endpoint = endpoint + self._clients = clients + + def mock_client(self, name, version=None): + admin = self.endpoint.startswith("admin") + try: + client = self._clients[(name, version, admin)] + except KeyError: + raise ValueError( + "Client %s version %s (admin %s) is missing, " + "please configure" % (name, version, admin)) + if not isinstance(client.return_value, mock.Mock): + return client.return_value + if client.side_effect is not None: + # NOTE(pboldin): if a client has side_effects that means the + # user wants some of the returned values overrided (look at + # the test_existing_users for instance) + return client() + return client + + def __getattr__(self, name): + # NOTE(pboldin): __getattr__ magic is called last, after the value + # were looked up for in __dict__ + return lambda version=None: self.mock_client(name, version) + + +class ContextTestCase(ScenarioTestCase): + def setUp(self): + super(ContextTestCase, self).setUp() + + self._adapters = {} + + def context_client(self, endpoint): + if endpoint not in self._adapters: + self._adapters[endpoint] = ContextClientAdapter( + endpoint, self._clients) + return self._adapters[endpoint] + + def get_client_mocks(self): + return [ + mock.patch( + "rally.osclients.Clients", + mock.Mock(side_effect=self.context_client)) + ] + + class FakeClientsScenarioTestCase(ScenarioTestCase): """Base class for Scenario tests using fake (not mocked) self.clients."""