Make usage_from_instances consider current usage

VirtNUMAHostTopology.usage_from_instances will now consider the current
usage of the passed host, and also accepts a 'free' keyword argument,
which if set to True, will cause the instance usage to be taken out of
the considered host. Also adds better handling of  None and emtpy
params.

Blueprint: virt-driver-numa-placement
Change-Id: I62c59b5e1dcbd4db247282f170c6f2f501bafd3d
This commit is contained in:
Nikola Dipanov 2014-07-30 14:48:20 +02:00
parent acbe3d58a6
commit 230471b645
2 changed files with 87 additions and 7 deletions

View File

@ -920,6 +920,76 @@ class NUMATopologyTest(test.NoDBTestCase):
self.assertEqual(hostusage.cells[2].cpu_usage, 1)
self.assertEqual(hostusage.cells[2].memory_usage, 256)
def test_host_usage_culmulative_with_free(self):
hosttopo = hw.VirtNUMAHostTopology([
hw.VirtNUMATopologyCellUsage(
0, set([0, 1, 2, 3]), 1024, cpu_usage=2, memory_usage=512),
hw.VirtNUMATopologyCellUsage(
1, set([4, 6]), 512, cpu_usage=1, memory_usage=512),
hw.VirtNUMATopologyCellUsage(2, set([5, 7]), 256),
])
instance1 = hw.VirtNUMAInstanceTopology([
hw.VirtNUMATopologyCell(0, set([0, 1, 2]), 512),
hw.VirtNUMATopologyCell(1, set([3]), 256),
hw.VirtNUMATopologyCell(2, set([4]), 256)])
hostusage = hw.VirtNUMAHostTopology.usage_from_instances(
hosttopo, [instance1])
self.assertIsInstance(hostusage.cells[0],
hw.VirtNUMATopologyCellUsage)
self.assertEqual(hostusage.cells[0].cpu_usage, 5)
self.assertEqual(hostusage.cells[0].memory_usage, 1024)
self.assertIsInstance(hostusage.cells[1],
hw.VirtNUMATopologyCellUsage)
self.assertEqual(hostusage.cells[1].cpu_usage, 2)
self.assertEqual(hostusage.cells[1].memory_usage, 768)
self.assertIsInstance(hostusage.cells[2],
hw.VirtNUMATopologyCellUsage)
self.assertEqual(hostusage.cells[2].cpu_usage, 1)
self.assertEqual(hostusage.cells[2].memory_usage, 256)
# Test freeing of resources
hostusage = hw.VirtNUMAHostTopology.usage_from_instances(
hostusage, [instance1], free=True)
self.assertEqual(hostusage.cells[0].cpu_usage, 2)
self.assertEqual(hostusage.cells[0].memory_usage, 512)
self.assertEqual(hostusage.cells[1].cpu_usage, 1)
self.assertEqual(hostusage.cells[1].memory_usage, 512)
self.assertEqual(hostusage.cells[2].cpu_usage, 0)
self.assertEqual(hostusage.cells[2].memory_usage, 0)
def test_topo_usage_none(self):
hosttopo = hw.VirtNUMAHostTopology([
hw.VirtNUMATopologyCellUsage(0, set([0, 1]), 512),
hw.VirtNUMATopologyCellUsage(1, set([2, 3]), 512),
])
instance1 = hw.VirtNUMAInstanceTopology([
hw.VirtNUMATopologyCell(0, set([0, 1]), 256),
hw.VirtNUMATopologyCell(2, set([2]), 256),
])
hostusage = hw.VirtNUMAHostTopology.usage_from_instances(
None, [instance1])
self.assertIsNone(hostusage)
hostusage = hw.VirtNUMAHostTopology.usage_from_instances(
hosttopo, [])
self.assertEqual(hostusage.cells[0].cpu_usage, 0)
self.assertEqual(hostusage.cells[0].memory_usage, 0)
self.assertEqual(hostusage.cells[1].cpu_usage, 0)
self.assertEqual(hostusage.cells[1].memory_usage, 0)
hostusage = hw.VirtNUMAHostTopology.usage_from_instances(
hosttopo, None)
self.assertEqual(hostusage.cells[0].cpu_usage, 0)
self.assertEqual(hostusage.cells[0].memory_usage, 0)
self.assertEqual(hostusage.cells[1].cpu_usage, 0)
self.assertEqual(hostusage.cells[1].memory_usage, 0)
def _test_to_dict(self, cell_or_topo, expected):
got = cell_or_topo._to_dict()
self.assertThat(expected, matchers.DictMatches(got))

View File

@ -596,6 +596,9 @@ class VirtNUMATopology(object):
"""Defined so that boolean testing works the same as for lists."""
return len(self.cells)
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, str(self._to_dict()))
def _to_dict(self):
return {'cells': [cell._to_dict() for cell in self.cells]}
@ -742,11 +745,12 @@ class VirtNUMAHostTopology(VirtNUMATopology):
cell_class = VirtNUMATopologyCellUsage
@classmethod
def usage_from_instances(cls, host, instances):
def usage_from_instances(cls, host, instances, free=False):
"""Get host topology usage
:param host: VirtNUMAHostTopology without usage information
:param host: VirtNUMAHostTopology with usage information
:param instances: list of VirtNUMAInstanceTopology
:param free: If True usage of the host will be decreased
Sum the usage from all @instances to report the overall
host topology usage
@ -754,19 +758,25 @@ class VirtNUMAHostTopology(VirtNUMATopology):
:returns: VirtNUMAHostTopology including usage information
"""
if host is None:
return
instances = instances or []
cells = []
sign = -1 if free else 1
for hostcell in host.cells:
memory_usage = 0
cpu_usage = 0
memory_usage = hostcell.memory_usage
cpu_usage = hostcell.cpu_usage
for instance in instances:
for instancecell in instance.cells:
if instancecell.id == hostcell.id:
memory_usage = memory_usage + instancecell.memory
cpu_usage = cpu_usage + len(instancecell.cpuset)
memory_usage = (
memory_usage + sign * instancecell.memory)
cpu_usage = cpu_usage + sign * len(instancecell.cpuset)
cell = cls.cell_class(
hostcell.id, hostcell.cpuset, hostcell.memory,
cpu_usage, memory_usage)
max(0, cpu_usage), max(0, memory_usage))
cells.append(cell)