tests: generate correct pci addresses for fake pci devices

fakelibvirt library was not generating a correct pci address for
its fake pci devices. PCI slot field would remain constant in all
generated devices.

While this issue would be transparrent for most of the tests,
but test_create_server_with_PF_no_VF would be affected, as it
should lookup VFs by its addresses.

Change-Id: I810b1087229366770f1ea536b67e3b9741a030a8
This commit is contained in:
Vladik Romanovsky 2016-12-06 17:07:19 -05:00
parent f61db221f3
commit 624e10ffd2
2 changed files with 93 additions and 7 deletions

View File

@ -171,8 +171,8 @@ PF_SLOT = '00'
class FakePciDevice(object):
pci_dev_template = """<device>
<name>pci_0000_81_%(slot)s_%(dev)d</name>
<path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:%(slot)s.%(dev)d</path>
<name>pci_0000_81_%(slot)02x_%(dev)d</name>
<path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:%(slot)02x.%(dev)d</path>
<parent>pci_0000_80_01_0</parent>
<driver>
<name>%(driver)s</name>
@ -180,7 +180,7 @@ class FakePciDevice(object):
<capability type='pci'>
<domain>0</domain>
<bus>129</bus>
<slot>0</slot>
<slot>%(slot)d</slot>
<function>%(dev)d</function>
<product id='0x%(prod)d'>%(prod_name)s</product>
<vendor id='0x8086'>Intel Corporation</vendor>
@ -188,7 +188,7 @@ class FakePciDevice(object):
%(functions)s
</capability>
<iommuGroup number='%(group_id)d'>
<address domain='0x0000' bus='0x81' slot='0x%(slot)s' function='0x%(dev)d'/>
<address domain='0x0000' bus='0x81' slot='%(slot)#02x' function='0x%(dev)d'/>
</iommuGroup>
<numa node='%(numa_node)s'/>
<pci-express>
@ -216,17 +216,19 @@ class FakePciDevice(object):
pf_caps = [addr_templ % {'dev': x, 'slot': VF_SLOT}
for x in range(dev * vf_ratio,
(dev + 1) * vf_ratio)]
slot = int(str(PF_SLOT), 16)
self.pci_dev = self.pci_dev_template % {'dev': dev,
'prod': product_id, 'group_id': group,
'functions': '\n'.join(pf_caps), 'slot': 0,
'functions': '\n'.join(pf_caps), 'slot': slot,
'cap_type': PF_CAP_TYPE, 'prod_name': PF_PROD_NAME,
'driver': PF_DRIVER_NAME, 'numa_node': numa_node}
elif dev_type == 'VF':
vf_caps = [addr_templ % {'dev': int(dev / vf_ratio),
'slot': PF_SLOT}]
slot = int(str(VF_SLOT), 16)
self.pci_dev = self.pci_dev_template % {'dev': dev,
'prod': product_id, 'group_id': group,
'functions': '\n'.join(vf_caps), 'slot': VF_SLOT,
'functions': '\n'.join(vf_caps), 'slot': slot,
'cap_type': VF_CAP_TYPE, 'prod_name': VF_PROD_NAME,
'driver': VF_DRIVER_NAME, 'numa_node': numa_node}
@ -256,7 +258,7 @@ class HostPciSRIOVDevicesInfo(object):
def _calc_numa_node(dev):
return dev % total_numa_nodes if numa_node is None else numa_node
vf_ratio = num_vfs / num_pfs
vf_ratio = num_vfs // num_pfs
# Generate PFs
for dev in range(num_pfs):

View File

@ -18,6 +18,7 @@ import six
from nova.objects import fields as obj_fields
from nova import test
import nova.tests.unit.virt.libvirt.fakelibvirt as libvirt
from nova.virt.libvirt import config as vconfig
def get_vm_xml(name="testname", uuid=None, source_type='file',
@ -418,3 +419,86 @@ class FakeLibvirtTests(test.NoDBTestCase):
kb_mem=15740000)
self.assertEqual(host_topology.to_xml(),
topology)
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()
pci_info.create_pci_devices(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')