Skip to content

Commit

Permalink
Refactor bandwidth related functional tests
Browse files Browse the repository at this point in the history
The common code that checked the allocation on the compute RP is move to
a separate function.

The PCI addresses used by the fake virt driver are moved to a constant.

Change-Id: I02179e5d1138278021200d2bad7c7d05efda0ea2
  • Loading branch information
Balazs Gibizer committed May 1, 2019
1 parent 095d3f9 commit c0c6afd
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 45 deletions.
75 changes: 42 additions & 33 deletions nova/tests/functional/test_servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6115,6 +6115,13 @@ def setUp(self):
macvtap = self.neutron.port_macvtap_with_resource_request
self.neutron._ports[macvtap['id']] = copy.deepcopy(macvtap)

def assertComputeAllocationMatchesFlavor(
self, allocations, compute_rp_uuid, flavor):
compute_allocations = allocations[compute_rp_uuid]['resources']
self.assertEqual(
self._resources_from_flavor(flavor),
compute_allocations)

def _create_server(self, flavor, networks):
server_req = self._build_minimal_create_server_request(
self.api, 'bandwidth-aware-server',
Expand Down Expand Up @@ -6535,12 +6542,11 @@ def test_boot_server_with_two_ports_one_having_resource_request(self):
# compute rp and one set for the networking resources on the ovs bridge
# rp due to the qos_port resource request
self.assertEqual(2, len(allocations))
compute_allocations = allocations[self.compute1_rp_uuid]['resources']

self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor)
network_allocations = allocations[
self.ovs_bridge_rp_per_host[self.compute1_rp_uuid]]['resources']

self.assertEqual(self._resources_from_flavor(self.flavor),
compute_allocations)
self.assertPortMatchesAllocation(qos_port, network_allocations)

# We expect that only the RP uuid of the networking RP having the port
Expand Down Expand Up @@ -6582,15 +6588,13 @@ def test_one_ovs_one_sriov_port(self):
# compute rp and one set for the networking resources on the ovs bridge
# rp and on the sriov PF rp.
self.assertEqual(3, len(allocations))
compute_allocations = allocations[self.compute1_rp_uuid]['resources']

self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor_with_group_policy)

ovs_allocations = allocations[
self.ovs_bridge_rp_per_host[self.compute1_rp_uuid]]['resources']
sriov_allocations = allocations[self.sriov_pf2_rp_uuid]['resources']

self.assertEqual(
self._resources_from_flavor(self.flavor_with_group_policy),
compute_allocations)

self.assertPortMatchesAllocation(ovs_port, ovs_allocations)
self.assertPortMatchesAllocation(sriov_port, sriov_allocations)

Expand Down Expand Up @@ -6619,12 +6623,12 @@ def test_interface_detach_with_port_with_bandwidth_request(self):
# compute rp and one set for the networking resources on the ovs bridge
# rp due to the port resource request
self.assertEqual(2, len(allocations))
compute_allocations = allocations[self.compute1_rp_uuid]['resources']

self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor)

network_allocations = allocations[
self.ovs_bridge_rp_per_host[self.compute1_rp_uuid]]['resources']

self.assertEqual(self._resources_from_flavor(self.flavor),
compute_allocations)
self.assertPortMatchesAllocation(port, network_allocations)

# We expect that only the RP uuid of the networking RP having the port
Expand All @@ -6649,9 +6653,9 @@ def test_interface_detach_with_port_with_bandwidth_request(self):

# We expect that the port related resource allocations are removed
self.assertEqual(1, len(allocations))
compute_allocations = allocations[self.compute1_rp_uuid]['resources']
self.assertEqual(self._resources_from_flavor(self.flavor),
compute_allocations)

self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor)

# We expect that the allocation is removed from the port too
binding_profile = updated_port['binding:profile']
Expand Down Expand Up @@ -6700,10 +6704,9 @@ def test_two_sriov_ports_one_with_request_two_available_pfs(self):
# compute rp and one set for the networking resources on the sriov PF2
# rp.
self.assertEqual(2, len(allocations))
compute_allocations = allocations[self.compute1_rp_uuid]['resources']
self.assertEqual(
self._resources_from_flavor(self.flavor_with_group_policy),
compute_allocations)

self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor_with_group_policy)

sriov_allocations = allocations[self.sriov_pf2_rp_uuid]['resources']
self.assertPortMatchesAllocation(
Expand All @@ -6722,11 +6725,15 @@ def test_two_sriov_ports_one_with_request_two_available_pfs(self):
# We expect that the selected PCI device matches with the RP from
# where the bandwidth is allocated from. The bandwidth is allocated
# from 0000:02:00 (PF2) so the PCI device should be a VF of that PF
self.assertEqual('0000:02:00.1', sriov_with_req_binding['pci_slot'])
self.assertEqual(
fake.FakeDriverWithPciResources.PCI_ADDR_PF2_VF1,
sriov_with_req_binding['pci_slot'])
# But also the port that has no resource request still gets a pci slot
# allocated. The 0000:02:00 has no more VF available but 0000:03:00 has
# one VF available and that PF is also on physnet2
self.assertEqual('0000:03:00.1', sriov_binding['pci_slot'])
self.assertEqual(
fake.FakeDriverWithPciResources.PCI_ADDR_PF3_VF1,
sriov_binding['pci_slot'])

def test_one_sriov_port_no_vf_and_bandwidth_available_on_the_same_pf(self):
"""Verify that if there is no PF that both provides bandwidth and VFs
Expand All @@ -6744,7 +6751,9 @@ def test_one_sriov_port_no_vf_and_bandwidth_available_on_the_same_pf(self):
sriov_binding = sriov_port['binding:profile']

# We expect that this consume the last available VF from the PF2
self.assertEqual('0000:02:00.1', sriov_binding['pci_slot'])
self.assertEqual(
fake.FakeDriverWithPciResources.PCI_ADDR_PF2_VF1,
sriov_binding['pci_slot'])

# Now boot a second server with a port that has resource request
# At this point PF2 has available bandwidth but no available VF
Expand Down Expand Up @@ -6790,10 +6799,8 @@ def test_sriov_macvtap_port_with_resource_request(self):
# rp.
self.assertEqual(2, len(allocations))

compute_allocations = allocations[self.compute1_rp_uuid]['resources']
self.assertEqual(
self._resources_from_flavor(self.flavor),
compute_allocations)
self.assertComputeAllocationMatchesFlavor(
allocations, self.compute1_rp_uuid, self.flavor)

sriov_allocations = allocations[self.sriov_pf2_rp_uuid]['resources']
self.assertPortMatchesAllocation(
Expand All @@ -6809,7 +6816,9 @@ def test_sriov_macvtap_port_with_resource_request(self):
# We expect that the selected PCI device matches with the RP from
# where the bandwidth is allocated from. The bandwidth is allocated
# from 0000:02:00 (PF2) so the PCI device should be a VF of that PF
self.assertEqual('0000:02:00.1', port_binding['pci_slot'])
self.assertEqual(
fake.FakeDriverWithPciResources.PCI_ADDR_PF2_VF1,
port_binding['pci_slot'])


class PortResourceRequestReSchedulingTest(
Expand Down Expand Up @@ -6856,12 +6865,12 @@ def test_boot_reschedule_success(self):
# compute rp and one set for the networking resources on the ovs bridge
# rp
self.assertEqual(2, len(allocations))
compute_allocations = allocations[dest_compute_rp_uuid]['resources']

self.assertComputeAllocationMatchesFlavor(
allocations, dest_compute_rp_uuid, self.flavor)

network_allocations = allocations[
self.ovs_bridge_rp_per_host[dest_compute_rp_uuid]]['resources']

self.assertEqual(self._resources_from_flavor(self.flavor),
compute_allocations)
self.assertPortMatchesAllocation(port, network_allocations)

# assert that the allocations against the host where the spawn
Expand Down
31 changes: 19 additions & 12 deletions nova/virt/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,13 @@ class FakeLiveMigrateDriverWithNestedCustomResources(

class FakeDriverWithPciResources(SmallFakeDriver):

PCI_ADDR_PF1 = '0000:01:00.0'
PCI_ADDR_PF1_VF1 = '0000:01:00.1'
PCI_ADDR_PF2 = '0000:02:00.0'
PCI_ADDR_PF2_VF1 = '0000:02:00.1'
PCI_ADDR_PF3 = '0000:03:00.0'
PCI_ADDR_PF3_VF1 = '0000:03:00.1'

# NOTE(gibi): Always use this fixture along with the
# FakeDriverWithPciResources to make the necessary configuration for the
# driver.
Expand Down Expand Up @@ -907,17 +914,17 @@ def setUp(self):
def get_available_resource(self, nodename):
host_status = super(
FakeDriverWithPciResources, self).get_available_resource(nodename)
# 01:00 - PF - ens1
# 01:00.0 - PF - ens1
# |---- 01:00.1 - VF
#
# 02:00 - PF - ens2
# 02:00.0 - PF - ens2
# |---- 02:00.1 - VF
#
# 03:00 - PF - ens3
# 03:00.0 - PF - ens3
# |---- 03:00.1 - VF
host_status['pci_passthrough_devices'] = jsonutils.dumps([
{
'address': '0000:01:00.0',
'address': self.PCI_ADDR_PF1,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
Expand All @@ -927,18 +934,18 @@ def get_available_resource(self, nodename):
'label': 'fake-label',
},
{
'address': '0000:01:00.1',
'address': self.PCI_ADDR_PF1_VF1,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
'dev_type': 'type-VF',
'parent_addr': '0000:01:00',
'parent_addr': self.PCI_ADDR_PF1,
'numa_node': 0,
'label': 'fake-label',
"parent_ifname": "ens1",
},
{
'address': '0000:02:00.0',
'address': self.PCI_ADDR_PF2,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
Expand All @@ -948,18 +955,18 @@ def get_available_resource(self, nodename):
'label': 'fake-label',
},
{
'address': '0000:02:00.1',
'address': self.PCI_ADDR_PF2_VF1,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
'dev_type': 'type-VF',
'parent_addr': '0000:02:00',
'parent_addr': self.PCI_ADDR_PF2,
'numa_node': 0,
'label': 'fake-label',
"parent_ifname": "ens2",
},
{
'address': '0000:03:00.0',
'address': self.PCI_ADDR_PF3,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
Expand All @@ -969,12 +976,12 @@ def get_available_resource(self, nodename):
'label': 'fake-label',
},
{
'address': '0000:03:00.1',
'address': self.PCI_ADDR_PF3_VF1,
'product_id': 'fake-product_id',
'vendor_id': 'fake-vendor_id',
'status': 'available',
'dev_type': 'type-VF',
'parent_addr': '0000:03:00',
'parent_addr': self.PCI_ADDR_PF3,
'numa_node': 0,
'label': 'fake-label',
"parent_ifname": "ens3",
Expand Down

0 comments on commit c0c6afd

Please sign in to comment.