Merge "Add Instance and InstanceList v2.0 objects"
This commit is contained in:
@@ -1043,8 +1043,29 @@ class InstanceV1(_BaseInstance):
|
||||
getattr(self, attrname), ftype)
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceV2(_BaseInstance):
|
||||
# Version 2.0: Initial version
|
||||
VERSION = '2.0'
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
if target_version.startswith('1.'):
|
||||
# NOTE(danms): Special case to backport to 1.x. Serialize
|
||||
# ourselves, change the version, deserialize that, and get
|
||||
# that to continue the backport of this primitive to
|
||||
# whatever 1.x version was actually requested. We can get
|
||||
# away with this because InstanceV2 is structurally a
|
||||
# subset of V1.
|
||||
# FIXME(danms): Remove this when we drop v1.x compatibility
|
||||
my_prim = self.obj_to_primitive()
|
||||
my_prim['nova_object.version'] = InstanceV1.VERSION
|
||||
instv1 = InstanceV1.obj_from_primitive(my_prim)
|
||||
return instv1.obj_make_compatible(primitive, target_version)
|
||||
super(InstanceV2, self).obj_make_compatible(primitive, target_version)
|
||||
|
||||
|
||||
# NOTE(danms): For the unit tests...
|
||||
Instance = InstanceV1
|
||||
Instance = InstanceV2
|
||||
|
||||
|
||||
def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
|
||||
@@ -1270,5 +1291,21 @@ class InstanceListV1(_BaseInstanceList):
|
||||
}
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceListV2(_BaseInstanceList):
|
||||
# Version 2.0: Initial version
|
||||
VERSION = '2.0'
|
||||
|
||||
NOVA_OBJ_INSTANCE_CLS = InstanceV2
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
if target_version.startswith('1.'):
|
||||
my_prim = self.obj_to_primitive()
|
||||
my_prim['nova_object.version'] = InstanceListV1.VERSION
|
||||
instv1 = InstanceListV1.obj_from_primitive(my_prim)
|
||||
return instv1.obj_make_compatible(primitive, target_version)
|
||||
super(InstanceListV2, self).obj_make_compatible(primitive,
|
||||
target_version)
|
||||
|
||||
# NOTE(danms): For the unit tests...
|
||||
InstanceList = InstanceListV1
|
||||
InstanceList = InstanceListV2
|
||||
|
||||
@@ -99,7 +99,9 @@ def fake_db_instance(**updates):
|
||||
return db_instance
|
||||
|
||||
|
||||
def fake_instance_obj(context, **updates):
|
||||
def fake_instance_obj(context, obj_instance_class=None, **updates):
|
||||
if obj_instance_class is None:
|
||||
obj_instance_class = objects.Instance
|
||||
expected_attrs = updates.pop('expected_attrs', None)
|
||||
flavor = updates.pop('flavor', None)
|
||||
if not flavor:
|
||||
@@ -114,8 +116,8 @@ def fake_instance_obj(context, **updates):
|
||||
extra_specs={},
|
||||
projects=[])
|
||||
flavor.obj_reset_changes()
|
||||
inst = objects.Instance._from_db_object(context,
|
||||
objects.Instance(), fake_db_instance(**updates),
|
||||
inst = obj_instance_class._from_db_object(context,
|
||||
obj_instance_class(), fake_db_instance(**updates),
|
||||
expected_attrs=expected_attrs)
|
||||
if flavor:
|
||||
inst.flavor = flavor
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import datetime
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
from mox3 import mox
|
||||
import netaddr
|
||||
@@ -426,17 +427,6 @@ class _TestInstanceObject(object):
|
||||
inst.save()
|
||||
self.assertTrue(save_mock.called)
|
||||
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
def test_save_skip_scheduled_at(self, mock_fdo, mock_update):
|
||||
mock_update.return_value = None, None
|
||||
inst = objects.Instance(context=self.context, id=123)
|
||||
inst.uuid = 'foo'
|
||||
inst.scheduled_at = None
|
||||
inst.save()
|
||||
self.assertNotIn('scheduled_at',
|
||||
mock_update.call_args_list[0][0][2])
|
||||
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
def test_save_does_not_refresh_pci_devices(self, mock_fdo, mock_update):
|
||||
@@ -1049,40 +1039,6 @@ class _TestInstanceObject(object):
|
||||
expected_attrs=['info_cache'])
|
||||
self.assertIs(info_cache, inst.info_cache)
|
||||
|
||||
def test_compat_strings(self):
|
||||
unicode_attributes = ['user_id', 'project_id', 'image_ref',
|
||||
'kernel_id', 'ramdisk_id', 'hostname',
|
||||
'key_name', 'key_data', 'host', 'node',
|
||||
'user_data', 'availability_zone',
|
||||
'display_name', 'display_description',
|
||||
'launched_on', 'locked_by', 'os_type',
|
||||
'architecture', 'vm_mode', 'root_device_name',
|
||||
'default_ephemeral_device',
|
||||
'default_swap_device', 'config_drive',
|
||||
'cell_name']
|
||||
inst = objects.Instance()
|
||||
expected = {}
|
||||
for key in unicode_attributes:
|
||||
inst[key] = u'\u2603'
|
||||
expected[key] = b'?'
|
||||
primitive = inst.obj_to_primitive(target_version='1.6')
|
||||
self.assertJsonEqual(expected, primitive['nova_object.data'])
|
||||
self.assertEqual('1.6', primitive['nova_object.version'])
|
||||
|
||||
def test_compat_pci_devices(self):
|
||||
inst = objects.Instance()
|
||||
inst.pci_devices = pci_device.PciDeviceList()
|
||||
primitive = inst.obj_to_primitive(target_version='1.5')
|
||||
self.assertNotIn('pci_devices', primitive)
|
||||
|
||||
def test_compat_info_cache(self):
|
||||
inst = objects.Instance()
|
||||
inst.info_cache = instance_info_cache.InstanceInfoCache()
|
||||
primitive = inst.obj_to_primitive(target_version='1.9')
|
||||
self.assertEqual(
|
||||
'1.4',
|
||||
primitive['nova_object.data']['info_cache']['nova_object.version'])
|
||||
|
||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance_uuid')
|
||||
def test_get_with_pci_requests(self, mock_get):
|
||||
mock_get.return_value = objects.InstancePCIRequests()
|
||||
@@ -1286,16 +1242,6 @@ class _TestInstanceObject(object):
|
||||
self.context, uuid, expected_attrs=['pci_requests'])
|
||||
self.assertTrue(inst.obj_attr_is_set('pci_requests'))
|
||||
|
||||
def test_backport_flavor(self):
|
||||
flavor = flavors.get_default_flavor()
|
||||
inst = objects.Instance(context=self.context, flavor=flavor,
|
||||
system_metadata={'foo': 'bar'},
|
||||
new_flavor=None,
|
||||
old_flavor=None)
|
||||
primitive = inst.obj_to_primitive(target_version='1.17')
|
||||
self.assertIn('instance_type_id',
|
||||
primitive['nova_object.data']['system_metadata'])
|
||||
|
||||
|
||||
class TestInstanceObject(test_objects._LocalTest,
|
||||
_TestInstanceObject):
|
||||
@@ -1325,7 +1271,95 @@ class TestInstanceObject(test_objects._LocalTest,
|
||||
|
||||
class TestRemoteInstanceObject(test_objects._RemoteTest,
|
||||
_TestInstanceObject):
|
||||
pass
|
||||
def setUp(self):
|
||||
super(TestRemoteInstanceObject, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch('nova.objects.Instance',
|
||||
instance.InstanceV2))
|
||||
|
||||
|
||||
class TestInstanceV1RemoteObject(test_objects._RemoteTest,
|
||||
_TestInstanceObject):
|
||||
def setUp(self):
|
||||
super(TestInstanceV1RemoteObject, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch('nova.objects.Instance',
|
||||
instance.InstanceV1))
|
||||
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
def test_save_skip_scheduled_at(self, mock_fdo, mock_update):
|
||||
mock_update.return_value = None, None
|
||||
inst = objects.Instance(context=self.context, id=123)
|
||||
inst.uuid = 'foo'
|
||||
inst.scheduled_at = None
|
||||
inst.save()
|
||||
self.assertNotIn('scheduled_at',
|
||||
mock_update.call_args_list[0][0][2])
|
||||
|
||||
def test_backport_flavor(self):
|
||||
flavor = flavors.get_default_flavor()
|
||||
inst = objects.Instance(context=self.context, flavor=flavor,
|
||||
system_metadata={'foo': 'bar'},
|
||||
new_flavor=None,
|
||||
old_flavor=None)
|
||||
primitive = inst.obj_to_primitive(target_version='1.17')
|
||||
self.assertIn('instance_type_id',
|
||||
primitive['nova_object.data']['system_metadata'])
|
||||
|
||||
def test_compat_strings(self):
|
||||
unicode_attributes = ['user_id', 'project_id', 'image_ref',
|
||||
'kernel_id', 'ramdisk_id', 'hostname',
|
||||
'key_name', 'key_data', 'host', 'node',
|
||||
'user_data', 'availability_zone',
|
||||
'display_name', 'display_description',
|
||||
'launched_on', 'locked_by', 'os_type',
|
||||
'architecture', 'vm_mode', 'root_device_name',
|
||||
'default_ephemeral_device',
|
||||
'default_swap_device', 'config_drive',
|
||||
'cell_name']
|
||||
inst = objects.Instance()
|
||||
expected = {}
|
||||
for key in unicode_attributes:
|
||||
inst[key] = u'\u2603'
|
||||
expected[key] = b'?'
|
||||
primitive = inst.obj_to_primitive(target_version='1.6')
|
||||
self.assertJsonEqual(expected, primitive['nova_object.data'])
|
||||
self.assertEqual('1.6', primitive['nova_object.version'])
|
||||
|
||||
def test_compat_pci_devices(self):
|
||||
inst = objects.Instance()
|
||||
inst.pci_devices = pci_device.PciDeviceList()
|
||||
primitive = inst.obj_to_primitive(target_version='1.5')
|
||||
self.assertNotIn('pci_devices', primitive)
|
||||
|
||||
def test_compat_info_cache(self):
|
||||
inst = objects.Instance()
|
||||
inst.info_cache = instance_info_cache.InstanceInfoCache()
|
||||
primitive = inst.obj_to_primitive(target_version='1.9')
|
||||
self.assertEqual(
|
||||
'1.4',
|
||||
primitive['nova_object.data']['info_cache']['nova_object.version'])
|
||||
|
||||
def test_backport_v2_to_v1(self):
|
||||
inst2 = fake_instance.fake_instance_obj(
|
||||
self.context, obj_instance_class=instance.InstanceV2)
|
||||
inst1 = instance.InstanceV1.obj_from_primitive(
|
||||
inst2.obj_to_primitive(target_version=instance.InstanceV1.VERSION))
|
||||
self.assertEqual(instance.InstanceV1.VERSION, inst1.VERSION)
|
||||
self.assertIsInstance(inst1, instance.InstanceV1)
|
||||
self.assertEqual(inst2.uuid, inst1.uuid)
|
||||
|
||||
def test_backport_list_v2_to_v1(self):
|
||||
inst2 = fake_instance.fake_instance_obj(
|
||||
self.context, obj_instance_class=instance.InstanceV2)
|
||||
list2 = instance.InstanceListV2(objects=[inst2])
|
||||
list1 = instance.InstanceListV1.obj_from_primitive(
|
||||
list2.obj_to_primitive(
|
||||
target_version=instance.InstanceListV1.VERSION))
|
||||
self.assertEqual(instance.InstanceListV1.VERSION, list1.VERSION)
|
||||
self.assertEqual(instance.InstanceV1.VERSION, list1[0].VERSION)
|
||||
self.assertIsInstance(list1, instance.InstanceListV1)
|
||||
self.assertIsInstance(list1[0], instance.InstanceV1)
|
||||
self.assertEqual(list2[0].uuid, list1[0].uuid)
|
||||
|
||||
|
||||
class _TestInstanceListObject(object):
|
||||
|
||||
@@ -1186,7 +1186,8 @@ object_data = {
|
||||
'HVSpec': '1.1-6b4f7c0f688cbd03e24142a44eb9010d',
|
||||
'ImageMeta': '1.6-642d1b2eb3e880a367f37d72dd76162d',
|
||||
'ImageMetaProps': '1.6-07a6d9f3576c4927220331584661ce45',
|
||||
'Instance': '1.23-4e68422207667f4abff5fa730a5edc98',
|
||||
'Instance': '2.0-ff56804dce87d81d9a04834d4bd1e3d2',
|
||||
'Instance1': '1.23-4e68422207667f4abff5fa730a5edc98',
|
||||
'InstanceAction': '1.1-f9f293e526b66fca0d05c3b3a2d13914',
|
||||
'InstanceActionEvent': '1.1-e56a64fa4710e43ef7af2ad9d6028b33',
|
||||
'InstanceActionEventList': '1.1-13d92fb953030cdbfee56481756e02be',
|
||||
@@ -1197,7 +1198,8 @@ object_data = {
|
||||
'InstanceGroup': '1.10-1a0c8c7447dc7ecb9da53849430c4a5f',
|
||||
'InstanceGroupList': '1.7-be18078220513316abd0ae1b2d916873',
|
||||
'InstanceInfoCache': '1.5-cd8b96fefe0fc8d4d337243ba0bf0e1e',
|
||||
'InstanceList': '1.22-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceList': '2.0-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceList1': '1.22-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceMapping': '1.0-47ef26034dfcbea78427565d9177fe50',
|
||||
'InstanceMappingList': '1.0-9e982e3de1613b9ada85e35f69b23d47',
|
||||
'InstanceNUMACell': '1.2-535ef30e0de2d6a0d26a71bd58ecafc4',
|
||||
@@ -1380,7 +1382,7 @@ class TestObjectVersions(test.NoDBTestCase):
|
||||
# a 2.0 version while calculating the old-style relationship
|
||||
# mapping. Once we drop all the 1.x versions, we can drop this
|
||||
# relationship test altogether.
|
||||
new_objects = []
|
||||
new_objects = ['Instance', 'InstanceList']
|
||||
|
||||
versions = base.NovaObjectRegistry.obj_classes()[name]
|
||||
if len(versions) > 1 and name in new_objects:
|
||||
|
||||
Reference in New Issue
Block a user