Add temporary registry pattern to VersionedObjectRegistry

There is a temp registry pattern [1] where you can backup the object
registry, register a class locally, and then restore the original
registry. This could be used for test objects that do not need to be
registered permanently but will have calls which lookup registration.
The FakeResource object in patch [2] is such a use case.

This change is to wrap the pattern rather than accessing
oslo.versionedobjects library internals.

[1] https://review.openstack.org/#/c/243826/4/cinder/test.py
[2] https://review.openstack.org/#/c/258026/

Change-Id: I02036becb32f8d3d11170c71e14e0a2db55d1f76
This commit is contained in:
Martin Hickey 2016-01-18 15:27:08 +00:00
parent 6e801d1c03
commit 37005c310e
2 changed files with 67 additions and 0 deletions
oslo_versionedobjects

@ -21,6 +21,7 @@
"""
from collections import OrderedDict
import copy
import datetime
import hashlib
import inspect
@ -350,3 +351,27 @@ class ObjectVersionChecker(object):
obj_classes = self.obj_classes[obj_name]
for obj_class in obj_classes:
self._test_relationships_in_order(obj_class)
class VersionedObjectRegistryFixture(fixtures.Fixture):
"""Use a VersionedObjectRegistry as a temp registry pattern fixture.
The pattern solution is to backup the object registry, register
a class locally, and then restore the original registry. This could be
used for test objects that do not need to be registered permanently but
will have calls which lookup registration.
"""
def setUp(self):
super(VersionedObjectRegistryFixture, self).setUp()
self._base_test_obj_backup = copy.deepcopy(
base.VersionedObjectRegistry._registry._obj_classes)
self.addCleanup(self._restore_obj_registry)
@staticmethod
def register(cls_name):
base.VersionedObjectRegistry.register(cls_name)
def _restore_obj_registry(self):
base.VersionedObjectRegistry._registry._obj_classes = \
self._base_test_obj_backup

@ -22,6 +22,7 @@ import mock
import six
from oslo_versionedobjects import base
from oslo_versionedobjects import exception
from oslo_versionedobjects import fields
from oslo_versionedobjects import fixture
from oslo_versionedobjects import test
@ -140,6 +141,15 @@ class TestObjectComparators(test.TestCase):
replaced_dt)
class FakeResource(base.VersionedObject):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'identifier': fields.Field(fields.Integer(), default=123)
}
class TestObjectVersionChecker(test.TestCase):
def setUp(self):
super(TestObjectVersionChecker, self).setUp()
@ -551,3 +561,35 @@ class TestObjectVersionChecker(test.TestCase):
deps = tree.get(parent_cls.__name__, {})
deps[child_cls.__name__] = '1.0'
tree[parent_cls.__name__] = deps
class TestVersionedObjectRegistryFixture(test.TestCase):
primitive = {'versioned_object.name': 'FakeResource',
'versioned_object.namespace': 'versionedobjects',
'versioned_object.version': '1.0',
'versioned_object.data': {'identifier': 123}}
def test_object_registered_temporarily(self):
# Test object that has not been registered
self.assertRaises(
exception.UnsupportedObjectError,
FakeResource.obj_from_primitive,
self.primitive)
with fixture.VersionedObjectRegistryFixture() as obj_registry:
# Register object locally
obj_registry.setUp()
obj_registry.register(FakeResource)
# Test object has now been registered
obj = FakeResource.obj_from_primitive(
self.primitive)
self.assertEqual(obj.identifier, 123)
self.assertEqual('1.0', obj.VERSION)
# Test object that is no longer registered
self.assertRaises(
exception.UnsupportedObjectError,
FakeResource.obj_from_primitive,
self.primitive)