diff options
Diffstat (limited to 'nova/tests/functional/regressions/test_bug_1983753.py')
-rw-r--r-- | nova/tests/functional/regressions/test_bug_1983753.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/nova/tests/functional/regressions/test_bug_1983753.py b/nova/tests/functional/regressions/test_bug_1983753.py new file mode 100644 index 0000000000..3658d6aeb8 --- /dev/null +++ b/nova/tests/functional/regressions/test_bug_1983753.py @@ -0,0 +1,177 @@ +# 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.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_DEVICE_SPEC = [] + 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): + 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): + self._test_resize_from_two_devs_to_one_dev(num_pci_on_dest=1) + + 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) + self._resize_server(server, flavor_id=flavor_id) + self._confirm_resize(server) + self.assertPCIDeviceCounts("compute1", total=1, free=1) + self.assertPCIDeviceCounts("compute2", total=1, free=0) |