def test_create_server_with_pci_dev_and_numa(self, img_mock): """Verifies that an instance can be booted with cpu pinning and with an assigned pci device. """ host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=1) fake_connection = self._get_connection(host_info, pci_info) # Create a flavor extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name, 'hw:numa_nodes': '1', 'hw:cpu_policy': 'dedicated', 'hw:cpu_thread_policy': 'prefer'} flavor_id = self._create_flavor(extra_spec=extra_spec) host_pass_mock = self._get_pci_passthrough_filter_spy() with test.nested( mock.patch('nova.virt.libvirt.host.Host.get_connection', return_value=fake_connection), mock.patch('nova.scheduler.filters' '.pci_passthrough_filter.PciPassthroughFilter' '.host_passes', side_effect=host_pass_mock)) as (conn_mock, filter_mock): pf_server = self._run_build_test(flavor_id, filter_mock) self._delete_server(pf_server['id'])
def test_create_server_with_pci_dev_and_numa_fails(self, img_mock): """This test ensures that it is not possible to allocated CPU and memory resources from one NUMA node and a PCI device from another. """ host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=0) fake_connection = self._get_connection(host_info, pci_info) # Create a flavor extra_spec_vm = {'hw:cpu_policy': 'dedicated', 'hw:numa_node': '1'} extra_spec = {'pci_passthrough:alias': '%s:1' % self.pfs_alias_name, 'hw:numa_nodes': '1', 'hw:cpu_policy': 'dedicated', 'hw:cpu_thread_policy': 'prefer'} vm_flavor_id = self._create_flavor(vcpu=4, extra_spec=extra_spec_vm) pf_flavor_id = self._create_flavor(extra_spec=extra_spec) host_pass_mock = self._get_pci_passthrough_filter_spy() with test.nested( mock.patch('nova.virt.libvirt.host.Host.get_connection', return_value=fake_connection), mock.patch('nova.scheduler.filters' '.pci_passthrough_filter.PciPassthroughFilter' '.host_passes', side_effect=host_pass_mock)) as (conn_mock, filter_mock): vm_server = self._run_build_test(vm_flavor_id, filter_mock) pf_server = self._run_build_test(pf_flavor_id, filter_mock, end_status='ERROR') self._delete_server(vm_server['id']) self._delete_server(pf_server['id'])
def test_create_server_with_VF_no_PF(self, img_mock): host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, num_vfs=4) fake_connection = self._get_connection(host_info, pci_info) # Create a flavor extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name} extra_spec_vfs = {"pci_passthrough:alias": "%s:1" % self.vfs_alias_name} flavor_id = self._create_flavor(extra_spec=extra_spec) flavor_id_vfs = self._create_flavor(extra_spec=extra_spec_vfs) host_pass_mock = self._get_pci_passthrough_filter_spy() with test.nested( mock.patch('nova.virt.libvirt.host.Host.get_connection', return_value=fake_connection), mock.patch('nova.scheduler.filters' '.pci_passthrough_filter.PciPassthroughFilter' '.host_passes', side_effect=host_pass_mock)) as (conn_mock, filter_mock): vf_server = self._run_build_test(flavor_id_vfs, filter_mock) pf_server = self._run_build_test(flavor_id, filter_mock, end_status='ERROR') self._delete_server(pf_server['id']) self._delete_server(vf_server['id'])
def test_create_server_with_PF(self, img_mock): host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo() fake_connection = self._get_connection(host_info, pci_info) self.mock_conn.return_value = fake_connection # Create a flavor extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name} flavor_id = self._create_flavor(extra_spec=extra_spec) self._run_build_test(flavor_id)
def test_create_server_with_pci_dev_and_numa(self, img_mock): """Verifies that an instance can be booted with cpu pinning and with an assigned pci device. """ host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=1) fake_connection = self._get_connection(host_info, pci_info) self.mock_conn.return_value = fake_connection # Create a flavor extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name, 'hw:numa_nodes': '1', 'hw:cpu_policy': 'dedicated', 'hw:cpu_thread_policy': 'prefer'} flavor_id = self._create_flavor(extra_spec=extra_spec) self._run_build_test(flavor_id)
def test_create_server_with_pci_dev_and_numa_fails(self, img_mock): """This test ensures that it is not possible to allocated CPU and memory resources from one NUMA node and a PCI device from another. """ host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, kB_mem=15740000) pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=0) fake_connection = self._get_connection(host_info, pci_info) self.mock_conn.return_value = fake_connection # Create a flavor extra_spec_vm = {'hw:cpu_policy': 'dedicated', 'hw:numa_node': '1'} extra_spec = {'pci_passthrough:alias': '%s:1' % self.pfs_alias_name, 'hw:numa_nodes': '1', 'hw:cpu_policy': 'dedicated', 'hw:cpu_thread_policy': 'prefer'} vm_flavor_id = self._create_flavor(vcpu=4, extra_spec=extra_spec_vm) pf_flavor_id = self._create_flavor(extra_spec=extra_spec) self._run_build_test(vm_flavor_id) self._run_build_test(pf_flavor_id, end_status='ERROR')
def test_pci_devices_generation(self): def _cmp_pci_dev_addr(dev_xml, cmp_addr): cfgdev = vconfig.LibvirtConfigNodeDevice() cfgdev.parse_str(dev_xml) address = "%04x:%02x:%02x.%1x" % ( cfgdev.pci_capability.domain, cfgdev.pci_capability.bus, cfgdev.pci_capability.slot, cfgdev.pci_capability.function) self.assertEqual(cmp_addr, address) pf_xml = """<device> <name>pci_0000_81_00_0</name> <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:00.0</path> <parent>pci_0000_80_01_0</parent> <driver> <name>ixgbe</name> </driver> <capability type='pci'> <domain>0</domain> <bus>129</bus> <slot>0</slot> <function>0</function> <product id='0x1528'>Ethernet Controller 10-Gigabit X540-AT2</product> <vendor id='0x8086'>Intel Corporation</vendor> <capability type='virt_functions'> <address domain='0x0000' bus='0x81' slot='0x10' function='0x0'/> </capability> <iommuGroup number='48'> <address domain='0x0000' bus='0x81' slot='0x0' function='0x0'/> </iommuGroup> <numa node='0'/> <pci-express> <link validity='cap' port='0' speed='5' width='8'/> <link validity='sta' speed='5' width='8'/> </pci-express> </capability> </device>""" vf_xml = """<device> <name>pci_0000_81_10_0</name> <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:10.0</path> <parent>pci_0000_80_01_0</parent> <driver> <name>ixgbevf</name> </driver> <capability type='pci'> <domain>0</domain> <bus>129</bus> <slot>16</slot> <function>0</function> <product id='0x1515'>X540 Ethernet Controller Virtual Function</product> <vendor id='0x8086'>Intel Corporation</vendor> <capability type='phys_function'> <address domain='0x0000' bus='0x81' slot='0x00' function='0x0'/> </capability> <iommuGroup number='48'> <address domain='0x0000' bus='0x81' slot='0x10' function='0x0'/> </iommuGroup> <numa node='0'/> <pci-express> <link validity='cap' port='0' speed='5' width='8'/> <link validity='sta' speed='5' width='8'/> </pci-express> </capability> </device>""" # create fake pci devices pci_info = libvirt.HostPciSRIOVDevicesInfo(num_pfs=1, num_vfs=1) # generate xml for the created pci devices gen_pf = pci_info.get_device_by_name('pci_0000_81_00_0') gen_vf = pci_info.get_device_by_name('pci_0000_81_10_0') self.assertEqual(gen_pf.XMLDesc(0), pf_xml) self.assertEqual(gen_vf.XMLDesc(0), vf_xml) # parse the generated xml with a libvirt config class and compare # device address _cmp_pci_dev_addr(pf_xml, '0000:81:00.0') _cmp_pci_dev_addr(vf_xml, '0000:81:10.0')