From 0e68cf94dd3302da4efe6e6b420629dd65ba229a Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Tue, 10 Nov 2015 15:45:29 -0800 Subject: [PATCH] Fix cinder objects unit test registration The base test case was extending test code from oslo_versionedobjects which is bad because (1) it was adding test objects from the o.vo registry into the cinder object registry and (2) it was extending internal private test classes from o.vo which are subject to change and would break cinder. This cleans up the base test case and object registration to basically do it the same way that nova does. It also moves the duplicate _compare() method into the base class and fixes a bug where db obj fields that were lists were compared incorrectly against object lists. This will allow us to verify object version hashes using o.vo's ObjectVersionChecker fixture in a follow on change without the extraneous object registrations from o.vo messing with the results. Partial-Bug: #1514926 Change-Id: Ie34675e378951cda9aa218f3181dc86767717450 --- cinder/test.py | 4 -- cinder/tests/unit/__init__.py | 11 +++++ cinder/tests/unit/objects/__init__.py | 49 +++++++++++++++++-- cinder/tests/unit/objects/test_backup.py | 13 ----- cinder/tests/unit/objects/test_cgsnapshot.py | 15 ------ .../unit/objects/test_consistencygroup.py | 15 ------ cinder/tests/unit/objects/test_service.py | 20 -------- cinder/tests/unit/objects/test_snapshot.py | 5 -- cinder/tests/unit/objects/test_volume.py | 15 ------ .../unit/objects/test_volume_attachment.py | 4 -- cinder/tests/unit/objects/test_volume_type.py | 13 ----- 11 files changed, 55 insertions(+), 109 deletions(-) diff --git a/cinder/test.py b/cinder/test.py index d0601802a..a06e44394 100644 --- a/cinder/test.py +++ b/cinder/test.py @@ -42,7 +42,6 @@ from cinder.common import config # noqa Need to register global_opts from cinder.db import migration from cinder.db.sqlalchemy import api as sqla_api from cinder import i18n -from cinder import objects from cinder import rpc from cinder import service from cinder.tests.unit import conf_fixture @@ -149,9 +148,6 @@ class TestCase(testtools.TestCase): side_effect=self._get_joined_notifier) p.start() - # Import cinder objects for test cases - objects.register_all() - # Unit tests do not need to use lazy gettext i18n.enable_lazy(False) diff --git a/cinder/tests/unit/__init__.py b/cinder/tests/unit/__init__.py index 35f2079f6..f59fa3d6e 100644 --- a/cinder/tests/unit/__init__.py +++ b/cinder/tests/unit/__init__.py @@ -31,8 +31,19 @@ import eventlet from six.moves import builtins +from cinder import objects + eventlet.monkey_patch() # See http://code.google.com/p/python-nose/issues/detail?id=373 # The code below enables nosetests to work with i18n _() blocks setattr(builtins, '_', lambda x: x) + +# NOTE(alaski): Make sure this is done after eventlet monkey patching otherwise +# the threading.local() store used in oslo_messaging will be initialized to +# threadlocal storage rather than greenthread local. This will cause context +# sets and deletes in that storage to clobber each other. +# NOTE(comstud): Make sure we have all of the objects loaded. We do this +# at module import time, because we may be using mock decorators in our +# tests that run at import time. +objects.register_all() diff --git a/cinder/tests/unit/objects/__init__.py b/cinder/tests/unit/objects/__init__.py index b62125f9a..c697b391d 100644 --- a/cinder/tests/unit/objects/__init__.py +++ b/cinder/tests/unit/objects/__init__.py @@ -1,10 +1,49 @@ -from oslo_versionedobjects.tests import test_objects +# Copyright 2015 IBM Corp. +# +# 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 cinder import objects +from oslo_utils import timeutils +from cinder import context +from cinder.objects import base as obj_base +from cinder import test -class BaseObjectsTestCase(test_objects._LocalTest): + +class BaseObjectsTestCase(test.TestCase): def setUp(self): super(BaseObjectsTestCase, self).setUp() - # Import cinder objects for test cases - objects.register_all() + self.user_id = 'fake-user' + self.project_id = 'fake-project' + self.context = context.RequestContext(self.user_id, self.project_id, + is_admin=False) + # We only test local right now. + # TODO(mriedem): Testing remote would be nice... + self.assertIsNone(obj_base.CinderObject.indirection_api) + + # TODO(mriedem): Replace this with + # oslo_versionedobjects.fixture.compare_obj when that is in a released + # version of o.vo. + @staticmethod + def _compare(test, db, obj): + for field, value in db.items(): + if not hasattr(obj, field): + continue + + if field in ('modified_at', 'created_at', + 'updated_at', 'deleted_at') and db[field]: + test.assertEqual(db[field], + timeutils.normalize_time(obj[field])) + elif isinstance(obj[field], obj_base.ObjectListBase): + test.assertEqual(db[field], obj[field].objects) + else: + test.assertEqual(db[field], obj[field]) diff --git a/cinder/tests/unit/objects/test_backup.py b/cinder/tests/unit/objects/test_backup.py index 9ebb50c8d..e5ba470b7 100644 --- a/cinder/tests/unit/objects/test_backup.py +++ b/cinder/tests/unit/objects/test_backup.py @@ -14,7 +14,6 @@ import mock -from cinder import context from cinder import exception from cinder import objects from cinder.tests.unit import fake_volume @@ -37,18 +36,6 @@ fake_backup = { class TestBackup(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestBackup, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - test.assertEqual(db[field], obj[field]) @mock.patch('cinder.db.backup_get', return_value=fake_backup) def test_get_by_id(self, backup_get): diff --git a/cinder/tests/unit/objects/test_cgsnapshot.py b/cinder/tests/unit/objects/test_cgsnapshot.py index d72225084..b846df237 100644 --- a/cinder/tests/unit/objects/test_cgsnapshot.py +++ b/cinder/tests/unit/objects/test_cgsnapshot.py @@ -14,7 +14,6 @@ import mock -from cinder import context from cinder import exception from cinder import objects from cinder.tests.unit import objects as test_objects @@ -33,20 +32,6 @@ fake_cgsnapshot = { class TestCGSnapshot(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestCGSnapshot, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.user_id = 123 - self.project_id = 456 - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - test.assertEqual(db[field], getattr(obj, field)) @mock.patch('cinder.db.cgsnapshot_get', return_value=fake_cgsnapshot) diff --git a/cinder/tests/unit/objects/test_consistencygroup.py b/cinder/tests/unit/objects/test_consistencygroup.py index 0f24a30a2..9743e3c3b 100644 --- a/cinder/tests/unit/objects/test_consistencygroup.py +++ b/cinder/tests/unit/objects/test_consistencygroup.py @@ -14,7 +14,6 @@ import mock -from cinder import context from cinder import exception from cinder import objects from cinder.tests.unit import objects as test_objects @@ -35,20 +34,6 @@ fake_consistencygroup = { class TestConsistencyGroup(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestConsistencyGroup, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.user_id = 123 - self.project_id = 456 - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - test.assertEqual(db[field], getattr(obj, field)) @mock.patch('cinder.db.consistencygroup_get', return_value=fake_consistencygroup) diff --git a/cinder/tests/unit/objects/test_service.py b/cinder/tests/unit/objects/test_service.py index b91ef3d02..89f073971 100644 --- a/cinder/tests/unit/objects/test_service.py +++ b/cinder/tests/unit/objects/test_service.py @@ -14,32 +14,12 @@ import mock -from oslo_utils import timeutils - -from cinder import context from cinder import objects from cinder.tests.unit import fake_service from cinder.tests.unit import objects as test_objects class TestService(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestService, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - if field in ('modified_at', 'created_at', - 'updated_at', 'deleted_at') and db[field]: - test.assertEqual(db[field], - timeutils.normalize_time(obj[field])) - else: - test.assertEqual(db[field], obj[field]) @mock.patch('cinder.db.service_get') def test_get_by_id(self, service_get): diff --git a/cinder/tests/unit/objects/test_snapshot.py b/cinder/tests/unit/objects/test_snapshot.py index e0efce88b..3237d26e4 100644 --- a/cinder/tests/unit/objects/test_snapshot.py +++ b/cinder/tests/unit/objects/test_snapshot.py @@ -47,11 +47,6 @@ fake_snapshot_obj = { class TestSnapshot(test_objects.BaseObjectsTestCase): - @staticmethod - def _compare(test, expected, actual): - for field, value in expected.items(): - test.assertEqual(expected[field], actual[field], - "Field '%s' is not equal" % field) @mock.patch('cinder.db.snapshot_get', return_value=fake_db_snapshot) def test_get_by_id(self, snapshot_get): diff --git a/cinder/tests/unit/objects/test_volume.py b/cinder/tests/unit/objects/test_volume.py index 8cadcafde..d50f0b79f 100644 --- a/cinder/tests/unit/objects/test_volume.py +++ b/cinder/tests/unit/objects/test_volume.py @@ -21,21 +21,6 @@ from cinder.tests.unit import objects as test_objects class TestVolume(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestVolume, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - if not hasattr(obj, field): - continue - - test.assertEqual(db[field], obj[field]) @mock.patch('cinder.db.volume_glance_metadata_get', return_value={}) @mock.patch('cinder.db.volume_get') diff --git a/cinder/tests/unit/objects/test_volume_attachment.py b/cinder/tests/unit/objects/test_volume_attachment.py index bce660696..0bd8c2ec4 100644 --- a/cinder/tests/unit/objects/test_volume_attachment.py +++ b/cinder/tests/unit/objects/test_volume_attachment.py @@ -20,10 +20,6 @@ from cinder.tests.unit import objects as test_objects class TestVolumeAttachment(test_objects.BaseObjectsTestCase): - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - test.assertEqual(db[field], obj[field]) @mock.patch('cinder.db.volume_attachment_get') def test_get_by_id(self, volume_attachment_get): diff --git a/cinder/tests/unit/objects/test_volume_type.py b/cinder/tests/unit/objects/test_volume_type.py index d0453513c..ad22bd36c 100644 --- a/cinder/tests/unit/objects/test_volume_type.py +++ b/cinder/tests/unit/objects/test_volume_type.py @@ -14,25 +14,12 @@ import mock -from cinder import context from cinder import objects from cinder.tests.unit import fake_volume from cinder.tests.unit import objects as test_objects class TestVolumeType(test_objects.BaseObjectsTestCase): - def setUp(self): - super(TestVolumeType, self).setUp() - # NOTE (e0ne): base tests contains original RequestContext from - # oslo_context. We change it to our RequestContext implementation - # to have 'elevated' method - self.context = context.RequestContext(self.user_id, self.project_id, - is_admin=False) - - @staticmethod - def _compare(test, db, obj): - for field, value in db.items(): - test.assertEqual(db[field], obj[field]) @mock.patch('cinder.db.volume_type_get') def test_get_by_id(self, volume_type_get): -- 2.45.2