|
| 1 | +# Copyright 2021, Canonical, Inc. All Rights Reserved. |
| 2 | +# |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | +# not use this file except in compliance with the License. You may obtain |
| 5 | +# a copy of the License at |
| 6 | +# |
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +# |
| 9 | +# Unless required by applicable law or agreed to in writing, software |
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 11 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 12 | +# License for the specific language governing permissions and limitations |
| 13 | +# under the License. |
| 14 | + |
| 15 | +import mock |
| 16 | + |
| 17 | +from nova import exception as nova_exceptions |
| 18 | +from nova.tests.fixtures import libvirt as fakelibvirt |
| 19 | +from nova.tests.functional import integrated_helpers |
| 20 | +from nova.tests.functional.libvirt import base |
| 21 | + |
| 22 | + |
| 23 | +class TestRollbackWithHWOffloadedOVS( |
| 24 | + base.LibvirtMigrationMixin, |
| 25 | + base.ServersTestBase, |
| 26 | + integrated_helpers.InstanceHelperMixin |
| 27 | +): |
| 28 | + """Regression test for bug LP#1944619 |
| 29 | +
|
| 30 | + Assert the behaviour observed in bug LP#1944619 caused by the live |
| 31 | + migration cleanup code being used to cleanup pre-live migration failures. |
| 32 | + When SRIOV devices are in use on a VM, that will cause the source host to |
| 33 | + try to re-attach a VIF not actually de-attached causing a failure. |
| 34 | +
|
| 35 | + The exception mocked in pre_live_migration reproduce an arbitrary error |
| 36 | + that might cause the pre-live migration process to fail and |
| 37 | + rollback_live_migration_at_source reproduce the device re-attach failure. |
| 38 | + """ |
| 39 | + |
| 40 | + api_major_version = 'v2.1' |
| 41 | + microversion = 'latest' |
| 42 | + ADMIN_API = True |
| 43 | + |
| 44 | + def setUp(self): |
| 45 | + super().setUp() |
| 46 | + |
| 47 | + self.start_compute( |
| 48 | + hostname='src', |
| 49 | + host_info=fakelibvirt.HostInfo( |
| 50 | + cpu_nodes=1, cpu_sockets=1, cpu_cores=4, cpu_threads=1)) |
| 51 | + self.start_compute( |
| 52 | + hostname='dest', |
| 53 | + host_info=fakelibvirt.HostInfo( |
| 54 | + cpu_nodes=1, cpu_sockets=1, cpu_cores=4, cpu_threads=1)) |
| 55 | + |
| 56 | + self.src = self.computes['src'] |
| 57 | + self.dest = self.computes['dest'] |
| 58 | + |
| 59 | + def test_rollback_pre_live_migration(self): |
| 60 | + self.server = self._create_server(host='src', networks='none') |
| 61 | + |
| 62 | + lib_path = "nova.virt.libvirt.driver.LibvirtDriver" |
| 63 | + funtion_path = "pre_live_migration" |
| 64 | + mock_lib_path_prelive = "%s.%s" % (lib_path, funtion_path) |
| 65 | + with mock.patch(mock_lib_path_prelive, |
| 66 | + side_effect=nova_exceptions.DestinationDiskExists( |
| 67 | + path='/var/non/existent')) as mlpp: |
| 68 | + funtion_path = "rollback_live_migration_at_source" |
| 69 | + mock_lib_path_rollback = "%s.%s" % (lib_path, funtion_path) |
| 70 | + with mock.patch(mock_lib_path_rollback) as mlpr: |
| 71 | + # Live migrate the instance to another host |
| 72 | + self._live_migrate(self.server, |
| 73 | + migration_expected_state='failed', |
| 74 | + server_expected_state='MIGRATING') |
| 75 | + # FIXME(erlon): In the current behavior, |
| 76 | + # rollback_live_migration_at_source is called if an error happens |
| 77 | + # during the pre_live_migration phase on the destination and therefore |
| 78 | + # triggers the observed bug. rollback_live_migration_at_source should |
| 79 | + # *not* be called for when errors happen during pre_live_migration |
| 80 | + # phase. |
| 81 | + mlpr.assert_called_once() |
| 82 | + mlpp.assert_called_once() |
0 commit comments