summaryrefslogtreecommitdiff
path: root/nova/tests/unit/objects
diff options
context:
space:
mode:
authorBalazs Gibizer <balazs.gibizer@est.tech>2021-12-01 18:33:32 +0100
committerBalazs Gibizer <balazs.gibizer@est.tech>2021-12-03 09:08:15 +0000
commit05e8977cb2fd660dcf6af32c5804f7548bf722a7 (patch)
treed420e75227b6bcc41bdeeee1f16bc665e63faa9b /nova/tests/unit/objects
parent7670303aabe16d1d7c25e411d7bd413aee7fdcf3 (diff)
downloadnova-05e8977cb2fd660dcf6af32c5804f7548bf722a7.tar.gz
Reproduce bug 1952941
The added unit test proves that pre-Victoria RequestSpec objects describing a cpu pinned Instance are not migrated to a proper format in Victoria or newer. Related-Bug: #1952941 Change-Id: I672af45a1d1c7fb428b1c4983d4f856852829fb9
Diffstat (limited to 'nova/tests/unit/objects')
-rw-r--r--nova/tests/unit/objects/test_request_spec.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/nova/tests/unit/objects/test_request_spec.py b/nova/tests/unit/objects/test_request_spec.py
index fabadfe898..7d656c555e 100644
--- a/nova/tests/unit/objects/test_request_spec.py
+++ b/nova/tests/unit/objects/test_request_spec.py
@@ -615,6 +615,69 @@ class _TestRequestSpecObject(object):
self.assertIsInstance(req_obj.instance_group, objects.InstanceGroup)
self.assertEqual('fresh', req_obj.instance_group.name)
+ # FIXME(gibi): This is bug 1952941. When the cpuset -> pcpuset data
+ # migration was added to InstanceNUMATopology it was missed that such
+ # object is not only hydrated via
+ # InstanceNUMATopology.get_by_instance_uuid() but also hydrated by
+ # RequestSpec.get_by_instance_uuid() indirectly. However the
+ # latter code patch does not call InstanceNUMATopology.obj_from_db_obj()
+ # that triggers the data migration via
+ # InstanceNUMATopology._migrate_legacy_dedicated_instance_cpuset.
+ # This causes that when the new nova code loads an old RequestSpec object
+ # from the DB (e.g. during migration of an instance) the
+ # InstanceNUMATopology in the RequestSpec will not be migrated to the new
+ # object version and it will lead to errors when the pcpuset field is read
+ # during scheduling.
+ @mock.patch(
+ 'nova.objects.instance_numa.InstanceNUMATopology.'
+ '_migrate_legacy_dedicated_instance_cpuset',
+ new=mock.NonCallableMock()
+ )
+ @mock.patch.object(
+ request_spec.RequestSpec, '_get_by_instance_uuid_from_db')
+ @mock.patch('nova.objects.InstanceGroup.get_by_uuid')
+ def test_get_by_instance_uuid_numa_topology_migration(
+ self, mock_get_ig, get_by_uuid
+ ):
+ # Simulate a pre-Victoria RequestSpec where the pcpuset field is not
+ # defined for the embedded InstanceNUMACell objects but the cpu_policy
+ # is dedicated meaning that cores in cpuset defines pinned cpus. So
+ # in Victoria or later these InstanceNUMACell objects should be
+ # translated to hold the cores in the pcpuset field instead.
+ numa_topology = objects.InstanceNUMATopology(
+ instance_uuid=uuids.instance_uuid,
+ cells=[
+ objects.InstanceNUMACell(
+ id=0, cpuset={1, 2}, memory=512, cpu_policy="dedicated"),
+ objects.InstanceNUMACell(
+ id=1, cpuset={3, 4}, memory=512, cpu_policy="dedicated"),
+ ]
+ )
+ spec_obj = fake_request_spec.fake_spec_obj()
+ spec_obj.numa_topology = numa_topology
+ fake_spec = fake_request_spec.fake_db_spec(spec_obj)
+ fake_spec['instance_uuid'] = uuids.instance_uuid
+
+ get_by_uuid.return_value = fake_spec
+ mock_get_ig.return_value = objects.InstanceGroup(name='fresh')
+
+ req_obj = request_spec.RequestSpec.get_by_instance_uuid(
+ self.context, fake_spec['instance_uuid'])
+
+ self.assertEqual(2, len(req_obj.numa_topology.cells))
+
+ # This is bug 1952941 as the pcpuset is not defined in object as the
+ # object is not migrated
+ ex = self.assertRaises(
+ NotImplementedError,
+ lambda: req_obj.numa_topology.cells[0].pcpuset
+ )
+ self.assertIn("Cannot load 'pcpuset' in the base class", str(ex))
+
+ # This is the expected behavior
+ # self.assertEqual({1, 2}, req_obj.numa_topology.cells[0].pcpuset)
+ # self.assertEqual({3, 4}, req_obj.numa_topology.cells[1].pcpuset)
+
def _check_update_primitive(self, req_obj, changes):
self.assertEqual(req_obj.instance_uuid, changes['instance_uuid'])
serialized_obj = objects.RequestSpec.obj_from_primitive(