instance_topology_from_instance handles request_spec properly

We special-case how we handle the instance that we extract from the
request_spec data blob in virt.hardware.instance_topology_from_instance,
however, we were making wrong assumptions about the data we get from it
in the scheduler.

This patch fixes how it is handled and also updates the tests and
comments in the code to reflect it.

Change-Id: I38d7078d670bc37ddb40fba82fd0f9cb74045047
Closes-bug: #1369508
This commit is contained in:
Nikola Dipanov 2014-09-15 15:32:56 +02:00
parent b00da8421c
commit 12b8b56807
3 changed files with 31 additions and 16 deletions

View File

@ -2053,7 +2053,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
objects.InstanceNUMATopology.obj_from_topology(
instance_topology))
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1',
{'numa_topology': fakes.NUMA_TOPOLOGY})
filt_cls = self.class_map['NUMATopologyFilter']()
@ -2069,7 +2070,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
instance_topology))
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1', {})
filt_cls = self.class_map['NUMATopologyFilter']()
self.assertFalse(filt_cls.host_passes(host, filter_properties))
@ -2078,7 +2080,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
instance = fake_instance.fake_instance_obj(self.context)
instance.numa_topology = None
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1',
{'numa_topology': fakes.NUMA_TOPOLOGY})
filt_cls = self.class_map['NUMATopologyFilter']()
@ -2095,7 +2098,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
objects.InstanceNUMATopology.obj_from_topology(
instance_topology))
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1',
{'numa_topology': fakes.NUMA_TOPOLOGY})
filt_cls = self.class_map['NUMATopologyFilter']()
@ -2112,7 +2116,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
objects.InstanceNUMATopology.obj_from_topology(
instance_topology))
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1',
{'numa_topology': fakes.NUMA_TOPOLOGY})
filt_cls = self.class_map['NUMATopologyFilter']()
@ -2130,7 +2135,8 @@ class HostFiltersTestCase(test.NoDBTestCase):
objects.InstanceNUMATopology.obj_from_topology(
instance_topology))
filter_properties = {
'instance_properties': obj_base.obj_to_primitive(instance)}
'instance_properties': jsonutils.to_primitive(
obj_base.obj_to_primitive(instance))}
host = fakes.FakeHostState('host1', 'node1',
{'numa_topology': fakes.NUMA_TOPOLOGY})
filt_cls = self.class_map['NUMATopologyFilter']()

View File

@ -21,6 +21,7 @@ from nova import context
from nova import exception
from nova import objects
from nova.objects import base as base_obj
from nova.openstack.common import jsonutils
from nova import test
from nova.tests import matchers
from nova.virt import hardware as hw
@ -1301,13 +1302,16 @@ class HelperMethodsTestCase(test.NoDBTestCase):
self.assertIsInstance(res, six.string_types)
self.assertTrue(get_mock.called)
def test_instance_serialized_by_base_obj_to_primitive(self):
def test_instance_serialized_by_build_request_spec(self):
host = objects.ComputeNode(numa_topology=self.hosttopo.to_json())
fake_uuid = str(uuid.uuid4())
instance = objects.Instance(context=self.context, id=1, uuid=fake_uuid,
numa_topology=objects.InstanceNUMATopology.obj_from_topology(
self.instancetopo))
instance_raw = base_obj.obj_to_primitive(instance)
# NOTE (ndipanov): This emulates scheduler.utils.build_request_spec
# We can remove this test once we no longer use that method.
instance_raw = jsonutils.to_primitive(
base_obj.obj_to_primitive(instance))
res = hw.get_host_numa_usage_from_instance(host, instance_raw)
self.assertIsInstance(res, six.string_types)
self._check_usage(hw.VirtNUMAHostTopology.from_json(res))

View File

@ -911,8 +911,7 @@ def instance_topology_from_instance(instance):
Since we may get an Instance as either a dict, a db object, or an actual
Instance object, this makes sure we get beck either None, or an instance
of
of objects.InstanceNUMATopology class.
"""
if isinstance(instance, objects.Instance):
# NOTE (ndipanov): This may cause a lazy-load of the attribute
@ -939,14 +938,20 @@ def instance_topology_from_instance(instance):
# NOTE (ndipanov): A horrible hack so that we can use this in the
# scheduler, since the InstanceNUMATopology object is serialized
# raw using the obj_base.obj_to_primitive, (which is buggy and will
# give us a dict with a list of InstanceNUMACell objects) by
# scheduler_utils.build_request_spec in the conductor.
# give us a dict with a list of InstanceNUMACell objects), and then
# passed to jsonutils.to_primitive, which will make a dict out of
# those objects. All of this is done by
# scheduler.utils.build_request_spec called in the conductor.
#
# Remove when request_spec is a proper object itself!
cells = instance_numa_topology.get('cells')
if cells:
instance_numa_topology = objects.InstanceNUMATopology(
cells=cells)
dict_cells = instance_numa_topology.get('cells')
if dict_cells:
cells = [objects.InstanceNUMACell(id=cell['id'],
cpuset=set(cell['cpuset']),
memory=cell['memory'])
for cell in dict_cells]
instance_numa_topology = (
objects.InstanceNUMATopology(cells=cells))
return instance_numa_topology