Merge "waiters: Add wait_for_volume_attachment_remove"

This commit is contained in:
Zuul 2020-02-11 09:55:21 +00:00 committed by Gerrit Code Review
commit fbde5a3948
2 changed files with 65 additions and 0 deletions

View File

@ -217,6 +217,22 @@ def wait_for_volume_resource_status(client, resource_id, status):
resource_name, resource_id, status, time.time() - start)
def wait_for_volume_attachment_remove(client, volume_id, attachment_id):
"""Waits for a volume attachment to be removed from a given volume."""
start = int(time.time())
attachments = client.show_volume(volume_id)['volume']['attachments']
while any(attachment_id == a['attachment_id'] for a in attachments):
time.sleep(client.build_interval)
if int(time.time()) - start >= client.build_timeout:
message = ('Failed to remove attachment %s from volume %s'
'within the required time (%s s).' %
(attachment_id, volume_id, client.build_timeout))
raise lib_exc.TimeoutException(message)
attachments = client.show_volume(volume_id)['volume']['attachments']
LOG.info('Attachment %s removed from volume %s after waiting for %f '
'seconds', attachment_id, volume_id, time.time() - start)
def wait_for_volume_migration(client, volume_id, new_host):
"""Waits for a Volume to move to a new host."""
body = client.show_volume(volume_id)['volume']

View File

@ -15,6 +15,7 @@
import time
import mock
from oslo_utils.fixture import uuidsentinel as uuids
from tempest.common import waiters
from tempest import exceptions
@ -232,3 +233,51 @@ class TestVolumeWaiters(base.TestCase):
mock_show.assert_has_calls([mock.call(volume_id),
mock.call(volume_id)])
mock_sleep.assert_called_once_with(1)
def test_wait_for_volume_attachment(self):
vol_detached = {'volume': {'attachments': []}}
vol_attached = {'volume': {'attachments': [
{'attachment_id': uuids.attachment_id}]}}
show_volume = mock.MagicMock(side_effect=[
vol_attached, vol_attached, vol_detached])
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')
waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
uuids.attachment_id)
# 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 test_wait_for_volume_attachment_timeout(self):
show_volume = mock.MagicMock(return_value={
'volume': {'attachments': [
{'attachment_id': uuids.attachment_id}]}})
client = mock.Mock(spec=volumes_client.VolumesClient,
build_interval=1,
build_timeout=1,
show_volume=show_volume)
self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
self.patch('time.sleep')
# Assert that a timeout is raised if the attachment remains.
self.assertRaises(lib_exc.TimeoutException,
waiters.wait_for_volume_attachment_remove,
client, uuids.volume_id, uuids.attachment_id)
def test_wait_for_volume_attachment_not_present(self):
show_volume = mock.MagicMock(return_value={
'volume': {'attachments': []}})
client = mock.Mock(spec=volumes_client.VolumesClient,
build_interval=1,
build_timeout=1,
show_volume=show_volume)
self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
self.patch('time.sleep')
waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
uuids.attachment_id)
# Assert that show volume is only called once before we return
show_volume.assert_called_once_with(uuids.volume_id)