Add functional tests to ensure BDM removal on delete

In certain cases, such as when an instance fails to be scheduled,
the volume may already have an attachment created (or the volume
has been reserved in the old flows).

This patch adds a test to check that these volume attachments
are deleted and removed once the instance has been deleted. It
also adds some functionality to allow checking when an volume
has been reserved in the Cinder fixtures.

Change-Id: I85cc3998fbcde30eefa5429913ca287246d51255
Related-Bug: #1404867
This commit is contained in:
Mohammed Naser 2018-02-14 16:26:38 -05:00
parent c43d44a6b6
commit 9f55c25d8d

View File

@ -1318,6 +1318,7 @@ class CinderFixture(fixtures.Fixture):
self.swap_error = False
self.swap_volume_instance_uuid = None
self.swap_volume_instance_error_uuid = None
self.reserved_volumes = list()
# This is a map of instance UUIDs mapped to a list of volume IDs.
# This map gets updated on attach/detach operations.
self.attachments = collections.defaultdict(list)
@ -1378,8 +1379,9 @@ class CinderFixture(fixtures.Fixture):
break
else:
# This is a test that does not care about the actual details.
reserved_volume = (volume_id in self.reserved_volumes)
volume = {
'status': 'available',
'status': 'attaching' if reserved_volume else 'available',
'display_name': 'TEST2',
'attach_status': 'detached',
'id': volume_id,
@ -1409,7 +1411,16 @@ class CinderFixture(fixtures.Fixture):
new_volume_id, error):
return {'save_volume_id': new_volume_id}
def fake_reserve_volume(self_api, context, volume_id):
self.reserved_volumes.append(volume_id)
def fake_unreserve_volume(self_api, context, volume_id):
# NOTE(mnaser): It's possible that we unreserve a volume that was
# never reserved (ex: instance.volume_attach.error
# notification tests)
if volume_id in self.reserved_volumes:
self.reserved_volumes.remove(volume_id)
# Signaling that swap_volume has encountered the error
# from initialize_connection and is working on rolling back
# the reservation on SWAP_ERR_NEW_VOL.
@ -1431,6 +1442,12 @@ class CinderFixture(fixtures.Fixture):
def fake_detach(_self, context, volume_id, instance_uuid=None,
attachment_id=None):
# NOTE(mnaser): It's possible that we unreserve a volume that was
# never reserved (ex: instance.volume_attach.error
# notification tests)
if volume_id in self.reserved_volumes:
self.reserved_volumes.remove(volume_id)
if instance_uuid is not None:
# If the volume isn't attached to this instance it will
# result in a ValueError which indicates a broken test or
@ -1454,7 +1471,7 @@ class CinderFixture(fixtures.Fixture):
'nova.volume.cinder.API.migrate_volume_completion',
fake_migrate_volume_completion)
self.test.stub_out('nova.volume.cinder.API.reserve_volume',
lambda *args, **kwargs: None)
fake_reserve_volume)
self.test.stub_out('nova.volume.cinder.API.roll_detaching',
lambda *args, **kwargs: None)
self.test.stub_out('nova.volume.cinder.API.terminate_connection',