Reproducer for bug 1983753
Related-Bug: #1983753 Change-Id: Ic6566272b8c5af57cd1c73c73b3cba6cd265bebe (cherry picked from commit 6d602c6b734c2e360fa319ba22c2fced02ad3d29) (cherry picked from commit bdc32226e2d9ce4a073306f8f6267fbe305e64e4)
This commit is contained in:
parent
62e1a621d1
commit
87a8a7df98
193
nova/tests/functional/regressions/test_bug_1983753.py
Normal file
193
nova/tests/functional/regressions/test_bug_1983753.py
Normal file
@ -0,0 +1,193 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# 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 fixtures
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from nova.tests.fixtures import libvirt as fakelibvirt
|
||||
from nova.tests.functional.api import client
|
||||
from nova.tests.functional.libvirt import test_pci_sriov_servers
|
||||
|
||||
|
||||
class TestPciResize(test_pci_sriov_servers._PCIServersTestBase):
|
||||
# these tests use multiple different configs so the whitelist is set by
|
||||
# each testcase individually
|
||||
PCI_PASSTHROUGH_WHITELIST = []
|
||||
PCI_ALIAS = [
|
||||
jsonutils.dumps(x)
|
||||
for x in [
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.PCI_PROD_ID,
|
||||
"name": "a-pci-dev",
|
||||
},
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.PF_PROD_ID,
|
||||
"device_type": "type-PF",
|
||||
"name": "a-pf",
|
||||
},
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.VF_PROD_ID,
|
||||
"device_type": "type-VF",
|
||||
"name": "a-vf",
|
||||
},
|
||||
]
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.useFixture(
|
||||
fixtures.MockPatch(
|
||||
'nova.virt.libvirt.driver.LibvirtDriver.'
|
||||
'migrate_disk_and_power_off',
|
||||
return_value='{}'
|
||||
)
|
||||
)
|
||||
# These tests should not depend on the host's sysfs
|
||||
self.useFixture(
|
||||
fixtures.MockPatch('nova.pci.utils.is_physical_function'))
|
||||
self.useFixture(
|
||||
fixtures.MockPatch(
|
||||
'nova.pci.utils.get_function_by_ifname',
|
||||
return_value=(None, False)
|
||||
)
|
||||
)
|
||||
|
||||
def _test_resize_from_two_devs_to_one_dev(self, num_pci_on_dest):
|
||||
# The fake libvirt will emulate on the host:
|
||||
# * two type-PCI in slot 0, 1
|
||||
compute1_pci_info = fakelibvirt.HostPCIDevicesInfo(num_pci=2)
|
||||
# the config matches the PCI dev
|
||||
compute1_device_spec = [
|
||||
jsonutils.dumps(x)
|
||||
for x in [
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.PCI_PROD_ID,
|
||||
},
|
||||
]
|
||||
]
|
||||
self.flags(group='pci', passthrough_whitelist=compute1_device_spec)
|
||||
self.start_compute(hostname="compute1", pci_info=compute1_pci_info)
|
||||
self.assertPCIDeviceCounts("compute1", total=2, free=2)
|
||||
|
||||
# create a server that requests two PCI devs
|
||||
extra_spec = {"pci_passthrough:alias": "a-pci-dev:2"}
|
||||
flavor_id = self._create_flavor(extra_spec=extra_spec)
|
||||
server = self._create_server(flavor_id=flavor_id, networks=[])
|
||||
self.assertPCIDeviceCounts("compute1", total=2, free=0)
|
||||
|
||||
# start another compute with a different amount of PCI dev available
|
||||
compute2_pci_info = fakelibvirt.HostPCIDevicesInfo(
|
||||
num_pci=num_pci_on_dest)
|
||||
# the config matches the PCI dev
|
||||
compute2_device_spec = [
|
||||
jsonutils.dumps(x)
|
||||
for x in [
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.PCI_PROD_ID,
|
||||
},
|
||||
]
|
||||
]
|
||||
self.flags(group='pci', passthrough_whitelist=compute2_device_spec)
|
||||
self.start_compute(hostname="compute2", pci_info=compute2_pci_info)
|
||||
self.assertPCIDeviceCounts(
|
||||
"compute2", total=num_pci_on_dest, free=num_pci_on_dest)
|
||||
|
||||
# resize the server to request only one PCI dev instead of the current
|
||||
# two. This should fit to compute2 having at least one dev
|
||||
extra_spec = {"pci_passthrough:alias": "a-pci-dev:1"}
|
||||
flavor_id = self._create_flavor(extra_spec=extra_spec)
|
||||
self._resize_server(server, flavor_id=flavor_id)
|
||||
self._confirm_resize(server)
|
||||
self.assertPCIDeviceCounts("compute1", total=2, free=2)
|
||||
self.assertPCIDeviceCounts(
|
||||
"compute2", total=num_pci_on_dest, free=num_pci_on_dest - 1)
|
||||
|
||||
def test_resize_from_two_devs_to_one_dev_dest_has_two_devs(self):
|
||||
# this works
|
||||
self._test_resize_from_two_devs_to_one_dev(num_pci_on_dest=2)
|
||||
|
||||
def test_resize_from_two_devs_to_one_dev_dest_has_one_dev(self):
|
||||
# This is bug 1983753 as nova uses the old InstancePciRequest during
|
||||
# the scheduling and therefore tries to find a compute with two PCI
|
||||
# devs even though the flavor only requests one.
|
||||
ex = self.assertRaises(
|
||||
client.OpenStackApiException,
|
||||
self._test_resize_from_two_devs_to_one_dev,
|
||||
num_pci_on_dest=1
|
||||
)
|
||||
self.assertIn('nova.exception.NoValidHost', str(ex))
|
||||
|
||||
def test_resize_from_vf_to_pf(self):
|
||||
# The fake libvirt will emulate on the host:
|
||||
# * one type-PF in slot 0 with one VF
|
||||
compute1_pci_info = fakelibvirt.HostPCIDevicesInfo(
|
||||
num_pfs=1, num_vfs=1)
|
||||
# the config matches only the VF
|
||||
compute1_device_spec = [
|
||||
jsonutils.dumps(x)
|
||||
for x in [
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.VF_PROD_ID,
|
||||
},
|
||||
]
|
||||
]
|
||||
self.flags(group='pci', passthrough_whitelist=compute1_device_spec)
|
||||
self.start_compute(hostname="compute1", pci_info=compute1_pci_info)
|
||||
self.assertPCIDeviceCounts("compute1", total=1, free=1)
|
||||
|
||||
# create a server that requests one Vf
|
||||
extra_spec = {"pci_passthrough:alias": "a-vf:1"}
|
||||
flavor_id = self._create_flavor(extra_spec=extra_spec)
|
||||
server = self._create_server(flavor_id=flavor_id, networks=[])
|
||||
self.assertPCIDeviceCounts("compute1", total=1, free=0)
|
||||
|
||||
# start another compute with a single PF dev available
|
||||
# The fake libvirt will emulate on the host:
|
||||
# * one type-PF in slot 0 with 1 VF
|
||||
compute2_pci_info = fakelibvirt.HostPCIDevicesInfo(
|
||||
num_pfs=1, num_vfs=1)
|
||||
# the config matches the PF dev but not the VF
|
||||
compute2_device_spec = [
|
||||
jsonutils.dumps(x)
|
||||
for x in [
|
||||
{
|
||||
"vendor_id": fakelibvirt.PCI_VEND_ID,
|
||||
"product_id": fakelibvirt.PF_PROD_ID,
|
||||
},
|
||||
]
|
||||
]
|
||||
self.flags(group='pci', passthrough_whitelist=compute2_device_spec)
|
||||
self.start_compute(hostname="compute2", pci_info=compute2_pci_info)
|
||||
self.assertPCIDeviceCounts("compute2", total=1, free=1)
|
||||
|
||||
# resize the server to request on PF dev instead of the current VF
|
||||
# dev. This should fit to compute2 having exactly one PF dev.
|
||||
extra_spec = {"pci_passthrough:alias": "a-pf:1"}
|
||||
flavor_id = self._create_flavor(extra_spec=extra_spec)
|
||||
# This is bug 1983753 as nova uses the old InstancePciRequest during
|
||||
# the scheduling and therefore tries to find a compute with a VF dev
|
||||
# even though the flavor only requests a PF dev.
|
||||
ex = self.assertRaises(
|
||||
client.OpenStackApiException,
|
||||
self._resize_server,
|
||||
server,
|
||||
flavor_id=flavor_id,
|
||||
)
|
||||
self.assertIn('nova.exception.NoValidHost', str(ex))
|
Loading…
x
Reference in New Issue
Block a user