diff --git a/oslo_versionedobjects/__init__.py b/oslo_versionedobjects/__init__.py index 6ab4ee0..aebaf75 100644 --- a/oslo_versionedobjects/__init__.py +++ b/oslo_versionedobjects/__init__.py @@ -24,36 +24,4 @@ def register_all(): # NOTE(danms): You must make sure your object gets imported in this # function in order for it to be registered by services that may # need to receive it via RPC. - __import__('nova.objects.agent') - __import__('nova.objects.aggregate') - __import__('nova.objects.bandwidth_usage') - __import__('nova.objects.block_device') - __import__('nova.objects.compute_node') - __import__('nova.objects.dns_domain') - __import__('nova.objects.ec2') - __import__('nova.objects.external_event') - __import__('nova.objects.fixed_ip') - __import__('nova.objects.flavor') - __import__('nova.objects.floating_ip') - __import__('nova.objects.hv_spec') - __import__('nova.objects.instance') - __import__('nova.objects.instance_action') - __import__('nova.objects.instance_fault') - __import__('nova.objects.instance_group') - __import__('nova.objects.instance_info_cache') - __import__('nova.objects.instance_numa_topology') - __import__('nova.objects.instance_pci_requests') - __import__('nova.objects.keypair') - __import__('nova.objects.migration') - __import__('nova.objects.network') - __import__('nova.objects.network_request') - __import__('nova.objects.numa') - __import__('nova.objects.pci_device') - __import__('nova.objects.pci_device_pool') - __import__('nova.objects.tag') - __import__('nova.objects.quotas') - __import__('nova.objects.security_group') - __import__('nova.objects.security_group_rule') - __import__('nova.objects.service') - __import__('nova.objects.virt_cpu_topology') - __import__('nova.objects.virtual_interface') + pass diff --git a/oslo_versionedobjects/base.py b/oslo_versionedobjects/base.py index de25ec3..9d6e8bc 100644 --- a/oslo_versionedobjects/base.py +++ b/oslo_versionedobjects/base.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -"""Nova common internal object model""" +"""Common internal object model""" import collections import contextlib @@ -159,13 +159,13 @@ def remotable_classmethod(fn): """Decorator for remotable classmethods.""" @functools.wraps(fn) def wrapper(cls, context, *args, **kwargs): - if NovaObject.indirection_api: - result = NovaObject.indirection_api.object_class_action( + if VersionedObject.indirection_api: + result = VersionedObject.indirection_api.object_class_action( context, cls.obj_name(), fn.__name__, cls.VERSION, args, kwargs) else: result = fn(cls, context, *args, **kwargs) - if isinstance(result, NovaObject): + if isinstance(result, VersionedObject): result._context = context return result @@ -188,16 +188,16 @@ def remotable(fn): if ctxt is None: raise exception.OrphanedObjectError(method=fn.__name__, objtype=self.obj_name()) - if NovaObject.indirection_api: - updates, result = NovaObject.indirection_api.object_action( + if VersionedObject.indirection_api: + updates, result = VersionedObject.indirection_api.object_action( ctxt, self, fn.__name__, args, kwargs) for key, value in updates.iteritems(): if key in self.fields: field = self.fields[key] - # NOTE(ndipanov): Since NovaObjectSerializer will have + # NOTE(ndipanov): Since VersionedObjectSerializer will have # deserialized any object fields into objects already, # we do not try to deserialize them again here. - if isinstance(value, NovaObject): + if isinstance(value, VersionedObject): self[key] = value else: self[key] = field.from_primitive(self, key, value) @@ -212,7 +212,7 @@ def remotable(fn): return wrapper -class NovaObject(object): +class VersionedObject(object): """Base class and object factory. This forms the base of all objects that can be remoted or instantiated @@ -327,8 +327,8 @@ class NovaObject(object): self = cls() self._context = context self.VERSION = objver - objdata = primitive['nova_object.data'] - changes = primitive.get('nova_object.changes', []) + objdata = primitive['versioned_object.data'] + changes = primitive.get('versioned_object.changes', []) for name, field in self.fields.items(): if name in objdata: setattr(self, name, field.from_primitive(self, name, @@ -339,14 +339,14 @@ class NovaObject(object): @classmethod def obj_from_primitive(cls, primitive, context=None): """Object field-by-field hydration.""" - if primitive['nova_object.namespace'] != 'nova': + if primitive['versioned_object.namespace'] != 'versionedobjects': # NOTE(danms): We don't do anything with this now, but it's # there for "the future" raise exception.UnsupportedObjectError( - objtype='%s.%s' % (primitive['nova_object.namespace'], - primitive['nova_object.name'])) - objname = primitive['nova_object.name'] - objver = primitive['nova_object.version'] + objtype='%s.%s' % (primitive['versioned_object.namespace'], + primitive['versioned_object.name'])) + objname = primitive['versioned_object.name'] + objver = primitive['versioned_object.version'] objclass = cls.obj_class_from_name(objname, objver) return objclass._obj_from_primitive(context, objver, primitive) @@ -391,17 +391,18 @@ class NovaObject(object): obj = getattr(self, field) if not obj: return - if isinstance(obj, NovaObject): + if isinstance(obj, VersionedObject): obj.obj_make_compatible( - primitive[field]['nova_object.data'], + primitive[field]['versioned_object.data'], to_version) - primitive[field]['nova_object.version'] = to_version + primitive[field]['versioned_object.version'] = to_version elif isinstance(obj, list): for i, element in enumerate(obj): element.obj_make_compatible( - primitive[field][i]['nova_object.data'], + primitive[field][i]['versioned_object.data'], to_version) - primitive[field][i]['nova_object.version'] = to_version + primitive[field][i][ + 'versioned_object.version'] = to_version target_version = utils.convert_version_to_tuple(target_version) for index, versions in enumerate(self.obj_relationships[field]): @@ -448,8 +449,8 @@ class NovaObject(object): :param:primitive: The result of self.obj_to_primitive() :param:target_version: The version string requested by the recipient of the object - :raises: nova.exception.UnsupportedObjectError if conversion - is not possible for some reason + :raises: oslo_versionedobjects.exception.UnsupportedObjectError + if conversion is not possible for some reason """ for key, field in self.fields.items(): if not isinstance(field, (fields.ObjectField, @@ -477,12 +478,12 @@ class NovaObject(object): getattr(self, name)) if target_version: self.obj_make_compatible(primitive, target_version) - obj = {'nova_object.name': self.obj_name(), - 'nova_object.namespace': 'nova', - 'nova_object.version': target_version or self.VERSION, - 'nova_object.data': primitive} + obj = {'versioned_object.name': self.obj_name(), + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': target_version or self.VERSION, + 'versioned_object.data': primitive} if self.obj_what_changed(): - obj['nova_object.changes'] = list(self.obj_what_changed()) + obj['versioned_object.changes'] = list(self.obj_what_changed()) return obj def obj_set_defaults(self, *attrs): @@ -520,7 +521,7 @@ class NovaObject(object): changes = set(self._changed_fields) for field in self.fields: if (self.obj_attr_is_set(field) and - isinstance(getattr(self, field), NovaObject) and + isinstance(getattr(self, field), VersionedObject) and getattr(self, field).obj_what_changed()): changes.add(field) return changes @@ -560,7 +561,7 @@ class NovaObject(object): return self.fields.keys() + self.obj_extra_fields -class NovaObjectDictCompat(object): +class VersionedObjectDictCompat(object): """Mix-in to provide dictionary key access compat If an object needs to support attribute access using @@ -631,7 +632,7 @@ class NovaObjectDictCompat(object): setattr(self, key, value) -class NovaPersistentObject(object): +class VersionedPersistentObject(object): """Mixin class for Persistent objects. This adds the fields that we use in common for all persistent objects. """ @@ -675,7 +676,7 @@ class ObjectListBase(object): serialization of the list of objects automatically. """ fields = { - 'objects': fields.ListOfObjectsField('NovaObject'), + 'objects': fields.ListOfObjectsField('VersionedObject'), } # This is a dictionary of my_version:child_version mappings so that @@ -702,7 +703,7 @@ class ObjectListBase(object): if isinstance(index, slice): new_obj = self.__class__() new_obj.objects = self.objects[index] - # NOTE(danms): We must be mixed in with a NovaObject! + # NOTE(danms): We must be mixed in with a VersionedObject! new_obj.obj_reset_changes() new_obj._context = self._context return new_obj @@ -728,9 +729,10 @@ class ObjectListBase(object): child_target_version = self.child_versions.get(target_version, '1.0') for index, item in enumerate(self.objects): self.objects[index].obj_make_compatible( - primitives[index]['nova_object.data'], + primitives[index]['versioned_object.data'], child_target_version) - primitives[index]['nova_object.version'] = child_target_version + primitives[index][ + 'versioned_object.version'] = child_target_version def obj_what_changed(self): changes = set(self._changed_fields) @@ -740,13 +742,13 @@ class ObjectListBase(object): return changes -class NovaObjectSerializer(messaging.NoOpSerializer): - """A NovaObject-aware Serializer. +class VersionedObjectSerializer(messaging.NoOpSerializer): + """A VersionedObject-aware Serializer. This implements the Oslo Serializer interface and provides the - ability to serialize and deserialize NovaObject entities. Any service - that needs to accept or return NovaObjects as arguments or result values - should pass this to its RPCClient and RPCServer objects. + ability to serialize and deserialize VersionedObject entities. Any service + that needs to accept or return VersionedObjects as arguments or result + values should pass this to its RPCClient and RPCServer objects. """ @property @@ -758,13 +760,14 @@ class NovaObjectSerializer(messaging.NoOpSerializer): def _process_object(self, context, objprim): try: - objinst = NovaObject.obj_from_primitive(objprim, context=context) + objinst = VersionedObject.obj_from_primitive( + objprim, context=context) except exception.IncompatibleObjectVersion as e: - objver = objprim['nova_object.version'] + objver = objprim['versioned_object.version'] if objver.count('.') == 2: # NOTE(danms): For our purposes, the .z part of the version # should be safe to accept without requiring a backport - objprim['nova_object.version'] = \ + objprim['versioned_object.version'] = \ '.'.join(objver.split('.')[:2]) return self._process_object(context, objprim) objinst = self.conductor.object_backport(context, objprim, @@ -803,7 +806,7 @@ class NovaObjectSerializer(messaging.NoOpSerializer): return entity def deserialize_entity(self, context, entity): - if isinstance(entity, dict) and 'nova_object.name' in entity: + if isinstance(entity, dict) and 'versioned_object.name' in entity: entity = self._process_object(context, entity) elif isinstance(entity, (tuple, list, set, dict)): entity = self._process_iterable(context, self.deserialize_entity, @@ -814,12 +817,12 @@ class NovaObjectSerializer(messaging.NoOpSerializer): def obj_to_primitive(obj): """Recursively turn an object into a python primitive. - A NovaObject becomes a dict, and anything that implements ObjectListBase - becomes a list. + A VersionedObject becomes a dict, and anything that implements + ObjectListBase becomes a list. """ if isinstance(obj, ObjectListBase): return [obj_to_primitive(x) for x in obj] - elif isinstance(obj, NovaObject): + elif isinstance(obj, VersionedObject): result = {} for key in obj.obj_fields: if obj.obj_attr_is_set(key) or key in obj.obj_extra_fields: @@ -841,7 +844,7 @@ def obj_make_list(context, list_obj, item_cls, db_list, **extra_args): :param:context: Request context :param:list_obj: An ObjectListBase object - :param:item_cls: The NovaObject class of the objects within the list + :param:item_cls: The VersionedObject class of the objects within the list :param:db_list: The list of primitives to convert to objects :param:extra_args: Extra arguments to pass to _from_db_object() :returns: list_obj diff --git a/oslo_versionedobjects/exception.py b/oslo_versionedobjects/exception.py index a34ca94..847f60c 100644 --- a/oslo_versionedobjects/exception.py +++ b/oslo_versionedobjects/exception.py @@ -14,9 +14,9 @@ # License for the specific language governing permissions and limitations # under the License. -"""Nova base exception handling. +"""VersionedObjects base exception handling. -Includes decorator for re-raising Nova-type exceptions. +Includes decorator for re-raising VersionedObjects-type exceptions. SHOULD include dedicated exception logging. @@ -91,8 +91,8 @@ def wrap_exception(notifier=None, get_notifier=None): return inner -class NovaException(Exception): - """Base Nova Exception +class VersionedObjectsException(Exception): + """Base VersionedObjects Exception To correctly use this class, inherit from it and define a 'msg_fmt' property. That msg_fmt will get printf'd @@ -131,33 +131,34 @@ class NovaException(Exception): # at least get the core message out if something happened message = self.msg_fmt - super(NovaException, self).__init__(message) + super(VersionedObjectsException, self).__init__(message) def format_message(self): # NOTE(mrodden): use the first argument to the python Exception object - # which should be our full NovaException message, (see __init__) + # which should be our full VersionedObjectsException message, + # (see __init__) return self.args[0] -class ObjectActionError(NovaException): +class ObjectActionError(VersionedObjectsException): msg_fmt = _('Object action %(action)s failed because: %(reason)s') -class ObjectFieldInvalid(NovaException): +class ObjectFieldInvalid(VersionedObjectsException): msg_fmt = _('Field %(field)s of %(objname)s is not an instance of Field') -class OrphanedObjectError(NovaException): +class OrphanedObjectError(VersionedObjectsException): msg_fmt = _('Cannot call %(method)s on orphaned %(objtype)s object') -class IncompatibleObjectVersion(NovaException): +class IncompatibleObjectVersion(VersionedObjectsException): msg_fmt = _('Version %(objver)s of %(objname)s is not supported') -class ReadOnlyFieldError(NovaException): +class ReadOnlyFieldError(VersionedObjectsException): msg_fmt = _('Cannot modify readonly field %(field)s') -class UnsupportedObjectError(NovaException): +class UnsupportedObjectError(VersionedObjectsException): msg_fmt = _('Unsupported object type %(objtype)s') diff --git a/oslo_versionedobjects/fields.py b/oslo_versionedobjects/fields.py old mode 100644 new mode 100755 index 9ca6822..e0b331c --- a/oslo_versionedobjects/fields.py +++ b/oslo_versionedobjects/fields.py @@ -16,7 +16,6 @@ import abc import datetime import iso8601 -import netaddr from oslo_utils import timeutils import six @@ -54,7 +53,7 @@ class AbstractFieldType(object): This method should convert the value given into the designated type, or throw an exception if this is not possible. - :param:obj: The NovaObject on which an attribute is being set + :param:obj: The VersionedObject on which an attribute is being set :param:attr: The name of the attribute being set :param:value: The value being set :returns: A properly-typed value @@ -68,7 +67,7 @@ class AbstractFieldType(object): This method should deserialize a value from the form given by to_primitive() to the designated type. - :param:obj: The NovaObject on which the value is to be set + :param:obj: The VersionedObject on which the value is to be set :param:attr: The name of the attribute which will hold the value :param:value: The serialized form of the value :returns: The natural form of the value @@ -82,7 +81,7 @@ class AbstractFieldType(object): This method should serialize a value to the form expected by from_primitive(). - :param:obj: The NovaObject on which the value is set + :param:obj: The VersionedObject on which the value is set :param:attr: The name of the attribute holding the value :param:value: The natural form of the value :returns: The serialized form of the value @@ -304,76 +303,6 @@ class DateTime(FieldType): return timeutils.isotime(value) -class IPAddress(FieldType): - @staticmethod - def coerce(obj, attr, value): - try: - return netaddr.IPAddress(value) - except netaddr.AddrFormatError as e: - raise ValueError(six.text_type(e)) - - def from_primitive(self, obj, attr, value): - return self.coerce(obj, attr, value) - - @staticmethod - def to_primitive(obj, attr, value): - return str(value) - - -class IPV4Address(IPAddress): - @staticmethod - def coerce(obj, attr, value): - result = IPAddress.coerce(obj, attr, value) - if result.version != 4: - raise ValueError(_('Network "%s" is not valid') % value) - return result - - -class IPV6Address(IPAddress): - @staticmethod - def coerce(obj, attr, value): - result = IPAddress.coerce(obj, attr, value) - if result.version != 6: - raise ValueError(_('Network "%s" is not valid') % value) - return result - - -class IPV4AndV6Address(IPAddress): - @staticmethod - def coerce(obj, attr, value): - result = IPAddress.coerce(obj, attr, value) - if result.version != 4 and result.version != 6: - raise ValueError(_('Network "%s" is not valid') % value) - return result - - -class IPNetwork(IPAddress): - @staticmethod - def coerce(obj, attr, value): - try: - return netaddr.IPNetwork(value) - except netaddr.AddrFormatError as e: - raise ValueError(six.text_type(e)) - - -class IPV4Network(IPNetwork): - @staticmethod - def coerce(obj, attr, value): - try: - return netaddr.IPNetwork(value, version=4) - except netaddr.AddrFormatError as e: - raise ValueError(six.text_type(e)) - - -class IPV6Network(IPNetwork): - @staticmethod - def coerce(obj, attr, value): - try: - return netaddr.IPNetwork(value, version=6) - except netaddr.AddrFormatError as e: - raise ValueError(six.text_type(e)) - - class CompoundFieldType(FieldType): def __init__(self, element_type, **field_args): self._element_type = Field(element_type, **field_args) @@ -517,9 +446,9 @@ class Object(FieldType): from oslo_versionedobjects import base as obj_base # NOTE (ndipanov): If they already got hydrated by the serializer, just # pass them back unchanged - if isinstance(value, obj_base.NovaObject): + if isinstance(value, obj_base.VersionedObject): return value - return obj_base.NovaObject.obj_from_primitive(value, obj._context) + return obj_base.VersionedObject.obj_from_primitive(value, obj._context) def describe(self): return "Object<%s>" % self._obj_name @@ -568,34 +497,6 @@ class DateTimeField(AutoTypedField): AUTO_TYPE = DateTime() -class IPAddressField(AutoTypedField): - AUTO_TYPE = IPAddress() - - -class IPV4AddressField(AutoTypedField): - AUTO_TYPE = IPV4Address() - - -class IPV6AddressField(AutoTypedField): - AUTO_TYPE = IPV6Address() - - -class IPV4AndV6AddressField(AutoTypedField): - AUTO_TYPE = IPV4AndV6Address() - - -class IPNetworkField(AutoTypedField): - AUTO_TYPE = IPNetwork() - - -class IPV4NetworkField(AutoTypedField): - AUTO_TYPE = IPV4Network() - - -class IPV6NetworkField(AutoTypedField): - AUTO_TYPE = IPV6Network() - - class DictOfStringsField(AutoTypedField): AUTO_TYPE = Dict(String()) diff --git a/oslo_versionedobjects/test.py b/oslo_versionedobjects/test.py index 90879ad..b03a3e1 100644 --- a/oslo_versionedobjects/test.py +++ b/oslo_versionedobjects/test.py @@ -51,7 +51,7 @@ CONF = cfg.CONF # CONF.set_override('use_stderr', False) logging.register_options(CONF) -logging.setup(CONF, 'nova') +logging.setup(CONF, 'versionedobjects') # 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 diff --git a/oslo_versionedobjects/tests/obj_fixtures.py b/oslo_versionedobjects/tests/obj_fixtures.py index e4baa42..22bae86 100644 --- a/oslo_versionedobjects/tests/obj_fixtures.py +++ b/oslo_versionedobjects/tests/obj_fixtures.py @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -"""Fixtures for Nova tests.""" +"""Fixtures for VersionedObject tests.""" from __future__ import absolute_import import gettext @@ -44,7 +44,7 @@ class ServiceFixture(fixtures.Fixture): name = name host = host or uuid.uuid4().hex kwargs.setdefault('host', host) - kwargs.setdefault('binary', 'nova-%s' % name) + kwargs.setdefault('binary', 'versionedobjects-%s' % name) self.kwargs = kwargs def setUp(self): diff --git a/oslo_versionedobjects/tests/test_fields.py b/oslo_versionedobjects/tests/test_fields.py old mode 100644 new mode 100755 index ca80b27..c208f9d --- a/oslo_versionedobjects/tests/test_fields.py +++ b/oslo_versionedobjects/tests/test_fields.py @@ -15,7 +15,6 @@ import datetime import iso8601 -import netaddr from oslo_utils import timeutils from oslo_versionedobjects import base as obj_base @@ -133,49 +132,6 @@ class TestDateTime(TestField): tzinfo=iso8601.iso8601.Utc()))) -class TestIPAddress(TestField): - def setUp(self): - super(TestIPAddress, self).setUp() - self.field = fields.IPAddressField() - self.coerce_good_values = [('1.2.3.4', netaddr.IPAddress('1.2.3.4')), - ('::1', netaddr.IPAddress('::1')), - (netaddr.IPAddress('::1'), - netaddr.IPAddress('::1'))] - self.coerce_bad_values = ['1-2', 'foo'] - self.to_primitive_values = [(netaddr.IPAddress('1.2.3.4'), '1.2.3.4'), - (netaddr.IPAddress('::1'), '::1')] - self.from_primitive_values = [('1.2.3.4', - netaddr.IPAddress('1.2.3.4')), - ('::1', - netaddr.IPAddress('::1'))] - - -class TestIPAddressV4(TestField): - def setUp(self): - super(TestIPAddressV4, self).setUp() - self.field = fields.IPV4AddressField() - self.coerce_good_values = [('1.2.3.4', netaddr.IPAddress('1.2.3.4')), - (netaddr.IPAddress('1.2.3.4'), - netaddr.IPAddress('1.2.3.4'))] - self.coerce_bad_values = ['1-2', 'foo', '::1'] - self.to_primitive_values = [(netaddr.IPAddress('1.2.3.4'), '1.2.3.4')] - self.from_primitive_values = [('1.2.3.4', - netaddr.IPAddress('1.2.3.4'))] - - -class TestIPAddressV6(TestField): - def setUp(self): - super(TestIPAddressV6, self).setUp() - self.field = fields.IPV6AddressField() - self.coerce_good_values = [('::1', netaddr.IPAddress('::1')), - (netaddr.IPAddress('::1'), - netaddr.IPAddress('::1'))] - self.coerce_bad_values = ['1.2', 'foo', '1.2.3.4'] - self.to_primitive_values = [(netaddr.IPAddress('::1'), '::1')] - self.from_primitive_values = [('::1', - netaddr.IPAddress('::1'))] - - class TestDict(TestField): def setUp(self): super(TestDict, self).setUp() @@ -332,7 +288,7 @@ class TestObject(TestField): super(TestObject, self).setUp() @obj_base.VersionedObjectRegistry.register - class TestableObject(obj_base.NovaObject): + class TestableObject(obj_base.VersionedObject): fields = { 'uuid': fields.StringField(), } @@ -343,7 +299,7 @@ class TestObject(TestField): # just want to make sure the right type of object is re-created return value.__class__.__name__ == TestableObject.__name__ - class OtherTestableObject(obj_base.NovaObject): + class OtherTestableObject(obj_base.VersionedObject): pass test_inst = TestableObject() @@ -360,45 +316,3 @@ class TestObject(TestField): obj = self._test_cls(uuid='fake-uuid') self.assertEqual('TestableObject(fake-uuid)', self.field.stringify(obj)) - - -class TestIPNetwork(TestField): - def setUp(self): - super(TestIPNetwork, self).setUp() - self.field = fields.Field(fields.IPNetwork()) - good = ['192.168.1.0/24', '0.0.0.0/0', '::1/128', '::1/64', '::1/0'] - self.coerce_good_values = [(x, netaddr.IPNetwork(x)) for x in good] - self.coerce_bad_values = ['192.168.0.0/f', '192.168.0.0/foo', - '::1/129', '192.168.0.0/-1'] - self.to_primitive_values = [(netaddr.IPNetwork(x), x) - for x in good] - self.from_primitive_values = [(x, netaddr.IPNetwork(x)) - for x in good] - - -class TestIPV4Network(TestField): - def setUp(self): - super(TestIPV4Network, self).setUp() - self.field = fields.Field(fields.IPV4Network()) - good = ['192.168.1.0/24', '0.0.0.0/0'] - self.coerce_good_values = [(x, netaddr.IPNetwork(x)) for x in good] - self.coerce_bad_values = ['192.168.0.0/f', '192.168.0.0/foo', - '::1/129', '192.168.0.0/-1'] - self.to_primitive_values = [(netaddr.IPNetwork(x), x) - for x in good] - self.from_primitive_values = [(x, netaddr.IPNetwork(x)) - for x in good] - - -class TestIPV6Network(TestField): - def setUp(self): - super(TestIPV6Network, self).setUp() - self.field = fields.Field(fields.IPV6Network()) - good = ['::1/128', '::1/64', '::1/0'] - self.coerce_good_values = [(x, netaddr.IPNetwork(x)) for x in good] - self.coerce_bad_values = ['192.168.0.0/f', '192.168.0.0/foo', - '::1/129', '192.168.0.0/-1'] - self.to_primitive_values = [(netaddr.IPNetwork(x), x) - for x in good] - self.from_primitive_values = [(x, netaddr.IPNetwork(x)) - for x in good] diff --git a/oslo_versionedobjects/tests/test_objects.py b/oslo_versionedobjects/tests/test_objects.py old mode 100644 new mode 100755 index ea4eb0c..b71b28f --- a/oslo_versionedobjects/tests/test_objects.py +++ b/oslo_versionedobjects/tests/test_objects.py @@ -27,13 +27,10 @@ from oslo_serialization import jsonutils from oslo_utils import timeutils from testtools import matchers -# from nova.conductor import rpcapi as conductor_rpcapi from oslo_versionedobjects import base from oslo_versionedobjects import exception from oslo_versionedobjects import fields -# from nova import rpc from oslo_versionedobjects import test -# from nova.tests.unit import fake_notifier from oslo_versionedobjects import utils @@ -49,14 +46,14 @@ def is_test_object(cls): @base.VersionedObjectRegistry.register -class MyOwnedObject(base.NovaPersistentObject, base.NovaObject): +class MyOwnedObject(base.VersionedPersistentObject, base.VersionedObject): VERSION = '1.0' fields = {'baz': fields.Field(fields.Integer())} @base.VersionedObjectRegistry.register -class MyObj(base.NovaPersistentObject, base.NovaObject, - base.NovaObjectDictCompat): +class MyObj(base.VersionedPersistentObject, base.VersionedObject, + base.VersionedObjectDictCompat): VERSION = '1.6' fields = {'foo': fields.Field(fields.Integer(), default=1), 'bar': fields.Field(fields.String()), @@ -134,7 +131,7 @@ class MyObjDiffVers(MyObj): @base.VersionedObjectRegistry.register -class MyObj2(base.NovaObject): +class MyObj2(base.VersionedObject): @classmethod def obj_name(cls): return 'MyObj' @@ -210,14 +207,14 @@ class TestRegistry(test.TestCase): def test_field_checking(self): def create_class(field): @base.VersionedObjectRegistry.register - class TestField(base.NovaObject): + class TestField(base.VersionedObject): VERSION = '1.5' fields = {'foo': field()} return TestField - create_class(fields.IPV4AndV6AddressField) + create_class(fields.DateTimeField) self.assertRaises(exception.ObjectFieldInvalid, - create_class, fields.IPV4AndV6Address) + create_class, fields.DateTime) self.assertRaises(exception.ObjectFieldInvalid, create_class, int) @@ -226,7 +223,7 @@ class TestObjToPrimitive(test.TestCase): def test_obj_to_primitive_list(self): @base.VersionedObjectRegistry.register - class MyObjElement(base.NovaObject): + class MyObjElement(base.VersionedObject): fields = {'foo': fields.IntegerField()} def __init__(self, foo): @@ -234,7 +231,7 @@ class TestObjToPrimitive(test.TestCase): self.foo = foo @base.VersionedObjectRegistry.register - class MyList(base.ObjectListBase, base.NovaObject): + class MyList(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('MyObjElement')} mylist = MyList() @@ -249,7 +246,7 @@ class TestObjToPrimitive(test.TestCase): def test_obj_to_primitive_recursive(self): @base.VersionedObjectRegistry.register - class MyList(base.ObjectListBase, base.NovaObject): + class MyList(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('MyObj')} mylist = MyList(objects=[MyObj(), MyObj()]) @@ -258,22 +255,12 @@ class TestObjToPrimitive(test.TestCase): self.assertEqual([{'foo': 0}, {'foo': 1}], base.obj_to_primitive(mylist)) - def test_obj_to_primitive_with_ip_addr(self): - @base.VersionedObjectRegistry.register - class TestObject(base.NovaObject): - fields = {'addr': fields.IPAddressField(), - 'cidr': fields.IPNetworkField()} - - obj = TestObject(addr='1.2.3.4', cidr='1.1.1.1/16') - self.assertEqual({'addr': '1.2.3.4', 'cidr': '1.1.1.1/16'}, - base.obj_to_primitive(obj)) - class TestObjMakeList(test.TestCase): def test_obj_make_list(self): @base.VersionedObjectRegistry.register - class MyList(base.ObjectListBase, base.NovaObject): + class MyList(base.ObjectListBase, base.VersionedObject): pass db_objs = [{'foo': 1, 'bar': 'baz', 'missing': 'banana'}, @@ -290,13 +277,13 @@ class TestObjMakeList(test.TestCase): def compare_obj(test, obj, db_obj, subs=None, allow_missing=None, comparators=None): - """Compare a NovaObject and a dict-like database object. + """Compare a VersionedObject and a dict-like database object. This automatically converts TZ-aware datetimes and iterates over the fields of the object. :param:test: The TestCase doing the comparison - :param:obj: The NovaObject to examine + :param:obj: The VersionedObject to examine :param:db_obj: The dict-like database object to use as reference :param:subs: A dict of objkey=dbkey field substitutions :param:allow_missing: A list of fields that may not be in db_obj @@ -370,7 +357,7 @@ class _LocalTest(_BaseTestCase): def setUp(self): super(_LocalTest, self).setUp() # Just in case - base.NovaObject.indirection_api = None + base.VersionedObject.indirection_api = None def assertRemotes(self): self.assertEqual(self.remote_object_calls, []) @@ -380,10 +367,10 @@ class _LocalTest(_BaseTestCase): def things_temporarily_local(): # Temporarily go non-remote so the conductor handles # this request directly - _api = base.NovaObject.indirection_api - base.NovaObject.indirection_api = None + _api = base.VersionedObject.indirection_api + base.VersionedObject.indirection_api = None yield - base.NovaObject.indirection_api = _api + base.VersionedObject.indirection_api = _api class _RemoteTest(_BaseTestCase): @@ -402,8 +389,9 @@ class _RemoteTest(_BaseTestCase): kwargs.get('objmethod'))) with things_temporarily_local(): result = orig_object_class_action(*args, **kwargs) - return (base.NovaObject.obj_from_primitive(result, context=args[0]) - if isinstance(result, base.NovaObject) else result) + return (base.VersionedObject.obj_from_primitive(result, + context=args[0]) + if isinstance(result, base.VersionedObject) else result) self.stubs.Set(self.conductor_service.manager, 'object_class_action', fake_object_class_action) @@ -418,7 +406,7 @@ class _RemoteTest(_BaseTestCase): # Things are remoted by default in this session # FIXME(dhellmann): See work items in adopt-oslo-versionedobjects. - # base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() + # base.VersionedObject.indirection_api =conductor_rpcapi.ConductorAPI() # To make sure local and remote contexts match # FIXME(dhellmann): See work items in adopt-oslo-versionedobjects. @@ -449,17 +437,17 @@ class _TestObject(object): # self.assertEqual('1.6', objects.MyObj.VERSION) def test_hydration_type_error(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.5', - 'nova_object.data': {'foo': 'a'}} + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.5', + 'versioned_object.data': {'foo': 'a'}} self.assertRaises(ValueError, MyObj.obj_from_primitive, primitive) def test_hydration(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.5', - 'nova_object.data': {'foo': 1}} + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.5', + 'versioned_object.data': {'foo': 1}} real_method = MyObj._obj_from_primitive def _obj_from_primitive(*args): @@ -472,27 +460,27 @@ class _TestObject(object): self.assertEqual(obj.foo, 1) def test_hydration_version_different(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.2', - 'nova_object.data': {'foo': 1}} + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.2', + 'versioned_object.data': {'foo': 1}} obj = MyObj.obj_from_primitive(primitive) self.assertEqual(obj.foo, 1) self.assertEqual('1.2', obj.VERSION) def test_hydration_bad_ns(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'foo', - 'nova_object.version': '1.5', - 'nova_object.data': {'foo': 1}} + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'foo', + 'versioned_object.version': '1.5', + 'versioned_object.data': {'foo': 1}} self.assertRaises(exception.UnsupportedObjectError, MyObj.obj_from_primitive, primitive) def test_hydration_additional_unexpected_stuff(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.5.1', - 'nova_object.data': { + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.5.1', + 'versioned_object.data': { 'foo': 1, 'unexpected_thing': 'foobar'}} obj = MyObj.obj_from_primitive(primitive) @@ -506,10 +494,10 @@ class _TestObject(object): self.assertEqual('1.5.1', obj.VERSION) def test_dehydration(self): - expected = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.6', - 'nova_object.data': {'foo': 1}} + expected = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.6', + 'versioned_object.data': {'foo': 1}} obj = MyObj(foo=1) obj.obj_reset_changes() self.assertEqual(obj.obj_to_primitive(), expected) @@ -539,7 +527,7 @@ class _TestObject(object): def test_load_in_base(self): @base.VersionedObjectRegistry.register - class Foo(base.NovaObject): + class Foo(base.VersionedObject): fields = {'foobar': fields.Field(fields.Integer())} obj = Foo() with self.assertRaisesRegex(NotImplementedError, ".*foobar.*"): @@ -549,40 +537,41 @@ class _TestObject(object): obj = MyObj(foo=1) obj.obj_reset_changes() self.assertEqual(obj.bar, 'loaded!') - expected = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.6', - 'nova_object.changes': ['bar'], - 'nova_object.data': {'foo': 1, - 'bar': 'loaded!'}} + expected = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.6', + 'versioned_object.changes': ['bar'], + 'versioned_object.data': {'foo': 1, + 'bar': 'loaded!'}} self.assertEqual(obj.obj_to_primitive(), expected) def test_changes_in_primitive(self): obj = MyObj(foo=123) self.assertEqual(obj.obj_what_changed(), set(['foo'])) primitive = obj.obj_to_primitive() - self.assertIn('nova_object.changes', primitive) + self.assertIn('versioned_object.changes', primitive) obj2 = MyObj.obj_from_primitive(primitive) self.assertEqual(obj2.obj_what_changed(), set(['foo'])) obj2.obj_reset_changes() self.assertEqual(obj2.obj_what_changed(), set()) def test_obj_class_from_name(self): - obj = base.NovaObject.obj_class_from_name('MyObj', '1.5') + obj = base.VersionedObject.obj_class_from_name('MyObj', '1.5') self.assertEqual('1.5', obj.VERSION) def test_obj_class_from_name_latest_compatible(self): - obj = base.NovaObject.obj_class_from_name('MyObj', '1.1') + obj = base.VersionedObject.obj_class_from_name('MyObj', '1.1') self.assertEqual('1.6', obj.VERSION) def test_unknown_objtype(self): self.assertRaises(exception.UnsupportedObjectError, - base.NovaObject.obj_class_from_name, 'foo', '1.0') + base.VersionedObject.obj_class_from_name, + 'foo', '1.0') def test_obj_class_from_name_supported_version(self): error = None try: - base.NovaObject.obj_class_from_name('MyObj', '1.25') + base.VersionedObject.obj_class_from_name('MyObj', '1.25') except exception.IncompatibleObjectVersion as error: pass @@ -637,7 +626,7 @@ class _TestObject(object): def test_changed_with_sub_object(self): @base.VersionedObjectRegistry.register - class ParentObject(base.NovaObject): + class ParentObject(base.VersionedObject): fields = {'foo': fields.IntegerField(), 'bar': fields.ObjectField('MyObj'), } @@ -672,13 +661,13 @@ class _TestObject(object): obj = MyObj(created_at=dt, updated_at=dt, deleted_at=None, deleted=False) expected = { - 'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.6', - 'nova_object.changes': [ + 'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.6', + 'versioned_object.changes': [ 'deleted', 'created_at', 'deleted_at', 'updated_at', ], - 'nova_object.data': { + 'versioned_object.data': { 'created_at': timeutils.isotime(dt), 'updated_at': timeutils.isotime(dt), 'deleted_at': None, @@ -718,7 +707,7 @@ class _TestObject(object): self.assertRaises(AttributeError, obj.get, 'nothing', 3) def test_object_inheritance(self): - base_fields = base.NovaPersistentObject.fields.keys() + base_fields = base.VersionedPersistentObject.fields.keys() myobj_fields = (['foo', 'bar', 'missing', 'readonly', 'rel_object', 'rel_objects'] + base_fields) @@ -764,7 +753,7 @@ class _TestObject(object): self.assertEqual({}, obj.obj_get_changes()) def test_obj_fields(self): - class TestObj(base.NovaObject): + class TestObj(base.VersionedObject): fields = {'foo': fields.Field(fields.Integer())} obj_extra_fields = ['bar'] @@ -800,7 +789,7 @@ class _TestObject(object): obj.obj_relationships = { 'rel_object': [('1.5', '1.1'), ('1.7', '1.2')], } - primitive = obj.obj_to_primitive()['nova_object.data'] + primitive = obj.obj_to_primitive()['versioned_object.data'] with mock.patch.object(subobj, 'obj_make_compatible') as mock_compat: obj._obj_make_obj_compatible(copy.copy(primitive), '1.8', 'rel_object') @@ -810,25 +799,25 @@ class _TestObject(object): obj._obj_make_obj_compatible(copy.copy(primitive), '1.7', 'rel_object') mock_compat.assert_called_once_with( - primitive['rel_object']['nova_object.data'], '1.2') - self.assertEqual('1.2', - primitive['rel_object']['nova_object.version']) + primitive['rel_object']['versioned_object.data'], '1.2') + self.assertEqual( + '1.2', primitive['rel_object']['versioned_object.version']) with mock.patch.object(subobj, 'obj_make_compatible') as mock_compat: obj._obj_make_obj_compatible(copy.copy(primitive), '1.6', 'rel_object') mock_compat.assert_called_once_with( - primitive['rel_object']['nova_object.data'], '1.1') - self.assertEqual('1.1', - primitive['rel_object']['nova_object.version']) + primitive['rel_object']['versioned_object.data'], '1.1') + self.assertEqual( + '1.1', primitive['rel_object']['versioned_object.version']) with mock.patch.object(subobj, 'obj_make_compatible') as mock_compat: obj._obj_make_obj_compatible(copy.copy(primitive), '1.5', 'rel_object') mock_compat.assert_called_once_with( - primitive['rel_object']['nova_object.data'], '1.1') - self.assertEqual('1.1', - primitive['rel_object']['nova_object.version']) + primitive['rel_object']['versioned_object.data'], '1.1') + self.assertEqual( + '1.1', primitive['rel_object']['versioned_object.version']) with mock.patch.object(subobj, 'obj_make_compatible') as mock_compat: _prim = copy.copy(primitive) @@ -924,14 +913,14 @@ class TestRemoteObject(_RemoteTest, _TestObject): class TestObjectListBase(test.TestCase): def test_list_like_operations(self): @base.VersionedObjectRegistry.register - class MyElement(base.NovaObject): + class MyElement(base.VersionedObject): fields = {'foo': fields.IntegerField()} def __init__(self, foo): super(MyElement, self).__init__() self.foo = foo - class Foo(base.ObjectListBase, base.NovaObject): + class Foo(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('MyElement')} objlist = Foo(context='foo', @@ -950,11 +939,11 @@ class TestObjectListBase(test.TestCase): def test_serialization(self): @base.VersionedObjectRegistry.register - class Foo(base.ObjectListBase, base.NovaObject): + class Foo(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('Bar')} @base.VersionedObjectRegistry.register - class Bar(base.NovaObject): + class Bar(base.VersionedObject): fields = {'foo': fields.Field(fields.String())} obj = Foo(objects=[]) @@ -962,7 +951,7 @@ class TestObjectListBase(test.TestCase): bar = Bar(foo=i) obj.objects.append(bar) - obj2 = base.NovaObject.obj_from_primitive(obj.obj_to_primitive()) + obj2 = base.VersionedObject.obj_from_primitive(obj.obj_to_primitive()) self.assertFalse(obj is obj2) self.assertEqual([x.foo for x in obj], [y.foo for y in obj2]) @@ -995,11 +984,11 @@ class TestObjectListBase(test.TestCase): def test_list_changes(self): @base.VersionedObjectRegistry.register - class Foo(base.ObjectListBase, base.NovaObject): + class Foo(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('Bar')} @base.VersionedObjectRegistry.register - class Bar(base.NovaObject): + class Bar(base.VersionedObject): fields = {'foo': fields.StringField()} obj = Foo(objects=[]) @@ -1014,10 +1003,10 @@ class TestObjectListBase(test.TestCase): self.assertEqual(set(), obj.obj_what_changed()) def test_initialize_objects(self): - class Foo(base.ObjectListBase, base.NovaObject): + class Foo(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('Bar')} - class Bar(base.NovaObject): + class Bar(base.VersionedObject): fields = {'foo': fields.StringField()} obj = Foo() @@ -1026,11 +1015,11 @@ class TestObjectListBase(test.TestCase): def test_obj_repr(self): @base.VersionedObjectRegistry.register - class Foo(base.ObjectListBase, base.NovaObject): + class Foo(base.ObjectListBase, base.VersionedObject): fields = {'objects': fields.ListOfObjectsField('Bar')} @base.VersionedObjectRegistry.register - class Bar(base.NovaObject): + class Bar(base.VersionedObject): fields = {'uuid': fields.StringField()} obj = Foo(objects=[Bar(uuid='fake-uuid')]) @@ -1039,22 +1028,22 @@ class TestObjectListBase(test.TestCase): class TestObjectSerializer(_BaseTestCase): def test_serialize_entity_primitive(self): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() for thing in (1, 'foo', [1, 2], {'foo': 'bar'}): self.assertEqual(thing, ser.serialize_entity(None, thing)) def test_deserialize_entity_primitive(self): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() for thing in (1, 'foo', [1, 2], {'foo': 'bar'}): self.assertEqual(thing, ser.deserialize_entity(None, thing)) def test_serialize_set_to_list(self): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() self.assertEqual([1, 2], ser.serialize_entity(None, set([1, 2]))) def _test_deserialize_entity_newer(self, obj_version, backported_to, my_version='1.6'): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() ser._conductor = mock.Mock() ser._conductor.object_backport.return_value = 'backported' @@ -1087,13 +1076,13 @@ class TestObjectSerializer(_BaseTestCase): self._test_deserialize_entity_newer('1.7', '1.6.1', '1.6.1') def test_deserialize_dot_z_with_extra_stuff(self): - primitive = {'nova_object.name': 'MyObj', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.6.1', - 'nova_object.data': { + primitive = {'versioned_object.name': 'MyObj', + 'versioned_object.namespace': 'versionedobjects', + 'versioned_object.version': '1.6.1', + 'versioned_object.data': { 'foo': 1, 'unexpected_thing': 'foobar'}} - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() obj = ser.deserialize_entity(self.context, primitive) self.assertEqual(1, obj.foo) self.assertFalse(hasattr(obj, 'unexpected_thing')) @@ -1105,23 +1094,23 @@ class TestObjectSerializer(_BaseTestCase): self.assertEqual('1.6', obj.VERSION) def test_object_serialization(self): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() obj = MyObj() primitive = ser.serialize_entity(self.context, obj) - self.assertIn('nova_object.name', primitive) + self.assertIn('versioned_object.name', primitive) obj2 = ser.deserialize_entity(self.context, primitive) self.assertIsInstance(obj2, MyObj) self.assertEqual(self.context, obj2._context) def test_object_serialization_iterables(self): - ser = base.NovaObjectSerializer() + ser = base.VersionedObjectSerializer() obj = MyObj() for iterable in (list, tuple, set): thing = iterable([obj]) primitive = ser.serialize_entity(self.context, thing) self.assertEqual(1, len(primitive)) for item in primitive: - self.assertNotIsInstance(item, base.NovaObject) + self.assertNotIsInstance(item, base.VersionedObject) thing2 = ser.deserialize_entity(self.context, primitive) self.assertEqual(1, len(thing2)) for item in thing2: @@ -1131,7 +1120,7 @@ class TestObjectSerializer(_BaseTestCase): primitive = ser.serialize_entity(self.context, thing) self.assertEqual(1, len(primitive)) for item in primitive.itervalues(): - self.assertNotIsInstance(item, base.NovaObject) + self.assertNotIsInstance(item, base.VersionedObject) thing2 = ser.deserialize_entity(self.context, primitive) self.assertEqual(1, len(thing2)) for item in thing2.itervalues(): @@ -1142,7 +1131,7 @@ class TestObjectSerializer(_BaseTestCase): primitive = ser.serialize_entity(self.context, thing) self.assertEqual(thing, primitive) thing2 = ser.deserialize_entity(self.context, thing) - self.assertIsInstance(thing2['foo'], base.NovaObject) + self.assertIsInstance(thing2['foo'], base.VersionedObject) # NOTE(danms): The hashes in this list should only be changed if diff --git a/oslo_versionedobjects/tests/test_utils.py b/oslo_versionedobjects/tests/test_utils.py old mode 100644 new mode 100755 index 1d3cad6..b6abb53 --- a/oslo_versionedobjects/tests/test_utils.py +++ b/oslo_versionedobjects/tests/test_utils.py @@ -26,7 +26,7 @@ class VersionTestCase(test.NoDBTestCase): self.assertEqual(utils.convert_version_to_int('6.2.0'), 6002000) self.assertEqual(utils.convert_version_to_int((6, 4, 3)), 6004003) self.assertEqual(utils.convert_version_to_int((5, )), 5) - self.assertRaises(exception.NovaException, + self.assertRaises(exception.VersionedObjectsException, utils.convert_version_to_int, '5a.6b') def test_convert_version_to_string(self): diff --git a/oslo_versionedobjects/utils.py b/oslo_versionedobjects/utils.py index 43ad03a..601e24a 100644 --- a/oslo_versionedobjects/utils.py +++ b/oslo_versionedobjects/utils.py @@ -35,7 +35,7 @@ def convert_version_to_int(version): return reduce(lambda x, y: (x * 1000) + y, version) except Exception: msg = _("Hypervisor version %s is invalid.") % version - raise exception.NovaException(msg) + raise exception.VersionedObjectsException(msg) def convert_version_to_str(version_int):