def test_wait_for_volume_attachment_create(self): vol_detached = {'volume': {'attachments': []}} vol_attached = { 'volume': { 'attachments': [{ 'id': uuids.volume_id, 'attachment_id': uuids.attachment_id, 'server_id': uuids.server_id, 'volume_id': uuids.volume_id }] } } show_volume = mock.MagicMock( side_effect=[vol_detached, vol_detached, vol_attached]) client = mock.Mock(spec=volumes_client.VolumesClient, build_interval=1, build_timeout=5, show_volume=show_volume) self.patch('time.time') self.patch('time.sleep') att = waiters.wait_for_volume_attachment_create( client, uuids.volume_id, uuids.server_id) assert att == vol_attached['volume']['attachments'][0] # Assert that show volume is called until the attachment is removed. show_volume.assert_has_calls([ mock.call(uuids.volume_id), mock.call(uuids.volume_id), mock.call(uuids.volume_id) ])
def attach_volume(self, server, volume, device=None, tag=None): """Attaches volume to server and waits for 'in-use' volume status. The volume will be detached when the test tears down. :param server: The server to which the volume will be attached. :param volume: The volume to attach. :param device: Optional mountpoint for the attached volume. Note that this is not guaranteed for all hypervisors and is not recommended. :param tag: Optional device role tag to apply to the volume. """ attach_kwargs = dict(volumeId=volume['id']) if device: attach_kwargs['device'] = device if tag: attach_kwargs['tag'] = tag attachment = self.servers_client.attach_volume( server['id'], **attach_kwargs)['volumeAttachment'] # NOTE(lyarwood): During attach we initially wait for the volume # attachment and then check the volume state. waiters.wait_for_volume_attachment_create( self.volumes_client, volume['id'], server['id']) # TODO(lyarwood): Remove the following volume status checks and move to # attachment status checks across all volumes now with the 3.27 # microversion somehow. if not volume['multiattach']: waiters.wait_for_volume_resource_status( self.volumes_client, volume['id'], 'in-use') # NOTE(lyarwood): On teardown (LIFO) initially wait for the volume # attachment in Nova to be removed. While this technically happens last # we want this to be the first waiter as if it fails we can then dump # the contents of the console log. The final check of the volume state # should be a no-op by this point and is just added for completeness # when detaching non-multiattach volumes. if not volume['multiattach']: self.addCleanup( waiters.wait_for_volume_resource_status, self.volumes_client, volume['id'], 'available') self.addCleanup( waiters.wait_for_volume_attachment_remove_from_server, self.servers_client, server['id'], volume['id']) self.addCleanup(self._detach_volume, server, volume) return attachment
def attach_volume(self, server, volume, device=None, tag=None): """Attaches volume to server and waits for 'in-use' volume status. The volume will be detached when the test tears down. :param server: The server to which the volume will be attached. :param volume: The volume to attach. :param device: Optional mountpoint for the attached volume. Note that this is not guaranteed for all hypervisors and is not recommended. :param tag: Optional device role tag to apply to the volume. """ attach_kwargs = dict(volumeId=volume['id']) if device: attach_kwargs['device'] = device if tag: attach_kwargs['tag'] = tag attachment = self.servers_client.attach_volume( server['id'], **attach_kwargs)['volumeAttachment'] # On teardown detach the volume and for multiattach volumes wait for # the attachment to be removed. For non-multiattach volumes wait for # the state of the volume to change to available. This is so we don't # error out when trying to delete the volume during teardown. if volume['multiattach']: att = waiters.wait_for_volume_attachment_create( self.volumes_client, volume['id'], server['id']) self.addCleanup(waiters.wait_for_volume_attachment_remove, self.volumes_client, volume['id'], att['attachment_id']) else: self.addCleanup(waiters.wait_for_volume_resource_status, self.volumes_client, volume['id'], 'available') waiters.wait_for_volume_resource_status(self.volumes_client, volume['id'], 'in-use') # Ignore 404s on detach in case the server is deleted or the volume # is already detached. self.addCleanup(self._detach_volume, server, volume) return attachment