Skip to content

Commit 7074ac0

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "fup: Assert state of connection_info during LM rollback in func tests" into stable/wallaby
2 parents d3bdf75 + c248986 commit 7074ac0

File tree

1 file changed

+72
-10
lines changed

1 file changed

+72
-10
lines changed

nova/tests/functional/compute/test_live_migration.py

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
# under the License.
1414

1515
import mock
16+
from oslo_serialization import jsonutils
1617
from oslo_utils.fixture import uuidsentinel as uuids
1718

19+
from nova import context
1820
from nova import exception
21+
from nova import objects
1922
from nova import test
2023
from nova.tests import fixtures as nova_fixtures
2124
from nova.tests.functional import integrated_helpers
@@ -116,12 +119,16 @@ def test_vol_attachments_during_driver_live_mig_failure(self, mock_lm):
116119
117120
* Mock live_migration to always rollback and raise a failure within the
118121
fake virt driver
119-
* Launch a boot from volume instance
122+
* Launch a boot from volume instance on src
120123
* Assert that the volume is attached correctly to the instance
124+
* Assert that the expected source attachment is recorded in the bdm
125+
* Wrap pre_live_migration on the dest and assert that we switch over
126+
to the new attachment and connection_info on the dest.
121127
* Live migrate the instance to another host invoking the mocked
122128
live_migration method
123129
* Assert that the instance is still on the source host
124130
* Assert that the original source host volume attachment remains
131+
* Assert that the original src connection_info is in the bdm
125132
"""
126133
# Mock out driver.live_migration so that we always rollback
127134
def _fake_live_migration_with_rollback(
@@ -135,21 +142,23 @@ def _fake_live_migration_with_rollback(
135142

136143
volume_id = nova_fixtures.CinderFixture.IMAGE_BACKED_VOL
137144
server = self._build_server(
138-
name='test_bfv_live_migration_failure', image_uuid='',
139-
networks='none'
145+
name='test_bfv_live_migration_failure',
146+
image_uuid='',
147+
networks='none',
148+
host='src'
140149
)
141150
server['block_device_mapping_v2'] = [{
142151
'source_type': 'volume',
143152
'destination_type': 'volume',
144153
'boot_index': 0,
145-
'uuid': volume_id
154+
'uuid': volume_id,
146155
}]
147156
server = self.api.post_server({'server': server})
148157
self._wait_for_state_change(server, 'ACTIVE')
149158

150-
# Fetch the source host for use later
159+
# Assert that the instance has landed correctly on src
151160
server = self.api.get_server(server['id'])
152-
src_host = server['OS-EXT-SRV-ATTR:host']
161+
self.assertEqual('src', server['OS-EXT-SRV-ATTR:host'])
153162

154163
# Assert that the volume is connected to the instance
155164
self.assertIn(
@@ -162,22 +171,75 @@ def _fake_live_migration_with_rollback(
162171
# Fetch the attachment_id for use later once we have migrated
163172
src_attachment_id = list(attachments.keys())[0]
164173

165-
# Migrate the instance and wait until the migration errors out thanks
166-
# to our mocked version of live_migration raising TestingException
167-
self._live_migrate(server, 'error', server_expected_state='ERROR')
174+
# Assert that this attachment_id is stashed in the connection_info
175+
# of the bdm so we can assert things again after the failure
176+
ctxt = context.get_admin_context()
177+
bdm = objects.BlockDeviceMapping.get_by_volume_and_instance(
178+
ctxt, volume_id, server['id'])
179+
self.assertEqual(src_attachment_id, bdm.attachment_id)
180+
connection_info = jsonutils.loads(bdm.connection_info)
181+
self.assertIn('attachment_id', connection_info['data'])
182+
self.assertEqual(
183+
src_attachment_id, connection_info['data']['attachment_id'])
184+
185+
dest_pre_live_mig = self.computes['dest'].manager.pre_live_migration
186+
187+
# Wrap pre_live_migration on the destination so we can assert that
188+
# we do switch over to the new attachment before the failure
189+
# and then later rollback to the source attachment
190+
def wrap_pre_live_migration(*args, **kwargs):
191+
192+
# Continue with pre_live_migration before we assert anything
193+
migrate_data = dest_pre_live_mig(*args, **kwargs)
194+
195+
# Assert that we now have two attachments in the fixture, one for
196+
# the src and another for the dest.
197+
attachments = self.cinder.volume_to_attachment.get(volume_id)
198+
self.assertEqual(2, len(attachments))
199+
200+
# Assert that the dest attachment id is saved in the bdm
201+
# and the connection_info.
202+
bdm = objects.BlockDeviceMapping.get_by_volume_and_instance(
203+
ctxt, volume_id, server['id'])
204+
self.assertNotEqual(src_attachment_id, bdm.attachment_id)
205+
dest_attachment_id = bdm.attachment_id
206+
connection_info = jsonutils.loads(bdm.connection_info)
207+
self.assertIn('attachment_id', connection_info['data'])
208+
self.assertEqual(
209+
dest_attachment_id, connection_info['data']['attachment_id'])
210+
return migrate_data
211+
212+
with mock.patch.object(
213+
self.computes['dest'].manager,
214+
'pre_live_migration',
215+
wrap_pre_live_migration
216+
):
217+
# Migrate the instance and wait until the migration errors out
218+
# thanks to our mocked version of live_migration raising
219+
# TestingException
220+
self._live_migrate(server, 'error', server_expected_state='ERROR')
168221

169222
# Assert that we called the fake live_migration method
170223
mock_lm.assert_called_once()
171224

172225
# Assert that the instance is on the source
173226
server = self.api.get_server(server['id'])
174-
self.assertEqual(src_host, server['OS-EXT-SRV-ATTR:host'])
227+
self.assertEqual('src', server['OS-EXT-SRV-ATTR:host'])
175228

176229
# Assert that the src attachment is still present
177230
attachments = self.cinder.volume_to_attachment.get(volume_id)
178231
self.assertIn(src_attachment_id, attachments.keys())
179232
self.assertEqual(1, len(attachments))
180233

234+
# Assert that the connection_info has reverted back to the src
235+
bdm = objects.BlockDeviceMapping.get_by_volume_and_instance(
236+
ctxt, volume_id, server['id'])
237+
self.assertEqual(src_attachment_id, bdm.attachment_id)
238+
connection_info = jsonutils.loads(bdm.connection_info)
239+
self.assertIn('attachment_id', connection_info['data'])
240+
self.assertEqual(
241+
src_attachment_id, connection_info['data']['attachment_id'])
242+
181243

182244
class LiveMigrationNeutronInteractionsTest(
183245
integrated_helpers._IntegratedTestBase):

0 commit comments

Comments
 (0)