def setUp(self): super(NUMATopologyClaimsTest, self).setUp() self.host = hw.VirtNUMAHostTopology( cells=[ hw.VirtNUMATopologyCellUsage( 1, set([1, 2, 3, 4]), 2048, cpu_usage=1, memory_usage=512), hw.VirtNUMATopologyCellUsage( 2, set([5, 6]), 1024)]) self.limits = hw.VirtNUMALimitTopology( cells=[ hw.VirtNUMATopologyCellLimit( 1, set([1, 2, 3, 4]), 2048, cpu_limit=8, memory_limit=4096), hw.VirtNUMATopologyCellLimit( 2, set([5, 6]), 1024, cpu_limit=4, memory_limit=2048)]) self.large_instance = hw.VirtNUMAInstanceTopology( cells=[ hw.VirtNUMATopologyCell(1, set([1, 2, 3, 4, 5, 6]), 8192), hw.VirtNUMATopologyCell(2, set([7, 8]), 4096)]) self.medium_instance = hw.VirtNUMAInstanceTopology( cells=[ hw.VirtNUMATopologyCell(1, set([1, 2, 3, 4]), 1024), hw.VirtNUMATopologyCell(2, set([7, 8]), 2048)]) self.small_instance = hw.VirtNUMAInstanceTopology( cells=[ hw.VirtNUMATopologyCell(1, set([1]), 256), hw.VirtNUMATopologyCell(2, set([5]), 1024)])
def test_host_usage_sparse(self): hosttopo = hw.VirtNUMAHostTopology([ hw.VirtNUMATopologyCellUsage(0, set([0, 1, 2, 3]), 1024), hw.VirtNUMATopologyCellUsage(5, set([4, 6]), 512), hw.VirtNUMATopologyCellUsage(6, set([5, 7]), 512), ]) instance1 = hw.VirtNUMAInstanceTopology([ hw.VirtNUMATopologyCell(0, set([0, 1, 2]), 256), hw.VirtNUMATopologyCell(6, set([4]), 256), ]) instance2 = hw.VirtNUMAInstanceTopology([ hw.VirtNUMATopologyCell(0, set([0, 1]), 256), hw.VirtNUMATopologyCell(5, set([5, 7]), 256), ]) hostusage = hw.VirtNUMAHostTopology.usage_from_instances( hosttopo, [instance1, instance2]) self.assertEqual(len(hosttopo), len(hostusage)) self.assertIsInstance(hostusage.cells[0], hw.VirtNUMATopologyCellUsage) self.assertEqual(hosttopo.cells[0].id, hostusage.cells[0].id) self.assertEqual(hosttopo.cells[0].cpuset, hostusage.cells[0].cpuset) self.assertEqual(hosttopo.cells[0].memory, hostusage.cells[0].memory) self.assertEqual(hostusage.cells[0].cpu_usage, 5) self.assertEqual(hostusage.cells[0].memory_usage, 512) self.assertIsInstance(hostusage.cells[1], hw.VirtNUMATopologyCellUsage) self.assertEqual(hosttopo.cells[1].id, hostusage.cells[1].id) self.assertEqual(hosttopo.cells[1].cpuset, hostusage.cells[1].cpuset) self.assertEqual(hosttopo.cells[1].memory, hostusage.cells[1].memory) self.assertEqual(hostusage.cells[1].cpu_usage, 2) self.assertEqual(hostusage.cells[1].memory_usage, 256) self.assertIsInstance(hostusage.cells[2], hw.VirtNUMATopologyCellUsage) self.assertEqual(hosttopo.cells[2].cpuset, hostusage.cells[2].cpuset) self.assertEqual(hosttopo.cells[2].memory, hostusage.cells[2].memory) self.assertEqual(hostusage.cells[2].cpu_usage, 1) self.assertEqual(hostusage.cells[2].memory_usage, 256)
def test_numa_topology_filter_pass_set_limit(self): self.flags(cpu_allocation_ratio=21) self.flags(ram_allocation_ratio=1.3) instance_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCellInstance(0, set([1]), 512), hardware.VirtNUMATopologyCellInstance(1, set([3]), 512) ]) instance = fake_instance.fake_instance_obj(mock.sentinel.ctx) instance.numa_topology = ( objects.InstanceNUMATopology.obj_from_topology(instance_topology)) filter_properties = { 'request_spec': { 'instance_properties': jsonutils.to_primitive(obj_base.obj_to_primitive(instance)) } } host = fakes.FakeHostState('host1', 'node1', {'numa_topology': fakes.NUMA_TOPOLOGY}) self.assertTrue(self.filt_cls.host_passes(host, filter_properties)) limits_topology = hardware.VirtNUMALimitTopology.from_json( host.limits['numa_topology']) self.assertEqual(limits_topology.cells[0].cpu_limit, 42) self.assertEqual(limits_topology.cells[1].cpu_limit, 42) self.assertEqual(limits_topology.cells[0].memory_limit, 665) self.assertEqual(limits_topology.cells[1].memory_limit, 665)
def topology_from_obj(self): cells = [] for objcell in self.cells: cell = hardware.VirtNUMATopologyCell(objcell.id, objcell.cpuset, objcell.memory) cells.append(cell) return hardware.VirtNUMAInstanceTopology(cells=cells)
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 topology_from_obj(self): cells = [] for objcell in self.cells: pagesize = (objcell.pagesize and hardware.VirtPageSize(objcell.pagesize) or None) cell = hardware.VirtNUMATopologyCellInstance(objcell.id, objcell.cpuset, objcell.memory, pagesize=pagesize) cells.append(cell) return hardware.VirtNUMAInstanceTopology(cells=cells)
def test_numa_topology_passes(self, mock_get): huge_instance = hardware.VirtNUMAInstanceTopology( cells=[hardware.VirtNUMATopologyCell( 1, set([1, 2, 3, 4, 5]), 2048)]) limit_topo = hardware.VirtNUMALimitTopology( cells=[hardware.VirtNUMATopologyCellLimit( 1, [1, 2], 512, cpu_limit=5, memory_limit=4096), hardware.VirtNUMATopologyCellLimit( 1, [3, 4], 512, cpu_limit=5, memory_limit=4096)]) self._claim(limits={'numa_topology': limit_topo.to_json()}, numa_topology=huge_instance)
def setUp(self): super(HelperMethodsTestCase, self).setUp() self.hosttopo = hw.VirtNUMAHostTopology([ hw.VirtNUMATopologyCellUsage(0, set([0, 1]), 512), hw.VirtNUMATopologyCellUsage(1, set([2, 3]), 512), ]) self.instancetopo = hw.VirtNUMAInstanceTopology([ hw.VirtNUMATopologyCell(0, set([0, 1]), 256), hw.VirtNUMATopologyCell(1, set([2]), 256), ]) self.context = context.RequestContext('fake-user', 'fake-project')
def test_numa_topology_fails(self, mock_get): huge_instance = hardware.VirtNUMAInstanceTopology( cells=[hardware.VirtNUMATopologyCell( 1, set([1, 2, 3, 4, 5]), 2048)]) limit_topo = hardware.VirtNUMALimitTopology( cells=[hardware.VirtNUMATopologyCellLimit( 1, [1, 2], 512, cpu_limit=2, memory_limit=512), hardware.VirtNUMATopologyCellLimit( 1, [3, 4], 512, cpu_limit=2, memory_limit=512)]) self.assertRaises(exception.ComputeResourcesUnavailable, self._claim, limits={'numa_topology': limit_topo.to_json()}, numa_topology=huge_instance)
def test_numa_instance_topo_dict(self): topo = hw.VirtNUMAInstanceTopology( cells=[ hw.VirtNUMATopologyCell(1, set([1, 2]), 1024), hw.VirtNUMATopologyCell(2, set([3, 4]), 1024)]) topo_dict = {'cells': [ {'cpus': '1,2', 'mem': {'total': 1024}, 'id': 1}, {'cpus': '3,4', 'mem': {'total': 1024}, 'id': 2}]} self._test_to_dict(topo, topo_dict) self._test_topo_from_dict(topo_dict, topo)
def test_numa_topology_filter_numa_instance_no_numa_host_fail(self): instance_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCellInstance(0, set([1]), 512), hardware.VirtNUMATopologyCellInstance(1, set([3]), 512) ]) instance = fake_instance.fake_instance_obj(mock.sentinel.ctx) instance.numa_topology = ( objects.InstanceNUMATopology.obj_from_topology(instance_topology)) filter_properties = { 'request_spec': { 'instance_properties': jsonutils.to_primitive(obj_base.obj_to_primitive(instance)) } } host = fakes.FakeHostState('host1', 'node1', {}) self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
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_numa_topology_filter_pass(self): instance_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCell(0, set([1]), 512), hardware.VirtNUMATopologyCell(1, set([3]), 512) ]) instance = fake_instance.fake_instance_obj(self.context) instance.numa_topology = ( objects.InstanceNUMATopology.obj_from_topology(instance_topology)) filter_properties = { 'request_spec': { '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']() self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_numa_topology_filter_fail_memory(self): self.flags(ram_allocation_ratio=1) instance_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCellInstance(0, set([1]), 1024), hardware.VirtNUMATopologyCellInstance(1, set([3]), 512) ]) instance = fake_instance.fake_instance_obj(mock.sentinel.ctx) instance.numa_topology = ( objects.InstanceNUMATopology.obj_from_topology(instance_topology)) filter_properties = { 'request_spec': { 'instance_properties': jsonutils.to_primitive(obj_base.obj_to_primitive(instance)) } } host = fakes.FakeHostState('host1', 'node1', {'numa_topology': fakes.NUMA_TOPOLOGY}) self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import uuid import mock from nova import exception from nova import objects from nova.tests.unit.objects import test_objects from nova.virt import hardware fake_numa_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCellInstance(0, set([1, 2]), 512, hardware.VirtPageSize(2048)), hardware.VirtNUMATopologyCellInstance(1, set([3, 4]), 512, hardware.VirtPageSize(2048)) ]) fake_db_topology = { 'created_at': None, 'updated_at': None, 'deleted_at': None, 'deleted': 0, 'id': 1, 'instance_uuid': str(uuid.uuid4()), 'numa_topology': fake_numa_topology.to_json() } class _TestInstanceNUMATopology(object):
def test_numa_topology_no_limit(self, mock_get): huge_instance = hardware.VirtNUMAInstanceTopology( cells=[hardware.VirtNUMATopologyCell( 1, set([1, 2, 3, 4, 5]), 2048)]) self._claim(numa_topology=huge_instance)
def test_topology_constraints(self): testdata = [ { "flavor": FakeFlavor(8, 2048, {}), "image": {}, "expect": None, }, { "flavor": FakeFlavor(8, 2048, {"hw:numa_nodes": 2}), "image": {}, "expect": hw.VirtNUMAInstanceTopology([ hw.VirtNUMATopologyCell(0, set([0, 1, 2, 3]), 1024), hw.VirtNUMATopologyCell(1, set([4, 5, 6, 7]), 1024), ]), }, { # vcpus is not a multiple of nodes, so it # is an error to not provide cpu/mem mapping "flavor": FakeFlavor(8, 2048, {"hw:numa_nodes": 3}), "image": {}, "expect": exception.ImageNUMATopologyAsymmetric, }, { "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 3, "hw:numa_cpus.0": "0-3", "hw:numa_mem.0": "1024", "hw:numa_cpus.1": "4,6", "hw:numa_mem.1": "512", "hw:numa_cpus.2": "5,7", "hw:numa_mem.2": "512", }), "image": {}, "expect": hw.VirtNUMAInstanceTopology([ hw.VirtNUMATopologyCell(0, set([0, 1, 2, 3]), 1024), hw.VirtNUMATopologyCell(1, set([4, 6]), 512), hw.VirtNUMATopologyCell(2, set([5, 7]), 512), ]), }, { # Request a CPU that is out of range # wrt vCPU count "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 1, "hw:numa_cpus.0": "0-16", "hw:numa_mem.0": "2048", }), "image": {}, "expect": exception.ImageNUMATopologyCPUOutOfRange, }, { # Request the same CPU in two nodes "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_cpus.0": "0-7", "hw:numa_mem.0": "1024", "hw:numa_cpus.1": "0-7", "hw:numa_mem.1": "1024", }), "image": {}, "expect": exception.ImageNUMATopologyCPUDuplicates, }, { # Request with some CPUs not assigned "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_cpus.0": "0-2", "hw:numa_mem.0": "1024", "hw:numa_cpus.1": "3-4", "hw:numa_mem.1": "1024", }), "image": {}, "expect": exception.ImageNUMATopologyCPUsUnassigned, }, { # Request too little memory vs flavor total "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_cpus.0": "0-3", "hw:numa_mem.0": "512", "hw:numa_cpus.1": "4-7", "hw:numa_mem.1": "512", }), "image": {}, "expect": exception.ImageNUMATopologyMemoryOutOfRange, }, { # Request too much memory vs flavor total "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_cpus.0": "0-3", "hw:numa_mem.0": "1576", "hw:numa_cpus.1": "4-7", "hw:numa_mem.1": "1576", }), "image": {}, "expect": exception.ImageNUMATopologyMemoryOutOfRange, }, { # Request missing mem.0 "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_cpus.0": "0-3", "hw:numa_mem.1": "1576", }), "image": {}, "expect": exception.ImageNUMATopologyIncomplete, }, { # Request missing cpu.0 "flavor": FakeFlavor( 8, 2048, { "hw:numa_nodes": 2, "hw:numa_mem.0": "1576", "hw:numa_cpus.1": "4-7", }), "image": {}, "expect": exception.ImageNUMATopologyIncomplete, }, { # Image attempts to override flavor "flavor": FakeFlavor(8, 2048, { "hw:numa_nodes": 2, }), "image": { "hw_numa_nodes": 4, }, "expect": exception.ImageNUMATopologyForbidden, }, ] for testitem in testdata: if testitem["expect"] is None: topology = hw.VirtNUMAInstanceTopology.get_constraints( testitem["flavor"], testitem["image"]) self.assertIsNone(topology) elif type(testitem["expect"]) == type: self.assertRaises(testitem["expect"], hw.VirtNUMAInstanceTopology.get_constraints, testitem["flavor"], testitem["image"]) else: topology = hw.VirtNUMAInstanceTopology.get_constraints( testitem["flavor"], testitem["image"]) self.assertEqual(len(testitem["expect"].cells), len(topology.cells)) for i in range(len(topology.cells)): self.assertEqual(testitem["expect"].cells[i].cpuset, topology.cells[i].cpuset) self.assertEqual(testitem["expect"].cells[i].memory, topology.cells[i].memory)
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import uuid import mock from nova import exception from nova import objects from nova.tests.objects import test_objects from nova.virt import hardware fake_numa_topology = hardware.VirtNUMAInstanceTopology(cells=[ hardware.VirtNUMATopologyCell(0, set([1, 2]), 512), hardware.VirtNUMATopologyCell(1, set([3, 4]), 512) ]) fake_db_topology = { 'created_at': None, 'updated_at': None, 'deleted_at': None, 'deleted': 0, 'id': 1, 'instance_uuid': str(uuid.uuid4()), 'numa_topology': fake_numa_topology.to_json() } class _TestInstanceNUMATopology(object): def test_create(self):