blob: 3092bf46611d56e28b04c76e25a11277c691e98f [file] [log] [blame]
Matthew Treinish7b015822014-01-21 18:15:39 +00001# Copyright 2014 IBM Corp.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import time
Sean McGinniseed80742020-04-18 12:01:03 -050016from unittest import mock
Matthew Treinish7b015822014-01-21 18:15:39 +000017
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +000018from oslo_utils.fixture import uuidsentinel as uuids
Matthew Treinish7b015822014-01-21 18:15:39 +000019
20from tempest.common import waiters
21from tempest import exceptions
guo yunxianebb15f22016-11-01 21:03:35 +080022from tempest.lib import exceptions as lib_exc
Balazs Gibizer2e515fe2020-12-07 15:10:11 +010023from tempest.lib.services.compute import servers_client
lkuchlanf53947e2016-09-15 10:37:57 +030024from tempest.lib.services.volume.v2 import volumes_client
Matthew Treinishffad78a2016-04-16 14:39:52 -040025from tempest.tests import base
Jordan Pittier0e53b612016-03-03 14:23:17 +010026import tempest.tests.utils as utils
Matthew Treinish7b015822014-01-21 18:15:39 +000027
28
29class TestImageWaiters(base.TestCase):
30 def setUp(self):
31 super(TestImageWaiters, self).setUp()
32 self.client = mock.MagicMock()
33 self.client.build_timeout = 1
34 self.client.build_interval = 1
35
36 def test_wait_for_image_status(self):
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +000037 self.client.show_image.return_value = ({'status': 'active'})
Matthew Treinish7b015822014-01-21 18:15:39 +000038 start_time = int(time.time())
39 waiters.wait_for_image_status(self.client, 'fake_image_id', 'active')
40 end_time = int(time.time())
41 # Ensure waiter returns before build_timeout
Béla Vancsics64862f72016-11-08 09:12:31 +010042 self.assertLess((end_time - start_time), 10)
Matthew Treinish7b015822014-01-21 18:15:39 +000043
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +030044 def test_wait_for_image_status_timeout(self):
Jordan Pittier0e53b612016-03-03 14:23:17 +010045 time_mock = self.patch('time.time')
46 time_mock.side_effect = utils.generate_timeout_series(1)
47
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +000048 self.client.show_image.return_value = ({'status': 'saving'})
guo yunxianebb15f22016-11-01 21:03:35 +080049 self.assertRaises(lib_exc.TimeoutException,
Matthew Treinish7b015822014-01-21 18:15:39 +000050 waiters.wait_for_image_status,
51 self.client, 'fake_image_id', 'active')
52
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +030053 def test_wait_for_image_status_error_on_image_create(self):
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +000054 self.client.show_image.return_value = ({'status': 'ERROR'})
Matthew Treinish7b015822014-01-21 18:15:39 +000055 self.assertRaises(exceptions.AddImageException,
56 waiters.wait_for_image_status,
57 self.client, 'fake_image_id', 'active')
Matt Riedemannf77e7dc2015-08-10 16:39:39 -070058
zhufl414ffba2020-11-19 16:57:06 +080059 def test_wait_for_image_imported_to_stores(self):
60 self.client.show_image.return_value = ({'status': 'active',
61 'stores': 'fake_store'})
62 start_time = int(time.time())
63 waiters.wait_for_image_imported_to_stores(
64 self.client, 'fake_image_id', 'fake_store')
65 end_time = int(time.time())
66 # Ensure waiter returns before build_timeout
67 self.assertLess((end_time - start_time), 10)
68
Dan Smithef8e0542021-02-05 13:05:45 -080069 def test_wait_for_image_imported_to_stores_failure(self):
zhufl414ffba2020-11-19 16:57:06 +080070 time_mock = self.patch('time.time')
71 client = mock.MagicMock()
72 client.build_timeout = 2
73 self.patch('time.time', side_effect=[0., 1., 2.])
74 time_mock.side_effect = utils.generate_timeout_series(1)
75
76 client.show_image.return_value = ({
77 'status': 'saving',
78 'stores': 'fake_store',
79 'os_glance_failed_import': 'fake_os_glance_failed_import'})
Dan Smithef8e0542021-02-05 13:05:45 -080080 self.assertRaises(lib_exc.OtherRestClientException,
81 waiters.wait_for_image_imported_to_stores,
82 client, 'fake_image_id', 'fake_store')
83
84 def test_wait_for_image_imported_to_stores_timeout(self):
85 time_mock = self.patch('time.time')
86 client = mock.MagicMock()
87 client.build_timeout = 2
88 self.patch('time.time', side_effect=[0., 1., 2.])
89 time_mock.side_effect = utils.generate_timeout_series(1)
90
91 client.show_image.return_value = ({
92 'status': 'saving',
93 'stores': 'fake_store'})
zhufl414ffba2020-11-19 16:57:06 +080094 self.assertRaises(lib_exc.TimeoutException,
95 waiters.wait_for_image_imported_to_stores,
96 client, 'fake_image_id', 'fake_store')
97
98 def test_wait_for_image_copied_to_stores(self):
99 self.client.show_image.return_value = ({
100 'status': 'active',
101 'os_glance_importing_to_stores': '',
102 'os_glance_failed_import': 'fake_os_glance_failed_import'})
103 start_time = int(time.time())
104 waiters.wait_for_image_copied_to_stores(
105 self.client, 'fake_image_id')
106 end_time = int(time.time())
107 # Ensure waiter returns before build_timeout
108 self.assertLess((end_time - start_time), 10)
109
110 def test_wait_for_image_copied_to_stores_timeout(self):
111 time_mock = self.patch('time.time')
112 self.patch('time.time', side_effect=[0., 1.])
113 time_mock.side_effect = utils.generate_timeout_series(1)
114
115 self.client.show_image.return_value = ({
116 'status': 'active',
117 'os_glance_importing_to_stores': 'processing',
118 'os_glance_failed_import': 'fake_os_glance_failed_import'})
119 self.assertRaises(lib_exc.TimeoutException,
120 waiters.wait_for_image_copied_to_stores,
121 self.client, 'fake_image_id')
122
Ghanshyam Mannb15b58e2021-04-29 19:45:29 -0500123 def test_wait_for_image_tasks_status(self):
124 self.client.show_image_tasks.return_value = ({
125 'tasks': [{'status': 'success'}]})
126 start_time = int(time.time())
127 waiters.wait_for_image_tasks_status(
128 self.client, 'fake_image_id', 'success')
129 end_time = int(time.time())
130 # Ensure waiter returns before build_timeout
131 self.assertLess((end_time - start_time), 10)
132
133 def test_wait_for_image_tasks_status_timeout(self):
134 time_mock = self.patch('time.time')
135 self.patch('time.time', side_effect=[0., 1.])
136 time_mock.side_effect = utils.generate_timeout_series(1)
137
138 self.client.show_image_tasks.return_value = ({
139 'tasks': [
140 {'status': 'success'},
141 {'status': 'processing'}]})
142 self.assertRaises(lib_exc.TimeoutException,
143 waiters.wait_for_image_tasks_status,
144 self.client, 'fake_image_id', 'success')
145
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400146
147class TestInterfaceWaiters(base.TestCase):
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400148
Federico Ressi8827d382018-06-12 23:27:00 +0200149 build_timeout = 1.
150 build_interval = 1
151 port_down = {'interfaceAttachment': {'port_state': 'DOWN'}}
152 port_active = {'interfaceAttachment': {'port_state': 'ACTIVE'}}
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400153
Federico Ressi8827d382018-06-12 23:27:00 +0200154 def mock_client(self, **kwargs):
155 return mock.MagicMock(
156 build_timeout=self.build_timeout,
157 build_interval=self.build_interval,
158 **kwargs)
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400159
160 def test_wait_for_interface_status(self):
Federico Ressi8827d382018-06-12 23:27:00 +0200161 show_interface = mock.Mock(
162 side_effect=[self.port_down, self.port_active])
163 client = self.mock_client(show_interface=show_interface)
164 self.patch('time.time', return_value=0.)
165 sleep = self.patch('time.sleep')
166
167 result = waiters.wait_for_interface_status(
168 client, 'server_id', 'port_id', 'ACTIVE')
169
170 self.assertIs(self.port_active['interfaceAttachment'], result)
171 show_interface.assert_has_calls([mock.call('server_id', 'port_id'),
172 mock.call('server_id', 'port_id')])
173 sleep.assert_called_once_with(client.build_interval)
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400174
175 def test_wait_for_interface_status_timeout(self):
Federico Ressi8827d382018-06-12 23:27:00 +0200176 show_interface = mock.MagicMock(return_value=self.port_down)
177 client = self.mock_client(show_interface=show_interface)
178 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
179 sleep = self.patch('time.sleep')
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400180
Artom Lifshitzdf0d6d72018-05-11 11:31:11 -0400181 self.assertRaises(lib_exc.TimeoutException,
182 waiters.wait_for_interface_status,
Federico Ressi8827d382018-06-12 23:27:00 +0200183 client, 'server_id', 'port_id', 'ACTIVE')
Artom Lifshitz3306d422018-03-22 12:20:54 -0400184
Federico Ressi8827d382018-06-12 23:27:00 +0200185 show_interface.assert_has_calls([mock.call('server_id', 'port_id'),
186 mock.call('server_id', 'port_id')])
187 sleep.assert_called_once_with(client.build_interval)
Artom Lifshitz3306d422018-03-22 12:20:54 -0400188
Federico Ressi8827d382018-06-12 23:27:00 +0200189 one_interface = {'interfaceAttachments': [{'port_id': 'port_one'}]}
190 two_interfaces = {'interfaceAttachments': [{'port_id': 'port_one'},
191 {'port_id': 'port_two'}]}
Artom Lifshitz3306d422018-03-22 12:20:54 -0400192
193 def test_wait_for_interface_detach(self):
Federico Ressi8827d382018-06-12 23:27:00 +0200194 list_interfaces = mock.MagicMock(
195 side_effect=[self.two_interfaces, self.one_interface])
196 client = self.mock_client(list_interfaces=list_interfaces)
197 self.patch('time.time', return_value=0.)
198 sleep = self.patch('time.sleep')
199
200 result = waiters.wait_for_interface_detach(
201 client, 'server_id', 'port_two')
202
203 self.assertIs(self.one_interface['interfaceAttachments'], result)
204 list_interfaces.assert_has_calls([mock.call('server_id'),
205 mock.call('server_id')])
206 sleep.assert_called_once_with(client.build_interval)
Artom Lifshitz3306d422018-03-22 12:20:54 -0400207
208 def test_wait_for_interface_detach_timeout(self):
Federico Ressi8827d382018-06-12 23:27:00 +0200209 list_interfaces = mock.MagicMock(return_value=self.one_interface)
210 client = self.mock_client(list_interfaces=list_interfaces)
211 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
212 sleep = self.patch('time.sleep')
Artom Lifshitz3306d422018-03-22 12:20:54 -0400213
Artom Lifshitz3306d422018-03-22 12:20:54 -0400214 self.assertRaises(lib_exc.TimeoutException,
215 waiters.wait_for_interface_detach,
Federico Ressi8827d382018-06-12 23:27:00 +0200216 client, 'server_id', 'port_one')
217
218 list_interfaces.assert_has_calls([mock.call('server_id'),
219 mock.call('server_id')])
220 sleep.assert_called_once_with(client.build_interval)
Lee Yarwoode5597402019-02-15 20:17:00 +0000221
Slawek Kaplonskie3405ba2020-11-09 17:24:13 +0100222 def test_wait_for_guest_os_boot(self):
223 get_console_output = mock.Mock(
224 side_effect=[
225 {'output': 'os not ready yet\n'},
226 {'output': 'login:\n'}
227 ])
228 client = self.mock_client(get_console_output=get_console_output)
229 self.patch('time.time', return_value=0.)
230 sleep = self.patch('time.sleep')
231
232 with mock.patch.object(waiters.LOG, "info") as log_info:
233 waiters.wait_for_guest_os_boot(client, 'server_id')
234
235 get_console_output.assert_has_calls([
236 mock.call('server_id'), mock.call('server_id')])
237 sleep.assert_called_once_with(client.build_interval)
238 log_info.assert_not_called()
239
240 def test_wait_for_guest_os_boot_timeout(self):
241 get_console_output = mock.Mock(
242 return_value={'output': 'os not ready yet\n'})
243 client = self.mock_client(get_console_output=get_console_output)
244 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
245 self.patch('time.sleep')
246
247 with mock.patch.object(waiters.LOG, "info") as log_info:
248 waiters.wait_for_guest_os_boot(client, 'server_id')
249
250 log_info.assert_called_once()
251
Lee Yarwoode5597402019-02-15 20:17:00 +0000252
253class TestVolumeWaiters(base.TestCase):
254 vol_migrating_src_host = {
255 'volume': {'migration_status': 'migrating',
256 'os-vol-host-attr:host': 'src_host@backend#type'}}
257 vol_migrating_dst_host = {
258 'volume': {'migration_status': 'migrating',
259 'os-vol-host-attr:host': 'dst_host@backend#type'}}
260 vol_migration_success = {
261 'volume': {'migration_status': 'success',
262 'os-vol-host-attr:host': 'dst_host@backend#type'}}
263 vol_migration_error = {
264 'volume': {'migration_status': 'error',
265 'os-vol-host-attr:host': 'src_host@backend#type'}}
266
267 def test_wait_for_volume_migration_timeout(self):
268 show_volume = mock.MagicMock(return_value=self.vol_migrating_src_host)
269 client = mock.Mock(spec=volumes_client.VolumesClient,
270 resource_type="volume",
271 build_interval=1,
272 build_timeout=1,
273 show_volume=show_volume)
274 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
275 self.patch('time.sleep')
276 self.assertRaises(lib_exc.TimeoutException,
277 waiters.wait_for_volume_migration,
278 client, mock.sentinel.volume_id, 'dst_host')
279
280 def test_wait_for_volume_migration_error(self):
281 show_volume = mock.MagicMock(side_effect=[
282 self.vol_migrating_src_host,
283 self.vol_migrating_src_host,
284 self.vol_migration_error])
285 client = mock.Mock(spec=volumes_client.VolumesClient,
286 resource_type="volume",
287 build_interval=1,
288 build_timeout=1,
289 show_volume=show_volume)
290 self.patch('time.time', return_value=0.)
291 self.patch('time.sleep')
292 self.assertRaises(lib_exc.TempestException,
293 waiters.wait_for_volume_migration,
294 client, mock.sentinel.volume_id, 'dst_host')
295
296 def test_wait_for_volume_migration_success_and_dst(self):
297 show_volume = mock.MagicMock(side_effect=[
298 self.vol_migrating_src_host,
299 self.vol_migrating_dst_host,
300 self.vol_migration_success])
301 client = mock.Mock(spec=volumes_client.VolumesClient,
302 resource_type="volume",
303 build_interval=1,
304 build_timeout=1,
305 show_volume=show_volume)
306 self.patch('time.time', return_value=0.)
307 self.patch('time.sleep')
308 waiters.wait_for_volume_migration(
309 client, mock.sentinel.volume_id, 'dst_host')
310
311 # Assert that we wait until migration_status is success and dst_host is
312 # part of the returned os-vol-host-attr:host.
313 show_volume.assert_has_calls([mock.call(mock.sentinel.volume_id),
314 mock.call(mock.sentinel.volume_id),
315 mock.call(mock.sentinel.volume_id)])
Lee Yarwood9e202d82020-01-08 16:41:32 +0000316
317 @mock.patch.object(time, 'sleep')
318 def test_wait_for_volume_status_error_restoring(self, mock_sleep):
319 # Tests that the wait method raises VolumeRestoreErrorException if
320 # the volume status is 'error_restoring'.
321 client = mock.Mock(spec=volumes_client.VolumesClient,
322 resource_type="volume",
323 build_interval=1)
324 volume1 = {'volume': {'status': 'restoring-backup'}}
325 volume2 = {'volume': {'status': 'error_restoring'}}
326 mock_show = mock.Mock(side_effect=(volume1, volume2))
327 client.show_volume = mock_show
328 volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
329 self.assertRaises(exceptions.VolumeRestoreErrorException,
330 waiters.wait_for_volume_resource_status,
331 client, volume_id, 'available')
332 mock_show.assert_has_calls([mock.call(volume_id),
333 mock.call(volume_id)])
334 mock_sleep.assert_called_once_with(1)
335
336 @mock.patch.object(time, 'sleep')
337 def test_wait_for_volume_status_error_extending(self, mock_sleep):
338 # Tests that the wait method raises VolumeExtendErrorException if
339 # the volume status is 'error_extending'.
340 client = mock.Mock(spec=volumes_client.VolumesClient,
341 resource_type="volume",
342 build_interval=1)
343 volume1 = {'volume': {'status': 'extending'}}
344 volume2 = {'volume': {'status': 'error_extending'}}
345 mock_show = mock.Mock(side_effect=(volume1, volume2))
346 client.show_volume = mock_show
347 volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
348 self.assertRaises(exceptions.VolumeExtendErrorException,
349 waiters.wait_for_volume_resource_status,
350 client, volume_id, 'available')
351 mock_show.assert_has_calls([mock.call(volume_id),
352 mock.call(volume_id)])
353 mock_sleep.assert_called_once_with(1)
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000354
Peter Penchev5c243a92020-09-06 02:26:03 +0300355 def test_wait_for_volume_attachment_create(self):
356 vol_detached = {'volume': {'attachments': []}}
357 vol_attached = {'volume': {'attachments': [
358 {'id': uuids.volume_id,
359 'attachment_id': uuids.attachment_id,
360 'server_id': uuids.server_id,
361 'volume_id': uuids.volume_id}]}}
362 show_volume = mock.MagicMock(side_effect=[
363 vol_detached, vol_detached, vol_attached])
364 client = mock.Mock(spec=volumes_client.VolumesClient,
365 build_interval=1,
366 build_timeout=5,
367 show_volume=show_volume)
368 self.patch('time.time')
369 self.patch('time.sleep')
370 att = waiters.wait_for_volume_attachment_create(
371 client, uuids.volume_id, uuids.server_id)
372 assert att == vol_attached['volume']['attachments'][0]
373 # Assert that show volume is called until the attachment is removed.
374 show_volume.assert_has_calls([mock.call(uuids.volume_id),
375 mock.call(uuids.volume_id),
376 mock.call(uuids.volume_id)])
377
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000378 def test_wait_for_volume_attachment(self):
379 vol_detached = {'volume': {'attachments': []}}
380 vol_attached = {'volume': {'attachments': [
381 {'attachment_id': uuids.attachment_id}]}}
382 show_volume = mock.MagicMock(side_effect=[
383 vol_attached, vol_attached, vol_detached])
384 client = mock.Mock(spec=volumes_client.VolumesClient,
385 build_interval=1,
386 build_timeout=5,
387 show_volume=show_volume)
388 self.patch('time.time')
389 self.patch('time.sleep')
390 waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
391 uuids.attachment_id)
392 # Assert that show volume is called until the attachment is removed.
Peter Penchevdc4ceae2020-09-09 00:47:50 +0300393 show_volume.assert_has_calls([mock.call(uuids.volume_id),
394 mock.call(uuids.volume_id),
395 mock.call(uuids.volume_id)])
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000396
397 def test_wait_for_volume_attachment_timeout(self):
398 show_volume = mock.MagicMock(return_value={
399 'volume': {'attachments': [
400 {'attachment_id': uuids.attachment_id}]}})
401 client = mock.Mock(spec=volumes_client.VolumesClient,
402 build_interval=1,
403 build_timeout=1,
404 show_volume=show_volume)
405 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
406 self.patch('time.sleep')
407 # Assert that a timeout is raised if the attachment remains.
408 self.assertRaises(lib_exc.TimeoutException,
409 waiters.wait_for_volume_attachment_remove,
410 client, uuids.volume_id, uuids.attachment_id)
411
412 def test_wait_for_volume_attachment_not_present(self):
413 show_volume = mock.MagicMock(return_value={
414 'volume': {'attachments': []}})
415 client = mock.Mock(spec=volumes_client.VolumesClient,
416 build_interval=1,
417 build_timeout=1,
418 show_volume=show_volume)
419 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
420 self.patch('time.sleep')
421 waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
422 uuids.attachment_id)
423 # Assert that show volume is only called once before we return
424 show_volume.assert_called_once_with(uuids.volume_id)
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100425
426 def test_wait_for_volume_attachment_remove_from_server(self):
427 volume_attached = {
428 "volumeAttachments": [{"volumeId": uuids.volume_id}]}
429 volume_not_attached = {"volumeAttachments": []}
430 mock_list_volume_attachments = mock.Mock(
431 side_effect=[volume_attached, volume_not_attached])
432 mock_client = mock.Mock(
433 spec=servers_client.ServersClient,
434 build_interval=1,
435 build_timeout=1,
436 list_volume_attachments=mock_list_volume_attachments)
437 self.patch(
438 'time.time',
439 side_effect=[0., 0.5, mock_client.build_timeout + 1.])
440 self.patch('time.sleep')
441
442 waiters.wait_for_volume_attachment_remove_from_server(
443 mock_client, uuids.server_id, uuids.volume_id)
444
445 # Assert that list_volume_attachments is called until the attachment is
446 # removed.
447 mock_list_volume_attachments.assert_has_calls([
448 mock.call(uuids.server_id),
449 mock.call(uuids.server_id)])
450
451 def test_wait_for_volume_attachment_remove_from_server_timeout(self):
452 volume_attached = {
453 "volumeAttachments": [{"volumeId": uuids.volume_id}]}
454 mock_list_volume_attachments = mock.Mock(
455 side_effect=[volume_attached, volume_attached])
Lee Yarwood1bd60592021-06-04 10:18:35 +0100456 mock_get_console_output = mock.Mock(
457 return_value={'output': 'output'})
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100458 mock_client = mock.Mock(
459 spec=servers_client.ServersClient,
460 build_interval=1,
461 build_timeout=1,
Lee Yarwood1bd60592021-06-04 10:18:35 +0100462 list_volume_attachments=mock_list_volume_attachments,
463 get_console_output=mock_get_console_output)
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100464 self.patch(
465 'time.time',
466 side_effect=[0., 0.5, mock_client.build_timeout + 1.])
467 self.patch('time.sleep')
468
469 self.assertRaises(
470 lib_exc.TimeoutException,
471 waiters.wait_for_volume_attachment_remove_from_server,
472 mock_client, uuids.server_id, uuids.volume_id)
473
474 # Assert that list_volume_attachments is called until the attachment is
475 # removed.
476 mock_list_volume_attachments.assert_has_calls([
477 mock.call(uuids.server_id),
478 mock.call(uuids.server_id)])
Lee Yarwood1bd60592021-06-04 10:18:35 +0100479
480 # Assert that we fetch console output
481 mock_get_console_output.assert_called_once_with(uuids.server_id)
482
483 def test_wait_for_volume_attachment_remove_from_server_not_found(self):
484 mock_list_volume_attachments = mock.Mock(
485 side_effect=lib_exc.NotFound)
486 mock_client = mock.Mock(
487 spec=servers_client.ServersClient,
488 list_volume_attachments=mock_list_volume_attachments)
489
490 # Assert that nothing is raised when lib_exc_NotFound is raised
491 # by the client call to list_volume_attachments
492 waiters.wait_for_volume_attachment_remove_from_server(
493 mock_client, mock.sentinel.server_id, mock.sentinel.volume_id)
494
495 # Assert that list_volume_attachments was actually called
496 mock_list_volume_attachments.assert_called_once_with(
497 mock.sentinel.server_id)
Artom Lifshitz8a959ea2021-09-27 12:09:12 -0400498
499
500class TestServerFloatingIPWaiters(base.TestCase):
501
502 def test_wait_for_server_floating_ip_associate_timeout(self):
503 mock_server = {'server': {'id': 'fake_uuid', 'addresses': {}}}
504 mock_client = mock.Mock(
505 spec=servers_client.ServersClient,
506 build_timeout=1, build_interval=1,
507 show_server=lambda id: mock_server)
508
509 fake_server = {'id': 'fake-uuid'}
510 fake_fip = {'floating_ip_address': 'fake_address'}
511 self.assertRaises(
512 lib_exc.TimeoutException,
513 waiters.wait_for_server_floating_ip, mock_client, fake_server,
514 fake_fip)
515
516 def test_wait_for_server_floating_ip_disassociate_timeout(self):
517 mock_addresses = {'shared': [{'OS-EXT-IPS:type': 'floating',
518 'addr': 'fake_address'}]}
519 mock_server = {'server': {'id': 'fake_uuid',
520 'addresses': mock_addresses}}
521 mock_client = mock.Mock(
522 spec=servers_client.ServersClient,
523 build_timeout=1, build_interval=1,
524 show_server=lambda id: mock_server)
525
526 fake_server = {'id': 'fake-uuid'}
527 fake_fip = {'floating_ip_address': 'fake_address'}
528 self.assertRaises(
529 lib_exc.TimeoutException,
530 waiters.wait_for_server_floating_ip, mock_client, fake_server,
531 fake_fip, wait_for_disassociate=True)