From 8954959817332ef4002e6bad20edb8e77a8f096b Mon Sep 17 00:00:00 2001 From: Charles Short Date: Sat, 19 May 2018 15:24:30 +0000 Subject: [PATCH] Introduce ''mock_object'' method to base test class We would like to fully remove mox from the test tree. Even for tests that don't use mox's validation, many of them are using the symbol patching with self.stubs.Set. We can do the same thing with the monkeypatch fixture instead. This introduces self.stub_out to nova/test.py and an example of what a stubs => stub_out change would look like. The teardown function in the converted test was removed at the same time, as those should no longer be used. Part of the mox community goal for Rocky. Change-Id: I8f471ff8fee600ebb4e8907bf240007b7b4fe59f Signed-off-by: Chuck Short --- glance/tests/functional/db/test_sqlalchemy.py | 8 ++-- glance/tests/integration/v2/base.py | 5 ++- glance/tests/unit/api/test_cmd.py | 41 ++++++++----------- glance/tests/unit/base.py | 12 ++++++ glance/tests/unit/common/test_config.py | 3 -- .../unit/common/test_location_strategy.py | 28 +++++++------ glance/tests/unit/common/test_wsgi.py | 9 ++-- glance/tests/unit/test_auth.py | 11 ++--- glance/tests/unit/test_image_cache.py | 5 +-- glance/tests/unit/test_policy.py | 19 ++++++++- glance/tests/unit/test_quota.py | 22 ++++++---- glance/tests/unit/test_store_image.py | 16 ++++---- glance/tests/unit/test_store_location.py | 4 +- .../tests/unit/v2/test_image_data_resource.py | 12 ++++-- glance/tests/unit/v2/test_images_resource.py | 25 ++++++----- glance/tests/unit/v2/test_registry_client.py | 2 +- glance/tests/utils.py | 16 +++++++- 17 files changed, 142 insertions(+), 96 deletions(-) diff --git a/glance/tests/functional/db/test_sqlalchemy.py b/glance/tests/functional/db/test_sqlalchemy.py index 57070b2b05..102bd2e785 100644 --- a/glance/tests/functional/db/test_sqlalchemy.py +++ b/glance/tests/functional/db/test_sqlalchemy.py @@ -117,8 +117,8 @@ class TestSqlAlchemyDBDataIntegrity(base.TestDriver, return original_method(query, model, limit, sort_keys, marker, sort_dir, sort_dirs) - self.stubs.Set(self.db_api, '_paginate_query', - fake_paginate_query) + self.mock_object(self.db_api, '_paginate_query', + fake_paginate_query) self.db_api.image_get_all(self.context, sort_key=['created_at']) def test_paginate_non_redundant_sort_keys(self): @@ -130,8 +130,8 @@ class TestSqlAlchemyDBDataIntegrity(base.TestDriver, return original_method(query, model, limit, sort_keys, marker, sort_dir, sort_dirs) - self.stubs.Set(self.db_api, '_paginate_query', - fake_paginate_query) + self.mock_object(self.db_api, '_paginate_query', + fake_paginate_query) self.db_api.image_get_all(self.context, sort_key=['name']) diff --git a/glance/tests/integration/v2/base.py b/glance/tests/integration/v2/base.py index f38c4e5721..22771024a7 100644 --- a/glance/tests/integration/v2/base.py +++ b/glance/tests/integration/v2/base.py @@ -117,6 +117,7 @@ CONF = cfg.CONF class ApiTest(test_utils.BaseTestCase): + def setUp(self): super(ApiTest, self).setUp() self.test_dir = self.useFixture(fixtures.TempDir()).path @@ -209,8 +210,8 @@ class ApiTest(test_utils.BaseTestCase): return test_utils.HttplibWsgiAdapter(self.glance_registry_app) return wrapped - self.stubs.Set(glance.common.client.BaseClient, - 'get_connection_type', get_connection_type) + self.mock_object(glance.common.client.BaseClient, + 'get_connection_type', get_connection_type) def tearDown(self): glance.db.sqlalchemy.api.clear_db_env() diff --git a/glance/tests/unit/api/test_cmd.py b/glance/tests/unit/api/test_cmd.py index ca21f453c1..788673a78c 100644 --- a/glance/tests/unit/api/test_cmd.py +++ b/glance/tests/unit/api/test_cmd.py @@ -52,19 +52,12 @@ class TestGlanceApiCmd(test_utils.BaseTestCase): store.register_opts(CONF) - self.config_patcher = mock.patch( - 'glance.common.config.load_paste_app', - side_effect=self._do_nothing) - self.start_patcher = mock.patch('glance.common.wsgi.Server.start', - side_effect=self._do_nothing) - self.wait_patcher = mock.patch('glance.common.wsgi.Server.wait', - side_effect=self._do_nothing) - - self.addCleanup(mock.patch.stopall) - - self.config_patcher.start() - self.start_patcher.start() - self.wait_patcher.start() + self.mock_object(glance.common.config, 'load_paste_app', + self._do_nothing) + self.mock_object(glance.common.wsgi.Server, 'start', + self._do_nothing) + self.mock_object(glance.common.wsgi.Server, 'wait', + self._do_nothing) def tearDown(self): sys.stderr = sys.__stderr__ @@ -77,10 +70,10 @@ class TestGlanceApiCmd(test_utils.BaseTestCase): def test_worker_creation_failure(self): failure = exc.WorkerCreationFailure(reason='test') - with mock.patch('glance.common.wsgi.Server.start', - side_effect=self._raise(failure)): - exit = self.assertRaises(SystemExit, glance.cmd.api.main) - self.assertEqual(2, exit.code) + self.mock_object(glance.common.wsgi.Server, 'start', + self._raise(failure)) + exit = self.assertRaises(SystemExit, glance.cmd.api.main) + self.assertEqual(2, exit.code) @mock.patch.object(glance.common.config, 'parse_cache_args') @mock.patch.object(logging, 'setup') @@ -103,12 +96,11 @@ class TestGlanceApiCmd(test_utils.BaseTestCase): mock.call.mock_cache_clean()] self.assertEqual(expected_call_sequence, manager.mock_calls) - @mock.patch.object(glance.image_cache.cleaner.Cleaner, 'run') @mock.patch.object(glance.image_cache.base.CacheApp, '__init__') - def test_cache_cleaner_main_runtime_exception_handling(self, mock_cache, - mock_run): + def test_cache_cleaner_main_runtime_exception_handling(self, mock_cache): mock_cache.return_value = None - mock_run.side_effect = self._raise(RuntimeError) + self.mock_object(glance.image_cache.cleaner.Cleaner, 'run', + self._raise(RuntimeError)) exit = self.assertRaises(SystemExit, glance.cmd.cache_cleaner.main) self.assertEqual('ERROR: ', exit.code) @@ -133,12 +125,11 @@ class TestGlanceApiCmd(test_utils.BaseTestCase): mock.call.mock_cache_prune()] self.assertEqual(expected_call_sequence, manager.mock_calls) - @mock.patch.object(glance.image_cache.pruner.Pruner, 'run') @mock.patch.object(glance.image_cache.base.CacheApp, '__init__') - def test_cache_pruner_main_runtime_exception_handling(self, mock_cache, - mock_run): + def test_cache_pruner_main_runtime_exception_handling(self, mock_cache): mock_cache.return_value = None - mock_run.side_effect = self._raise(RuntimeError) + self.mock_object(glance.image_cache.pruner.Pruner, 'run', + self._raise(RuntimeError)) exit = self.assertRaises(SystemExit, glance.cmd.cache_pruner.main) self.assertEqual('ERROR: ', exit.code) diff --git a/glance/tests/unit/base.py b/glance/tests/unit/base.py index 1cd992bf07..69de6fa5ba 100644 --- a/glance/tests/unit/base.py +++ b/glance/tests/unit/base.py @@ -17,6 +17,7 @@ import os import glance_store as store from glance_store import location +import mock from oslo_concurrency import lockutils from oslo_config import cfg from oslo_db import options @@ -134,3 +135,14 @@ class MultiIsolatedUnitTest(MultiStoreClearingUnitTest): fap = open(CONF.oslo_policy.policy_file, 'w') fap.write(jsonutils.dumps(rules)) fap.close() + + def mock_object(self, obj, attr_name, *args, **kwargs): + """Use python mock to mock an object attribute + + Mocks the specified objects attribute with the given value. + Automatically performs 'addCleanup' for the mock. + """ + patcher = mock.patch.object(obj, attr_name, *args, **kwargs) + result = patcher.start() + self.addCleanup(patcher.stop) + return result diff --git a/glance/tests/unit/common/test_config.py b/glance/tests/unit/common/test_config.py index d91c55f0a7..b3e4d67941 100644 --- a/glance/tests/unit/common/test_config.py +++ b/glance/tests/unit/common/test_config.py @@ -18,7 +18,6 @@ import shutil import fixtures import oslo_middleware -from oslotest import moxstubout from glance.api.middleware import context from glance.common import config @@ -29,8 +28,6 @@ class TestPasteApp(test_utils.BaseTestCase): def setUp(self): super(TestPasteApp, self).setUp() - mox_fixture = self.useFixture(moxstubout.MoxStubout()) - self.stubs = mox_fixture.stubs def _do_test_load_paste_app(self, expected_app_type, diff --git a/glance/tests/unit/common/test_location_strategy.py b/glance/tests/unit/common/test_location_strategy.py index bef1a9f923..1b47bc65fe 100644 --- a/glance/tests/unit/common/test_location_strategy.py +++ b/glance/tests/unit/common/test_location_strategy.py @@ -48,12 +48,14 @@ class TestLocationStrategy(base.IsolatedUnitTest): modules = ['module1', 'module2'] def _fake_stevedore_extension_manager(*args, **kwargs): - ret = lambda: None + def ret(): + return None ret.names = lambda: modules return ret def _fake_stevedore_driver_manager(*args, **kwargs): - ret = lambda: None + def ret(): + return None ret.driver = lambda: None ret.driver.__name__ = kwargs['name'] # Module 1 and 2 has a same strategy name @@ -61,10 +63,10 @@ class TestLocationStrategy(base.IsolatedUnitTest): ret.driver.init = lambda: None return ret - self.stub = self.stubs.Set(stevedore.extension, "ExtensionManager", - _fake_stevedore_extension_manager) - self.stub = self.stubs.Set(stevedore.driver, "DriverManager", - _fake_stevedore_driver_manager) + self.stub = self.mock_object(stevedore.extension, "ExtensionManager", + _fake_stevedore_extension_manager) + self.stub = self.mock_object(stevedore.driver, "DriverManager", + _fake_stevedore_driver_manager) loaded_modules = location_strategy._load_strategies() self.assertEqual(1, len(loaded_modules)) @@ -76,7 +78,8 @@ class TestLocationStrategy(base.IsolatedUnitTest): modules = ['module_init_exception', 'module_good'] def _fake_stevedore_extension_manager(*args, **kwargs): - ret = lambda: None + def ret(): + return None ret.names = lambda: modules return ret @@ -84,17 +87,18 @@ class TestLocationStrategy(base.IsolatedUnitTest): if kwargs['name'] == 'module_init_exception': raise Exception('strategy module failed to initialize.') else: - ret = lambda: None + def ret(): + return None ret.driver = lambda: None ret.driver.__name__ = kwargs['name'] ret.driver.get_strategy_name = lambda: kwargs['name'] ret.driver.init = lambda: None return ret - self.stub = self.stubs.Set(stevedore.extension, "ExtensionManager", - _fake_stevedore_extension_manager) - self.stub = self.stubs.Set(stevedore.driver, "DriverManager", - _fake_stevedore_driver_manager) + self.stub = self.mock_object(stevedore.extension, "ExtensionManager", + _fake_stevedore_extension_manager) + self.stub = self.mock_object(stevedore.driver, "DriverManager", + _fake_stevedore_driver_manager) loaded_modules = location_strategy._load_strategies() self.assertEqual(1, len(loaded_modules)) diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py index 3b348f178f..adda23e11d 100644 --- a/glance/tests/unit/common/test_wsgi.py +++ b/glance/tests/unit/common/test_wsgi.py @@ -49,7 +49,8 @@ class RequestTest(test_utils.BaseTestCase): def returns_some_locales(*args, **kwargs): return all_locales - self.stubs.Set(localedata, 'locale_identifiers', returns_some_locales) + self.mock_object(localedata, 'locale_identifiers', + returns_some_locales) # Override gettext.find to return other than None for some languages. def fake_gettext_find(lang_id, *args, **kwargs): @@ -62,7 +63,7 @@ class RequestTest(test_utils.BaseTestCase): return found_ret return None - self.stubs.Set(gettext, 'find', fake_gettext_find) + self.mock_object(gettext, 'find', fake_gettext_find) def test_content_range(self): request = wsgi.Request.blank('/tests/123') @@ -338,7 +339,7 @@ class ResourceTest(test_utils.BaseTestCase): if isinstance(obj, wsgi.JSONResponseSerializer): raise webob.exc.HTTPForbidden() - self.stubs.Set(wsgi.Resource, 'dispatch', dispatch) + self.mock_object(wsgi.Resource, 'dispatch', dispatch) request = wsgi.Request.blank('/') @@ -357,7 +358,7 @@ class ResourceTest(test_utils.BaseTestCase): def dispatch(self, obj, action, *args, **kwargs): raise Exception("test exception") - self.stubs.Set(wsgi.Resource, 'dispatch', dispatch) + self.mock_object(wsgi.Resource, 'dispatch', dispatch) request = wsgi.Request.blank('/') diff --git a/glance/tests/unit/test_auth.py b/glance/tests/unit/test_auth.py index 4807f14de7..f3600e9978 100644 --- a/glance/tests/unit/test_auth.py +++ b/glance/tests/unit/test_auth.py @@ -15,7 +15,6 @@ # under the License. from oslo_serialization import jsonutils -from oslotest import moxstubout from six.moves import http_client as http import webob @@ -123,8 +122,6 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase): def setUp(self): super(TestKeystoneAuthPlugin, self).setUp() - mox_fixture = self.useFixture(moxstubout.MoxStubout()) - self.stubs = mox_fixture.stubs def test_get_plugin_from_strategy_keystone(self): strategy = auth.get_plugin_from_strategy('keystone') @@ -200,7 +197,7 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase): resp.status = http.BAD_REQUEST return FakeResponse(resp), "" - self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) + self.mock_object(auth.KeystoneStrategy, '_do_request', fake_do_request) bad_creds = { 'username': 'user1', @@ -222,7 +219,7 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase): resp.status = http.BAD_REQUEST return FakeResponse(resp), "" - self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) + self.mock_object(auth.KeystoneStrategy, '_do_request', fake_do_request) bad_creds = { 'username': 'user1', @@ -254,7 +251,7 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase): return FakeResponse(resp), "" - self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) + self.mock_object(auth.KeystoneStrategy, '_do_request', fake_do_request) unauthorized_creds = [ { @@ -344,7 +341,7 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase): mock_token = V2Token() mock_token.add_service('image', ['RegionOne']) - self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) + self.mock_object(auth.KeystoneStrategy, '_do_request', fake_do_request) unauthorized_creds = [ { diff --git a/glance/tests/unit/test_image_cache.py b/glance/tests/unit/test_image_cache.py index f77e9ae5a2..8226d60d47 100644 --- a/glance/tests/unit/test_image_cache.py +++ b/glance/tests/unit/test_image_cache.py @@ -23,7 +23,6 @@ import time import fixtures from oslo_utils import units -from oslotest import moxstubout import six # NOTE(jokke): simplified transition to py3, behaves like py2 xrange from six.moves import range @@ -518,9 +517,7 @@ class TestImageCacheNoDep(test_utils.BaseTestCase): def init_driver(self2): self2.driver = self.driver - mox_fixture = self.useFixture(moxstubout.MoxStubout()) - self.stubs = mox_fixture.stubs - self.stubs.Set(image_cache.ImageCache, 'init_driver', init_driver) + self.mock_object(image_cache.ImageCache, 'init_driver', init_driver) def test_get_caching_iter_when_write_fails(self): diff --git a/glance/tests/unit/test_policy.py b/glance/tests/unit/test_policy.py index b5abca70f1..03de222854 100644 --- a/glance/tests/unit/test_policy.py +++ b/glance/tests/unit/test_policy.py @@ -32,12 +32,14 @@ UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' class IterableMock(mock.Mock, collections.Iterable): + def __iter__(self): while False: yield None class ImageRepoStub(object): + def get(self, *args, **kwargs): return 'image_from_get' @@ -52,6 +54,7 @@ class ImageRepoStub(object): class ImageStub(object): + def __init__(self, image_id=None, visibility='private', container_format='bear', disk_format='raw', status='active', extra_properties=None, @@ -87,6 +90,7 @@ class ImageStub(object): class ImageFactoryStub(object): + def new_image(self, image_id=None, name=None, visibility='private', min_disk=0, min_ram=0, protected=False, owner=None, disk_format=None, container_format=None, @@ -117,11 +121,13 @@ class MemberRepoStub(object): class ImageMembershipStub(object): + def __init__(self, output=None): self.output = output class TaskRepoStub(object): + def get(self, *args, **kwargs): return 'task_from_get' @@ -133,6 +139,7 @@ class TaskRepoStub(object): class TaskStub(object): + def __init__(self, task_id): self.task_id = task_id self.status = 'pending' @@ -142,11 +149,13 @@ class TaskStub(object): class TaskFactoryStub(object): + def new_task(self, *args): return 'new_task' class TestPolicyEnforcer(base.IsolatedUnitTest): + def test_policy_file_default_rules_default_location(self): enforcer = glance.api.policy.Enforcer() @@ -209,6 +218,7 @@ class TestPolicyEnforcer(base.IsolatedUnitTest): class TestPolicyEnforcerNoFile(base.IsolatedUnitTest): + def test_policy_file_specified_but_not_found(self): """Missing defined policy file should result in a default ruleset""" self.config(policy_file='gobble.gobble', group='oslo_policy') @@ -223,11 +233,12 @@ class TestPolicyEnforcerNoFile(base.IsolatedUnitTest): def test_policy_file_default_not_found(self): """Missing default policy file should result in a default ruleset""" + def fake_find_file(self, name): return None - self.stubs.Set(oslo_config.cfg.ConfigOpts, 'find_file', - fake_find_file) + self.mock_object(oslo_config.cfg.ConfigOpts, 'find_file', + fake_find_file) enforcer = glance.api.policy.Enforcer() @@ -240,6 +251,7 @@ class TestPolicyEnforcerNoFile(base.IsolatedUnitTest): class TestImagePolicy(test_utils.BaseTestCase): + def setUp(self): self.image_stub = ImageStub(UUID1) self.image_repo_stub = ImageRepoStub() @@ -416,6 +428,7 @@ class TestImagePolicy(test_utils.BaseTestCase): class TestMemberPolicy(test_utils.BaseTestCase): + def setUp(self): self.policy = mock.Mock() self.policy.enforce = mock.Mock() @@ -491,6 +504,7 @@ class TestMemberPolicy(test_utils.BaseTestCase): class TestTaskPolicy(test_utils.BaseTestCase): + def setUp(self): self.task_stub = TaskStub(UUID1) self.task_repo_stub = TaskRepoStub() @@ -569,6 +583,7 @@ class TestTaskPolicy(test_utils.BaseTestCase): class TestContextPolicyEnforcer(base.IsolatedUnitTest): + def _do_test_policy_influence_context_admin(self, policy_admin_role, context_role, diff --git a/glance/tests/unit/test_quota.py b/glance/tests/unit/test_quota.py index 6419adc6c6..f024de98d1 100644 --- a/glance/tests/unit/test_quota.py +++ b/glance/tests/unit/test_quota.py @@ -52,6 +52,7 @@ class FakeImage(object): class TestImageQuota(test_utils.BaseTestCase): + def setUp(self): super(TestImageQuota, self).setUp() @@ -283,8 +284,8 @@ class TestImageQuota(test_utils.BaseTestCase): image = glance.quota.ImageProxy(base_image, context, db_api, store) self.assertIsNone(image.size) - self.stubs.Set(store_api, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store_api, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) image.locations.append({'url': 'file:///fake.img.tar.gz', 'metadata': {}}) self.assertIn({'url': 'file:///fake.img.tar.gz', 'metadata': {}}, @@ -300,8 +301,8 @@ class TestImageQuota(test_utils.BaseTestCase): image = glance.quota.ImageProxy(base_image, context, db_api, store) self.assertIsNone(image.size) - self.stubs.Set(store_api, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store_api, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) image.locations.insert(0, {'url': 'file:///fake.img.tar.gz', 'metadata': {}}) @@ -318,8 +319,8 @@ class TestImageQuota(test_utils.BaseTestCase): image = glance.quota.ImageProxy(base_image, context, db_api, store) self.assertIsNone(image.size) - self.stubs.Set(store_api, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store_api, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) image.locations = [{'url': 'file:///fake.img.tar.gz', 'metadata': {}}] self.assertEqual([{'url': 'file:///fake.img.tar.gz', 'metadata': {}}], image.locations) @@ -334,14 +335,15 @@ class TestImageQuota(test_utils.BaseTestCase): image = glance.quota.ImageProxy(base_image, context, db_api, store) self.assertIsNone(image.size) - self.stubs.Set(store_api, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store_api, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) image.locations += [{'url': 'file:///fake.img.tar.gz', 'metadata': {}}] self.assertIn({'url': 'file:///fake.img.tar.gz', 'metadata': {}}, image.locations) class TestImagePropertyQuotas(test_utils.BaseTestCase): + def setUp(self): super(TestImagePropertyQuotas, self).setUp() self.base_image = FakeImage() @@ -485,6 +487,7 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase): class TestImageTagQuotas(test_utils.BaseTestCase): + def setUp(self): super(TestImageTagQuotas, self).setUp() self.base_image = mock.Mock() @@ -549,6 +552,7 @@ class TestImageTagQuotas(test_utils.BaseTestCase): class TestQuotaImageTagsProxy(test_utils.BaseTestCase): + def setUp(self): super(TestQuotaImageTagsProxy, self).setUp() @@ -594,6 +598,7 @@ class TestQuotaImageTagsProxy(test_utils.BaseTestCase): class TestImageMemberQuotas(test_utils.BaseTestCase): + def setUp(self): super(TestImageMemberQuotas, self).setUp() db_api = unit_test_utils.FakeDB() @@ -631,6 +636,7 @@ class TestImageMemberQuotas(test_utils.BaseTestCase): class TestImageLocationQuotas(test_utils.BaseTestCase): + def setUp(self): super(TestImageLocationQuotas, self).setUp() self.base_image = mock.Mock() diff --git a/glance/tests/unit/test_store_image.py b/glance/tests/unit/test_store_image.py index cdf5a9c171..55d734461c 100644 --- a/glance/tests/unit/test_store_image.py +++ b/glance/tests/unit/test_store_image.py @@ -128,8 +128,8 @@ class TestStoreImage(utils.BaseTestCase): self.assertEqual(2, len(image1.locations)) self.assertEqual(UUID2, location_data['url']) - self.stubs.Set(unit_test_utils.FakeStoreAPI, 'get_from_backend', - fake_get_from_backend) + self.mock_object(unit_test_utils.FakeStoreAPI, 'get_from_backend', + fake_get_from_backend) # This time, image1.get_data() returns the data wrapped in a # LimitingReader|CooperativeReader pipeline, so peeking under # the hood of those objects to get at the underlying string. @@ -200,8 +200,8 @@ class TestStoreImage(utils.BaseTestCase): } image_stub = ImageStub(UUID2, status='queued', extra_properties=extra_properties) - self.stubs.Set(signature_utils, 'get_verifier', - unit_test_utils.fake_get_verifier) + self.mock_object(signature_utils, 'get_verifier', + unit_test_utils.fake_get_verifier) image = glance.location.ImageProxy(image_stub, context, self.store_api, self.store_utils) image.set_data('YYYY', 4) @@ -220,8 +220,8 @@ class TestStoreImage(utils.BaseTestCase): } image_stub = ImageStub(UUID2, status='queued', extra_properties=extra_properties) - self.stubs.Set(signature_utils, 'get_verifier', - unit_test_utils.fake_get_verifier) + self.mock_object(signature_utils, 'get_verifier', + unit_test_utils.fake_get_verifier) image = glance.location.ImageProxy(image_stub, context, self.store_api, self.store_utils) with mock.patch.object(self.store_api, @@ -240,8 +240,8 @@ class TestStoreImage(utils.BaseTestCase): } image_stub = ImageStub(UUID2, status='queued', extra_properties=extra_properties) - self.stubs.Set(signature_utils, 'get_verifier', - unit_test_utils.fake_get_verifier) + self.mock_object(signature_utils, 'get_verifier', + unit_test_utils.fake_get_verifier) image = glance.location.ImageProxy(image_stub, context, self.store_api, self.store_utils) image.set_data('YYYY', 4) diff --git a/glance/tests/unit/test_store_location.py b/glance/tests/unit/test_store_location.py index 1d9dbdd7d0..a3db624528 100644 --- a/glance/tests/unit/test_store_location.py +++ b/glance/tests/unit/test_store_location.py @@ -43,8 +43,8 @@ class TestStoreLocation(base.StoreClearingUnitTest): def fake_get_size_from_backend(uri, context=None): return 1 - self.stubs.Set(glance_store, 'get_size_from_backend', - fake_get_size_from_backend) + self.mock_object(glance_store, 'get_size_from_backend', + fake_get_size_from_backend) with mock.patch('glance.location._check_image_location'): loc1 = {'url': 'file:///fake1.img.tar.gz', 'metadata': {}} diff --git a/glance/tests/unit/v2/test_image_data_resource.py b/glance/tests/unit/v2/test_image_data_resource.py index a6e122b349..cd76fe5f11 100644 --- a/glance/tests/unit/v2/test_image_data_resource.py +++ b/glance/tests/unit/v2/test_image_data_resource.py @@ -32,6 +32,7 @@ import glance.tests.utils as test_utils class Raise(object): + def __init__(self, exc): self.exc = exc @@ -40,6 +41,7 @@ class Raise(object): class FakeImage(object): + def __init__(self, image_id=None, data=None, checksum=None, size=0, virtual_size=0, locations=None, container_format='bear', disk_format='rawr', status=None): @@ -76,6 +78,7 @@ class FakeImage(object): class FakeImageRepo(object): + def __init__(self, result=None): self.result = result @@ -90,6 +93,7 @@ class FakeImageRepo(object): class FakeGateway(object): + def __init__(self, db=None, store=None, notifier=None, policy=None, repo=None): self.db = db @@ -103,6 +107,7 @@ class FakeGateway(object): class TestImagesController(base.StoreClearingUnitTest): + def setUp(self): super(TestImagesController, self).setUp() @@ -157,6 +162,7 @@ class TestImagesController(base.StoreClearingUnitTest): def test_download_ok_when_get_image_location_forbidden(self): class ImageLocations(object): + def __len__(self): raise exception.Forbidden() @@ -888,9 +894,9 @@ class TestImageDataSerializer(test_utils.BaseTestCase): def get_data(*args, **kwargs): raise exception.Forbidden() - self.stubs.Set(glance.api.policy.ImageProxy, - 'get_data', - get_data) + self.mock_object(glance.api.policy.ImageProxy, + 'get_data', + get_data) request = wsgi.Request.blank('/') request.environ = {} response = webob.Response() diff --git a/glance/tests/unit/v2/test_images_resource.py b/glance/tests/unit/v2/test_images_resource.py index 1786be233d..83e2caf1ca 100644 --- a/glance/tests/unit/v2/test_images_resource.py +++ b/glance/tests/unit/v2/test_images_resource.py @@ -1973,8 +1973,8 @@ class TestImagesController(base.IsolatedUnitTest): as long as the image has fewer than the limited number of image locations after the transaction. """ - self.stubs.Set(store, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) self.config(show_multiple_locations=True) request = unit_test_utils.get_fake_request() @@ -2039,8 +2039,8 @@ class TestImagesController(base.IsolatedUnitTest): def test_update_remove_location(self): self.config(show_multiple_locations=True) - self.stubs.Set(store, 'get_size_from_backend', - unit_test_utils.fake_get_size_from_backend) + self.mock_object(store, 'get_size_from_backend', + unit_test_utils.fake_get_size_from_backend) request = unit_test_utils.get_fake_request() new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} @@ -2080,8 +2080,9 @@ class TestImagesController(base.IsolatedUnitTest): def fake_delete_image_location_from_backend(self, *args, **kwargs): raise Exception('fake_backend_exception') - self.stubs.Set(self.store_utils, 'delete_image_location_from_backend', - fake_delete_image_location_from_backend) + self.mock_object(self.store_utils, + 'delete_image_location_from_backend', + fake_delete_image_location_from_backend) request = unit_test_utils.get_fake_request() changes = [ @@ -2288,8 +2289,8 @@ class TestImagesController(base.IsolatedUnitTest): def test_delete_in_use(self): def fake_safe_delete_from_backend(self, *args, **kwargs): raise store.exceptions.InUseByStore() - self.stubs.Set(self.store_utils, 'safe_delete_from_backend', - fake_safe_delete_from_backend) + self.mock_object(self.store_utils, 'safe_delete_from_backend', + fake_safe_delete_from_backend) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPConflict, self.controller.delete, request, UUID1) @@ -2297,8 +2298,8 @@ class TestImagesController(base.IsolatedUnitTest): def test_delete_has_snapshot(self): def fake_safe_delete_from_backend(self, *args, **kwargs): raise store.exceptions.HasSnapshot() - self.stubs.Set(self.store_utils, 'safe_delete_from_backend', - fake_safe_delete_from_backend) + self.mock_object(self.store_utils, 'safe_delete_from_backend', + fake_safe_delete_from_backend) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPConflict, self.controller.delete, request, UUID1) @@ -3584,6 +3585,7 @@ class TestImagesSerializer(test_utils.BaseTestCase): """ class ImageLocations(object): + def __len__(self): raise exception.Forbidden() @@ -4140,6 +4142,7 @@ class TestImagesSerializerWithAdditionalProperties(test_utils.BaseTestCase): class TestImagesSerializerDirectUrl(test_utils.BaseTestCase): + def setUp(self): super(TestImagesSerializerDirectUrl, self).setUp() self.serializer = glance.api.v2.images.ResponseSerializer() @@ -4225,6 +4228,7 @@ class TestImagesSerializerDirectUrl(test_utils.BaseTestCase): class TestImageSchemaFormatConfiguration(test_utils.BaseTestCase): + def test_default_disk_formats(self): schema = glance.api.v2.images.get_schema() expected = [None, 'ami', 'ari', 'aki', 'vhd', 'vhdx', 'vmdk', @@ -4254,6 +4258,7 @@ class TestImageSchemaFormatConfiguration(test_utils.BaseTestCase): class TestImageSchemaDeterminePropertyBasis(test_utils.BaseTestCase): + def test_custom_property_marked_as_non_base(self): self.config(allow_additional_image_properties=False) custom_image_properties = { diff --git a/glance/tests/unit/v2/test_registry_client.py b/glance/tests/unit/v2/test_registry_client.py index 6d5b11bc97..2401dd54e1 100644 --- a/glance/tests/unit/v2/test_registry_client.py +++ b/glance/tests/unit/v2/test_registry_client.py @@ -759,7 +759,7 @@ class TestRegistryV2ClientApi(base.IsolatedUnitTest): self.config(admin_tenant_name=expected['tenant']) self.config(auth_strategy=expected['strategy']) self.config(auth_region=expected['region']) - self.stubs.Set(os, 'getenv', lambda x: None) + self.mock_object(os, 'getenv', lambda x: None) self.assertIsNone(rapi._CLIENT_CREDS) rapi.configure_registry_admin_creds() diff --git a/glance/tests/utils.py b/glance/tests/utils.py index 056c449c98..0b0d143b02 100644 --- a/glance/tests/utils.py +++ b/glance/tests/utils.py @@ -25,6 +25,7 @@ import subprocess from alembic import command as alembic_command import fixtures +import mock from oslo_config import cfg from oslo_config import fixture as cfg_fixture from oslo_log.fixture import logging_error as log_fixture @@ -79,7 +80,7 @@ class BaseTestCase(testtools.TestCase): self.addCleanup(CONF.reset) mox_fixture = self.useFixture(moxstubout.MoxStubout()) self.stubs = mox_fixture.stubs - self.stubs.Set(exception, '_FATAL_EXCEPTION_FORMAT_ERRORS', True) + self.mock_object(exception, '_FATAL_EXCEPTION_FORMAT_ERRORS', True) self.test_dir = self.useFixture(fixtures.TempDir()).path self.conf_dir = os.path.join(self.test_dir, 'etc') utils.safe_mkdirs(self.conf_dir) @@ -139,9 +140,21 @@ class BaseTestCase(testtools.TestCase): """ self._config_fixture.config(**kw) + def mock_object(self, obj, attr_name, *args, **kwargs): + """"Use python mock to mock an object attirbute + + Mocks the specified objects attribute with the given value. + Automatically performs 'addCleanup' for the mock. + """ + patcher = mock.patch.object(obj, attr_name, *args, **kwargs) + result = patcher.start() + self.addCleanup(patcher.stop) + return result + class requires(object): """Decorator that initiates additional test setup/teardown.""" + def __init__(self, setup=None, teardown=None): self.setup = setup self.teardown = teardown @@ -160,6 +173,7 @@ class requires(object): class depends_on_exe(object): """Decorator to skip test if an executable is unavailable""" + def __init__(self, exe): self.exe = exe