Add regression tests for bug #1889108

NOTE(lyarwood): nova.virt.fake.set_nodes() is required on stable/queens
to avoid duplicate hostnames.

Related-Bug: #1889108
Change-Id: Ib9dbc792dc918e7ea45915e2c1dbd96be82ef562
(cherry picked from commit 4c970f499c)
(cherry picked from commit 6db72002a6)
(cherry picked from commit 6a9bb79fc0)
(cherry picked from commit 06d9d0d705)
(cherry picked from commit 7b2662c85c)
This commit is contained in:
Lee Yarwood 2020-07-27 18:18:28 +01:00
parent db7713475e
commit 5a8d5e93c5
1 changed files with 122 additions and 0 deletions

View File

@ -0,0 +1,122 @@
# 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 mock
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers
from nova.tests.unit import fake_notifier
from nova.virt import fake
class TestVolAttachmentsDuringPreLiveMigration(
integrated_helpers._IntegratedTestBase,
integrated_helpers.InstanceHelperMixin
):
"""Regression test for bug 1889108.
This regression test asserts that the original source volume attachments
are incorrectly removed during the rollback from pre_live_migration
failures on the destination.
"""
api_major_version = 'v2.1'
microversion = 'latest'
ADMIN_API = True
USE_NEUTRON = True
def setUp(self):
super(TestVolAttachmentsDuringPreLiveMigration, self).setUp()
self.cinder = self.useFixture(
nova_fixtures.CinderFixtureNewAttachFlow(self))
fake_notifier.stub_notifier(self)
self.addCleanup(fake_notifier.reset)
def _setup_compute_service(self):
# Start a second compte node (the first one was started for us by
# _IntegratedTestBase. set_nodes() is needed to avoid duplicate
# nodenames. See comments in test_bug_1702454.py.
fake.set_nodes(['src'])
self.addCleanup(fake.restore_nodes)
self.start_service('compute', host='src')
fake.set_nodes(['dest'])
self.addCleanup(fake.restore_nodes)
self.start_service('compute', host='dest')
@mock.patch('nova.virt.fake.FakeDriver.pre_live_migration',
side_effect=test.TestingException)
def test_vol_attachments_during_driver_pre_live_mig_failure(
self, mock_plm):
"""Assert that the src attachment is incorrectly removed
* Mock pre_live_migration to always fail within the virt driver
* Launch a boot from volume instance
* Assert that the volume is attached correctly to the instance.
* Live migrate the instance to another host invoking the mocked
pre_live_migration
* Assert that the instance is still on the source host
* Assert that both the original source host volume attachment and
new destination volume attachment have been removed
"""
volume_id = nova_fixtures.CinderFixture.IMAGE_BACKED_VOL
server = {
'name': 'test_bfv_pre_live_migration_failure',
'flavorRef': 1,
'imageRef': '',
'networks': 'none',
'block_device_mapping_v2': [{
'source_type': 'volume',
'destination_type': 'volume',
'boot_index': 0,
'uuid': volume_id}],
}
server = self.api.post_server({'server': server})
self._wait_for_state_change(self.api, server, 'ACTIVE')
# Fetch the source host for use later
server = self.api.get_server(server['id'])
src_host = server['OS-EXT-SRV-ATTR:host']
# Assert that the volume is connected to the instance
self.assertIn(
volume_id, self.cinder.volume_ids_for_instance(server['id']))
# Assert that we have an active attachment in the fixture
attachments = self.cinder.volume_to_attachment.get(volume_id)
self.assertEqual(1, len(attachments))
# Fetch the attachment_id for use later once we have migrated
src_attachment_id = list(attachments.keys())[0]
# Migrate the instance and wait until the migration errors out thanks
# to our mocked version of pre_live_migration raising
# test.TestingException
self.api.post_server_action(
server['id'],
{'os-migrateLive': {'host': None, 'block_migration': 'auto'}})
self._wait_for_state_change(self.api, server, 'ACTIVE')
self._wait_for_migration_status(server, ['error'])
# Assert that we called the fake pre_live_migration method
mock_plm.assert_called_once()
# Assert that the instance is listed on the source
server = self.api.get_server(server['id'])
self.assertEqual(src_host, server['OS-EXT-SRV-ATTR:host'])
# FIXME(lyarwood): Assert that both the src and dest attachments have
# been removed. Only the dest attachment should be removed during the
# rollback of a pre_live_migration failure.
attachments = self.cinder.volume_to_attachment.get(volume_id)
self.assertNotIn(src_attachment_id, attachments.keys())
self.assertEqual(0, len(attachments))