Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 1 | # 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 | |
| 15 | import time |
Sean McGinnis | eed8074 | 2020-04-18 12:01:03 -0500 | [diff] [blame] | 16 | from unittest import mock |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 17 | |
Lee Yarwood | c1b2a4a | 2020-01-08 17:02:49 +0000 | [diff] [blame] | 18 | from oslo_utils.fixture import uuidsentinel as uuids |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 19 | |
| 20 | from tempest.common import waiters |
| 21 | from tempest import exceptions |
guo yunxian | ebb15f2 | 2016-11-01 21:03:35 +0800 | [diff] [blame] | 22 | from tempest.lib import exceptions as lib_exc |
Balazs Gibizer | 2e515fe | 2020-12-07 15:10:11 +0100 | [diff] [blame] | 23 | from tempest.lib.services.compute import servers_client |
lkuchlan | f53947e | 2016-09-15 10:37:57 +0300 | [diff] [blame] | 24 | from tempest.lib.services.volume.v2 import volumes_client |
Matthew Treinish | ffad78a | 2016-04-16 14:39:52 -0400 | [diff] [blame] | 25 | from tempest.tests import base |
Jordan Pittier | 0e53b61 | 2016-03-03 14:23:17 +0100 | [diff] [blame] | 26 | import tempest.tests.utils as utils |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 27 | |
| 28 | |
| 29 | class 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 Ohmichi | 5d41076 | 2015-05-22 01:10:03 +0000 | [diff] [blame] | 37 | self.client.show_image.return_value = ({'status': 'active'}) |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 38 | 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 Vancsics | 64862f7 | 2016-11-08 09:12:31 +0100 | [diff] [blame] | 42 | self.assertLess((end_time - start_time), 10) |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 43 | |
Yaroslav Lobankov | 2fea405 | 2016-04-19 15:05:57 +0300 | [diff] [blame] | 44 | def test_wait_for_image_status_timeout(self): |
Jordan Pittier | 0e53b61 | 2016-03-03 14:23:17 +0100 | [diff] [blame] | 45 | time_mock = self.patch('time.time') |
| 46 | time_mock.side_effect = utils.generate_timeout_series(1) |
| 47 | |
Ken'ichi Ohmichi | 5d41076 | 2015-05-22 01:10:03 +0000 | [diff] [blame] | 48 | self.client.show_image.return_value = ({'status': 'saving'}) |
guo yunxian | ebb15f2 | 2016-11-01 21:03:35 +0800 | [diff] [blame] | 49 | self.assertRaises(lib_exc.TimeoutException, |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 50 | waiters.wait_for_image_status, |
| 51 | self.client, 'fake_image_id', 'active') |
| 52 | |
Yaroslav Lobankov | 2fea405 | 2016-04-19 15:05:57 +0300 | [diff] [blame] | 53 | def test_wait_for_image_status_error_on_image_create(self): |
Ken'ichi Ohmichi | 5d41076 | 2015-05-22 01:10:03 +0000 | [diff] [blame] | 54 | self.client.show_image.return_value = ({'status': 'ERROR'}) |
Matthew Treinish | 7b01582 | 2014-01-21 18:15:39 +0000 | [diff] [blame] | 55 | self.assertRaises(exceptions.AddImageException, |
| 56 | waiters.wait_for_image_status, |
| 57 | self.client, 'fake_image_id', 'active') |
Matt Riedemann | f77e7dc | 2015-08-10 16:39:39 -0700 | [diff] [blame] | 58 | |
zhufl | 414ffba | 2020-11-19 16:57:06 +0800 | [diff] [blame] | 59 | 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 Smith | ef8e054 | 2021-02-05 13:05:45 -0800 | [diff] [blame] | 69 | def test_wait_for_image_imported_to_stores_failure(self): |
zhufl | 414ffba | 2020-11-19 16:57:06 +0800 | [diff] [blame] | 70 | 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 Smith | ef8e054 | 2021-02-05 13:05:45 -0800 | [diff] [blame] | 80 | 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'}) |
zhufl | 414ffba | 2020-11-19 16:57:06 +0800 | [diff] [blame] | 94 | 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 Mann | b15b58e | 2021-04-29 19:45:29 -0500 | [diff] [blame] | 123 | 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 Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 146 | |
| 147 | class TestInterfaceWaiters(base.TestCase): |
Artom Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 148 | |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 149 | build_timeout = 1. |
| 150 | build_interval = 1 |
| 151 | port_down = {'interfaceAttachment': {'port_state': 'DOWN'}} |
| 152 | port_active = {'interfaceAttachment': {'port_state': 'ACTIVE'}} |
Artom Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 153 | |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 154 | def mock_client(self, **kwargs): |
| 155 | return mock.MagicMock( |
| 156 | build_timeout=self.build_timeout, |
| 157 | build_interval=self.build_interval, |
| 158 | **kwargs) |
Artom Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 159 | |
| 160 | def test_wait_for_interface_status(self): |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 161 | 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 Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 174 | |
| 175 | def test_wait_for_interface_status_timeout(self): |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 176 | 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 Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 180 | |
Artom Lifshitz | df0d6d7 | 2018-05-11 11:31:11 -0400 | [diff] [blame] | 181 | self.assertRaises(lib_exc.TimeoutException, |
| 182 | waiters.wait_for_interface_status, |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 183 | client, 'server_id', 'port_id', 'ACTIVE') |
Artom Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 184 | |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 185 | 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 Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 188 | |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 189 | one_interface = {'interfaceAttachments': [{'port_id': 'port_one'}]} |
| 190 | two_interfaces = {'interfaceAttachments': [{'port_id': 'port_one'}, |
| 191 | {'port_id': 'port_two'}]} |
Artom Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 192 | |
| 193 | def test_wait_for_interface_detach(self): |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 194 | 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 Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 207 | |
| 208 | def test_wait_for_interface_detach_timeout(self): |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 209 | 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 Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 213 | |
Artom Lifshitz | 3306d42 | 2018-03-22 12:20:54 -0400 | [diff] [blame] | 214 | self.assertRaises(lib_exc.TimeoutException, |
| 215 | waiters.wait_for_interface_detach, |
Federico Ressi | 8827d38 | 2018-06-12 23:27:00 +0200 | [diff] [blame] | 216 | 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 Yarwood | e559740 | 2019-02-15 20:17:00 +0000 | [diff] [blame] | 221 | |
Slawek Kaplonski | e3405ba | 2020-11-09 17:24:13 +0100 | [diff] [blame] | 222 | 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 Yarwood | e559740 | 2019-02-15 20:17:00 +0000 | [diff] [blame] | 252 | |
| 253 | class 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 Yarwood | 9e202d8 | 2020-01-08 16:41:32 +0000 | [diff] [blame] | 316 | |
| 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 Yarwood | c1b2a4a | 2020-01-08 17:02:49 +0000 | [diff] [blame] | 354 | |
Peter Penchev | 5c243a9 | 2020-09-06 02:26:03 +0300 | [diff] [blame] | 355 | 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 Yarwood | c1b2a4a | 2020-01-08 17:02:49 +0000 | [diff] [blame] | 378 | 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 Penchev | dc4ceae | 2020-09-09 00:47:50 +0300 | [diff] [blame] | 393 | show_volume.assert_has_calls([mock.call(uuids.volume_id), |
| 394 | mock.call(uuids.volume_id), |
| 395 | mock.call(uuids.volume_id)]) |
Lee Yarwood | c1b2a4a | 2020-01-08 17:02:49 +0000 | [diff] [blame] | 396 | |
| 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 Gibizer | 2e515fe | 2020-12-07 15:10:11 +0100 | [diff] [blame] | 425 | |
| 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 Yarwood | 1bd6059 | 2021-06-04 10:18:35 +0100 | [diff] [blame] | 456 | mock_get_console_output = mock.Mock( |
| 457 | return_value={'output': 'output'}) |
Balazs Gibizer | 2e515fe | 2020-12-07 15:10:11 +0100 | [diff] [blame] | 458 | mock_client = mock.Mock( |
| 459 | spec=servers_client.ServersClient, |
| 460 | build_interval=1, |
| 461 | build_timeout=1, |
Lee Yarwood | 1bd6059 | 2021-06-04 10:18:35 +0100 | [diff] [blame] | 462 | list_volume_attachments=mock_list_volume_attachments, |
| 463 | get_console_output=mock_get_console_output) |
Balazs Gibizer | 2e515fe | 2020-12-07 15:10:11 +0100 | [diff] [blame] | 464 | 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 Yarwood | 1bd6059 | 2021-06-04 10:18:35 +0100 | [diff] [blame] | 479 | |
| 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 Lifshitz | 8a959ea | 2021-09-27 12:09:12 -0400 | [diff] [blame^] | 498 | |
| 499 | |
| 500 | class 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) |