Skip to content

Commit 17ba10b

Browse files
committed
functional: Add test for SR-IOV neutron ports
Add a simple test to demonstrate the interaction between nova and neutron when creating an instance with a (pre-created) SR-IOV port. Change-Id: I9d0596f31ca342b952c35c742befd75fdc39d95c Signed-off-by: Stephen Finucane <[email protected]>
1 parent cc8b300 commit 17ba10b

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

nova/tests/functional/libvirt/base.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,9 @@ class LibvirtNeutronFixture(nova_fixtures.NeutronFixture):
321321
'subnet_id': subnet_4['id']
322322
}
323323
],
324-
'binding:vif_details': {'vlan': 42},
325324
'binding:vif_type': 'hw_veb',
325+
'binding:vif_details': {'vlan': 42},
326326
'binding:vnic_type': 'direct',
327-
'binding:profile': {'pci_vendor_info': '1377:0047',
328-
'pci_slot': '0000:81:00.1',
329-
'physical_network': 'physnet4'},
330327
}
331328

332329
def __init__(self, test):
@@ -357,6 +354,15 @@ def create_port(self, body=None):
357354
# network_2_port_1 below at the update call
358355
port = copy.deepcopy(port)
359356
port.update(body['port'])
357+
358+
# the tenant ID is normally extracted from credentials in the request
359+
# and is not present in the body
360+
if 'tenant_id' not in port:
361+
port['tenant_id'] = nova_fixtures.NeutronFixture.tenant_id
362+
363+
# similarly, these attributes are set by neutron itself
364+
port['admin_state_up'] = True
365+
360366
self._ports[port['id']] = port
361367
# this copy is here as nova sometimes modifies the returned port
362368
# locally and we want to avoid that nova modifies the fixture internals

nova/tests/functional/libvirt/test_pci_sriov_servers.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class SRIOVServersTest(_PCIServersTestBase):
7474
{
7575
'vendor_id': fakelibvirt.PCI_VEND_ID,
7676
'product_id': fakelibvirt.VF_PROD_ID,
77+
'physical_network': 'physnet4',
7778
},
7879
)]
7980
# PFs will be removed from pools unless they are specifically
@@ -168,20 +169,82 @@ def test_create_server_with_VF_no_PF(self):
168169
flavor_id=flavor_id_pfs, networks='none', expected_state='ERROR',
169170
)
170171

172+
def test_create_server_with_neutron(self):
173+
"""Create an instance using a neutron-provisioned SR-IOV VIF."""
174+
175+
pci_info = fakelibvirt.HostPCIDevicesInfo(num_pfs=1, num_vfs=2)
176+
177+
orig_create = nova.virt.libvirt.guest.Guest.create
178+
179+
def fake_create(cls, xml, host):
180+
tree = etree.fromstring(xml)
181+
elem = tree.find('./devices/interface/source/address')
182+
183+
# compare address
184+
expected = ('0x81', '0x00', '0x2')
185+
actual = (
186+
elem.get('bus'), elem.get('slot'), elem.get('function'),
187+
)
188+
self.assertEqual(expected, actual)
189+
190+
return orig_create(xml, host)
191+
192+
self.stub_out(
193+
'nova.virt.libvirt.guest.Guest.create',
194+
fake_create,
195+
)
196+
197+
self.start_compute(pci_info=pci_info)
198+
199+
# create the port
200+
self.neutron.create_port({'port': self.neutron.network_4_port_1})
201+
202+
# ensure the binding details are currently unset
203+
port = self.neutron.show_port(
204+
base.LibvirtNeutronFixture.network_4_port_1['id'],
205+
)['port']
206+
self.assertNotIn('binding:profile', port)
207+
208+
# create a server using the VF via neutron
209+
flavor_id = self._create_flavor()
210+
self._create_server(
211+
flavor_id=flavor_id,
212+
networks=[
213+
{'port': base.LibvirtNeutronFixture.network_4_port_1['id']},
214+
],
215+
)
216+
217+
# ensure the binding details sent to "neutron" were correct
218+
port = self.neutron.show_port(
219+
base.LibvirtNeutronFixture.network_4_port_1['id'],
220+
)['port']
221+
self.assertIn('binding:profile', port)
222+
self.assertEqual(
223+
{
224+
'pci_vendor_info': '8086:1515',
225+
'pci_slot': '0000:81:00.2',
226+
'physical_network': 'physnet4',
227+
},
228+
port['binding:profile'],
229+
)
230+
171231
def test_get_server_diagnostics_server_with_VF(self):
172232
"""Ensure server disagnostics include info on VF-type PCI devices."""
173233

174234
pci_info = fakelibvirt.HostPCIDevicesInfo()
175235
self.start_compute(pci_info=pci_info)
176236

237+
# create the SR-IOV port
238+
self.neutron.create_port({'port': self.neutron.network_4_port_1})
239+
177240
# create a server using the VF and multiple networks
178241
extra_spec = {'pci_passthrough:alias': f'{self.VFS_ALIAS_NAME}:1'}
179242
flavor_id = self._create_flavor(extra_spec=extra_spec)
180243
server = self._create_server(
181244
flavor_id=flavor_id,
182245
networks=[
183246
{'uuid': base.LibvirtNeutronFixture.network_1['id']},
184-
{'uuid': base.LibvirtNeutronFixture.network_4['id']},
247+
{'port': base.LibvirtNeutronFixture.network_4_port_1['id']},
185248
],
186249
)
187250

0 commit comments

Comments
 (0)