blob: b76a263e509c161ee57801838b852af3af875b01 [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
Artom Lifshitz3306d422018-03-22 12:20:54 -0400189 def test_wait_for_interface_detach(self):
Balazs Gibizer55414582021-10-05 11:22:30 +0200190 no_event = {
191 'instanceAction': {
192 'events': []
193 }
194 }
195 one_event_without_result = {
196 'instanceAction': {
197 'events': [
198 {
199 'event': 'compute_detach_interface',
200 'result': None
201 }
202
203 ]
204 }
205 }
206 one_event_successful = {
207 'instanceAction': {
208 'events': [
209 {
210 'event': 'compute_detach_interface',
211 'result': 'Success'
212 }
213 ]
214 }
215 }
216
217 show_instance_action = mock.MagicMock(
218 # there is an extra call to return the result from the waiter
219 side_effect=[
220 no_event,
221 one_event_without_result,
222 one_event_successful,
223 one_event_successful,
224 ]
225 )
226 client = self.mock_client(show_instance_action=show_instance_action)
Federico Ressi8827d382018-06-12 23:27:00 +0200227 self.patch('time.time', return_value=0.)
228 sleep = self.patch('time.sleep')
229
230 result = waiters.wait_for_interface_detach(
Balazs Gibizer55414582021-10-05 11:22:30 +0200231 client, mock.sentinel.server_id, mock.sentinel.port_id,
232 mock.sentinel.detach_request_id
233 )
Federico Ressi8827d382018-06-12 23:27:00 +0200234
Balazs Gibizer55414582021-10-05 11:22:30 +0200235 self.assertIs(one_event_successful['instanceAction'], result)
236 show_instance_action.assert_has_calls(
237 # there is an extra call to return the result from the waiter
238 [
239 mock.call(
240 mock.sentinel.server_id, mock.sentinel.detach_request_id)
241 ] * 4
242 )
243 sleep.assert_has_calls([mock.call(client.build_interval)] * 2)
Artom Lifshitz3306d422018-03-22 12:20:54 -0400244
245 def test_wait_for_interface_detach_timeout(self):
Balazs Gibizer55414582021-10-05 11:22:30 +0200246 one_event_without_result = {
247 'instanceAction': {
248 'events': [
249 {
250 'event': 'compute_detach_interface',
251 'result': None
252 }
253
254 ]
255 }
256 }
257
258 show_instance_action = mock.MagicMock(
259 return_value=one_event_without_result)
260 client = self.mock_client(show_instance_action=show_instance_action)
Federico Ressi8827d382018-06-12 23:27:00 +0200261 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
262 sleep = self.patch('time.sleep')
Artom Lifshitz3306d422018-03-22 12:20:54 -0400263
Balazs Gibizer55414582021-10-05 11:22:30 +0200264 self.assertRaises(
265 lib_exc.TimeoutException,
266 waiters.wait_for_interface_detach,
267 client, mock.sentinel.server_id, mock.sentinel.port_id,
268 mock.sentinel.detach_request_id
269 )
Federico Ressi8827d382018-06-12 23:27:00 +0200270
Balazs Gibizer55414582021-10-05 11:22:30 +0200271 show_instance_action.assert_has_calls(
272 [
273 mock.call(
274 mock.sentinel.server_id, mock.sentinel.detach_request_id)
275 ] * 2
276 )
Federico Ressi8827d382018-06-12 23:27:00 +0200277 sleep.assert_called_once_with(client.build_interval)
Lee Yarwoode5597402019-02-15 20:17:00 +0000278
Slawek Kaplonskie3405ba2020-11-09 17:24:13 +0100279 def test_wait_for_guest_os_boot(self):
280 get_console_output = mock.Mock(
281 side_effect=[
282 {'output': 'os not ready yet\n'},
283 {'output': 'login:\n'}
284 ])
285 client = self.mock_client(get_console_output=get_console_output)
286 self.patch('time.time', return_value=0.)
287 sleep = self.patch('time.sleep')
288
289 with mock.patch.object(waiters.LOG, "info") as log_info:
290 waiters.wait_for_guest_os_boot(client, 'server_id')
291
292 get_console_output.assert_has_calls([
293 mock.call('server_id'), mock.call('server_id')])
294 sleep.assert_called_once_with(client.build_interval)
295 log_info.assert_not_called()
296
297 def test_wait_for_guest_os_boot_timeout(self):
298 get_console_output = mock.Mock(
299 return_value={'output': 'os not ready yet\n'})
300 client = self.mock_client(get_console_output=get_console_output)
301 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
302 self.patch('time.sleep')
303
304 with mock.patch.object(waiters.LOG, "info") as log_info:
305 waiters.wait_for_guest_os_boot(client, 'server_id')
306
307 log_info.assert_called_once()
308
Lee Yarwoode5597402019-02-15 20:17:00 +0000309
310class TestVolumeWaiters(base.TestCase):
311 vol_migrating_src_host = {
312 'volume': {'migration_status': 'migrating',
313 'os-vol-host-attr:host': 'src_host@backend#type'}}
314 vol_migrating_dst_host = {
315 'volume': {'migration_status': 'migrating',
316 'os-vol-host-attr:host': 'dst_host@backend#type'}}
317 vol_migration_success = {
318 'volume': {'migration_status': 'success',
319 'os-vol-host-attr:host': 'dst_host@backend#type'}}
320 vol_migration_error = {
321 'volume': {'migration_status': 'error',
322 'os-vol-host-attr:host': 'src_host@backend#type'}}
323
324 def test_wait_for_volume_migration_timeout(self):
325 show_volume = mock.MagicMock(return_value=self.vol_migrating_src_host)
326 client = mock.Mock(spec=volumes_client.VolumesClient,
327 resource_type="volume",
328 build_interval=1,
329 build_timeout=1,
330 show_volume=show_volume)
331 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
332 self.patch('time.sleep')
333 self.assertRaises(lib_exc.TimeoutException,
334 waiters.wait_for_volume_migration,
335 client, mock.sentinel.volume_id, 'dst_host')
336
337 def test_wait_for_volume_migration_error(self):
338 show_volume = mock.MagicMock(side_effect=[
339 self.vol_migrating_src_host,
340 self.vol_migrating_src_host,
341 self.vol_migration_error])
342 client = mock.Mock(spec=volumes_client.VolumesClient,
343 resource_type="volume",
344 build_interval=1,
345 build_timeout=1,
346 show_volume=show_volume)
347 self.patch('time.time', return_value=0.)
348 self.patch('time.sleep')
349 self.assertRaises(lib_exc.TempestException,
350 waiters.wait_for_volume_migration,
351 client, mock.sentinel.volume_id, 'dst_host')
352
353 def test_wait_for_volume_migration_success_and_dst(self):
354 show_volume = mock.MagicMock(side_effect=[
355 self.vol_migrating_src_host,
356 self.vol_migrating_dst_host,
357 self.vol_migration_success])
358 client = mock.Mock(spec=volumes_client.VolumesClient,
359 resource_type="volume",
360 build_interval=1,
361 build_timeout=1,
362 show_volume=show_volume)
363 self.patch('time.time', return_value=0.)
364 self.patch('time.sleep')
365 waiters.wait_for_volume_migration(
366 client, mock.sentinel.volume_id, 'dst_host')
367
368 # Assert that we wait until migration_status is success and dst_host is
369 # part of the returned os-vol-host-attr:host.
370 show_volume.assert_has_calls([mock.call(mock.sentinel.volume_id),
371 mock.call(mock.sentinel.volume_id),
372 mock.call(mock.sentinel.volume_id)])
Lee Yarwood9e202d82020-01-08 16:41:32 +0000373
374 @mock.patch.object(time, 'sleep')
375 def test_wait_for_volume_status_error_restoring(self, mock_sleep):
376 # Tests that the wait method raises VolumeRestoreErrorException if
377 # the volume status is 'error_restoring'.
378 client = mock.Mock(spec=volumes_client.VolumesClient,
379 resource_type="volume",
380 build_interval=1)
381 volume1 = {'volume': {'status': 'restoring-backup'}}
382 volume2 = {'volume': {'status': 'error_restoring'}}
383 mock_show = mock.Mock(side_effect=(volume1, volume2))
384 client.show_volume = mock_show
385 volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
386 self.assertRaises(exceptions.VolumeRestoreErrorException,
387 waiters.wait_for_volume_resource_status,
388 client, volume_id, 'available')
389 mock_show.assert_has_calls([mock.call(volume_id),
390 mock.call(volume_id)])
391 mock_sleep.assert_called_once_with(1)
392
393 @mock.patch.object(time, 'sleep')
394 def test_wait_for_volume_status_error_extending(self, mock_sleep):
395 # Tests that the wait method raises VolumeExtendErrorException if
396 # the volume status is 'error_extending'.
397 client = mock.Mock(spec=volumes_client.VolumesClient,
398 resource_type="volume",
399 build_interval=1)
400 volume1 = {'volume': {'status': 'extending'}}
401 volume2 = {'volume': {'status': 'error_extending'}}
402 mock_show = mock.Mock(side_effect=(volume1, volume2))
403 client.show_volume = mock_show
404 volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
405 self.assertRaises(exceptions.VolumeExtendErrorException,
406 waiters.wait_for_volume_resource_status,
407 client, volume_id, 'available')
408 mock_show.assert_has_calls([mock.call(volume_id),
409 mock.call(volume_id)])
410 mock_sleep.assert_called_once_with(1)
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000411
Peter Penchev5c243a92020-09-06 02:26:03 +0300412 def test_wait_for_volume_attachment_create(self):
413 vol_detached = {'volume': {'attachments': []}}
414 vol_attached = {'volume': {'attachments': [
415 {'id': uuids.volume_id,
416 'attachment_id': uuids.attachment_id,
417 'server_id': uuids.server_id,
418 'volume_id': uuids.volume_id}]}}
419 show_volume = mock.MagicMock(side_effect=[
420 vol_detached, vol_detached, vol_attached])
421 client = mock.Mock(spec=volumes_client.VolumesClient,
422 build_interval=1,
423 build_timeout=5,
424 show_volume=show_volume)
425 self.patch('time.time')
426 self.patch('time.sleep')
427 att = waiters.wait_for_volume_attachment_create(
428 client, uuids.volume_id, uuids.server_id)
429 assert att == vol_attached['volume']['attachments'][0]
430 # Assert that show volume is called until the attachment is removed.
431 show_volume.assert_has_calls([mock.call(uuids.volume_id),
432 mock.call(uuids.volume_id),
433 mock.call(uuids.volume_id)])
434
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000435 def test_wait_for_volume_attachment(self):
436 vol_detached = {'volume': {'attachments': []}}
437 vol_attached = {'volume': {'attachments': [
438 {'attachment_id': uuids.attachment_id}]}}
439 show_volume = mock.MagicMock(side_effect=[
440 vol_attached, vol_attached, vol_detached])
441 client = mock.Mock(spec=volumes_client.VolumesClient,
442 build_interval=1,
443 build_timeout=5,
444 show_volume=show_volume)
445 self.patch('time.time')
446 self.patch('time.sleep')
447 waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
448 uuids.attachment_id)
449 # Assert that show volume is called until the attachment is removed.
Peter Penchevdc4ceae2020-09-09 00:47:50 +0300450 show_volume.assert_has_calls([mock.call(uuids.volume_id),
451 mock.call(uuids.volume_id),
452 mock.call(uuids.volume_id)])
Lee Yarwoodc1b2a4a2020-01-08 17:02:49 +0000453
454 def test_wait_for_volume_attachment_timeout(self):
455 show_volume = mock.MagicMock(return_value={
456 'volume': {'attachments': [
457 {'attachment_id': uuids.attachment_id}]}})
458 client = mock.Mock(spec=volumes_client.VolumesClient,
459 build_interval=1,
460 build_timeout=1,
461 show_volume=show_volume)
462 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
463 self.patch('time.sleep')
464 # Assert that a timeout is raised if the attachment remains.
465 self.assertRaises(lib_exc.TimeoutException,
466 waiters.wait_for_volume_attachment_remove,
467 client, uuids.volume_id, uuids.attachment_id)
468
469 def test_wait_for_volume_attachment_not_present(self):
470 show_volume = mock.MagicMock(return_value={
471 'volume': {'attachments': []}})
472 client = mock.Mock(spec=volumes_client.VolumesClient,
473 build_interval=1,
474 build_timeout=1,
475 show_volume=show_volume)
476 self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
477 self.patch('time.sleep')
478 waiters.wait_for_volume_attachment_remove(client, uuids.volume_id,
479 uuids.attachment_id)
480 # Assert that show volume is only called once before we return
481 show_volume.assert_called_once_with(uuids.volume_id)
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100482
483 def test_wait_for_volume_attachment_remove_from_server(self):
484 volume_attached = {
485 "volumeAttachments": [{"volumeId": uuids.volume_id}]}
486 volume_not_attached = {"volumeAttachments": []}
487 mock_list_volume_attachments = mock.Mock(
488 side_effect=[volume_attached, volume_not_attached])
489 mock_client = mock.Mock(
490 spec=servers_client.ServersClient,
491 build_interval=1,
492 build_timeout=1,
493 list_volume_attachments=mock_list_volume_attachments)
494 self.patch(
495 'time.time',
496 side_effect=[0., 0.5, mock_client.build_timeout + 1.])
497 self.patch('time.sleep')
498
499 waiters.wait_for_volume_attachment_remove_from_server(
500 mock_client, uuids.server_id, uuids.volume_id)
501
502 # Assert that list_volume_attachments is called until the attachment is
503 # removed.
504 mock_list_volume_attachments.assert_has_calls([
505 mock.call(uuids.server_id),
506 mock.call(uuids.server_id)])
507
508 def test_wait_for_volume_attachment_remove_from_server_timeout(self):
509 volume_attached = {
510 "volumeAttachments": [{"volumeId": uuids.volume_id}]}
511 mock_list_volume_attachments = mock.Mock(
512 side_effect=[volume_attached, volume_attached])
Lee Yarwood1bd60592021-06-04 10:18:35 +0100513 mock_get_console_output = mock.Mock(
514 return_value={'output': 'output'})
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100515 mock_client = mock.Mock(
516 spec=servers_client.ServersClient,
517 build_interval=1,
518 build_timeout=1,
Lee Yarwood1bd60592021-06-04 10:18:35 +0100519 list_volume_attachments=mock_list_volume_attachments,
520 get_console_output=mock_get_console_output)
Balazs Gibizer2e515fe2020-12-07 15:10:11 +0100521 self.patch(
522 'time.time',
523 side_effect=[0., 0.5, mock_client.build_timeout + 1.])
524 self.patch('time.sleep')
525
526 self.assertRaises(
527 lib_exc.TimeoutException,
528 waiters.wait_for_volume_attachment_remove_from_server,
529 mock_client, uuids.server_id, uuids.volume_id)
530
531 # Assert that list_volume_attachments is called until the attachment is
532 # removed.
533 mock_list_volume_attachments.assert_has_calls([
534 mock.call(uuids.server_id),
535 mock.call(uuids.server_id)])
Lee Yarwood1bd60592021-06-04 10:18:35 +0100536
537 # Assert that we fetch console output
538 mock_get_console_output.assert_called_once_with(uuids.server_id)
539
540 def test_wait_for_volume_attachment_remove_from_server_not_found(self):
541 mock_list_volume_attachments = mock.Mock(
542 side_effect=lib_exc.NotFound)
543 mock_client = mock.Mock(
544 spec=servers_client.ServersClient,
545 list_volume_attachments=mock_list_volume_attachments)
546
547 # Assert that nothing is raised when lib_exc_NotFound is raised
548 # by the client call to list_volume_attachments
549 waiters.wait_for_volume_attachment_remove_from_server(
550 mock_client, mock.sentinel.server_id, mock.sentinel.volume_id)
551
552 # Assert that list_volume_attachments was actually called
553 mock_list_volume_attachments.assert_called_once_with(
554 mock.sentinel.server_id)
Artom Lifshitz8a959ea2021-09-27 12:09:12 -0400555
556
557class TestServerFloatingIPWaiters(base.TestCase):
558
559 def test_wait_for_server_floating_ip_associate_timeout(self):
560 mock_server = {'server': {'id': 'fake_uuid', 'addresses': {}}}
561 mock_client = mock.Mock(
562 spec=servers_client.ServersClient,
563 build_timeout=1, build_interval=1,
564 show_server=lambda id: mock_server)
565
566 fake_server = {'id': 'fake-uuid'}
567 fake_fip = {'floating_ip_address': 'fake_address'}
568 self.assertRaises(
569 lib_exc.TimeoutException,
570 waiters.wait_for_server_floating_ip, mock_client, fake_server,
571 fake_fip)
572
573 def test_wait_for_server_floating_ip_disassociate_timeout(self):
574 mock_addresses = {'shared': [{'OS-EXT-IPS:type': 'floating',
575 'addr': 'fake_address'}]}
576 mock_server = {'server': {'id': 'fake_uuid',
577 'addresses': mock_addresses}}
578 mock_client = mock.Mock(
579 spec=servers_client.ServersClient,
580 build_timeout=1, build_interval=1,
581 show_server=lambda id: mock_server)
582
583 fake_server = {'id': 'fake-uuid'}
584 fake_fip = {'floating_ip_address': 'fake_address'}
585 self.assertRaises(
586 lib_exc.TimeoutException,
587 waiters.wait_for_server_floating_ip, mock_client, fake_server,
588 fake_fip, wait_for_disassociate=True)