blob: b7b02ab99afce76df31e6cb4ed1555f1ef257c54 [file] [log] [blame]
Attila Fazekas0abbc952013-07-01 19:19:42 +02001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13
14import time
15
Doug Hellmann583ce2c2015-03-11 14:55:46 +000016from oslo_log import log as logging
Matthew Treinish01472ff2015-02-20 17:26:52 -050017
Ken'ichi Ohmichi01151e82016-06-10 11:19:52 -070018from tempest.common import image as common_image
Attila Fazekas0abbc952013-07-01 19:19:42 +020019from tempest import config
20from tempest import exceptions
zhufl88c89b52016-07-01 18:09:05 +080021from tempest.lib.common.utils import test_utils
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050022from tempest.lib import exceptions as lib_exc
Ken'ichi Ohmichi41721012016-06-22 10:41:26 -070023from tempest.lib.services.image.v1 import images_client as images_v1_client
Attila Fazekas0abbc952013-07-01 19:19:42 +020024
Sean Dague86bd8422013-12-20 09:56:44 -050025CONF = config.CONF
Attila Fazekas0abbc952013-07-01 19:19:42 +020026LOG = logging.getLogger(__name__)
27
28
Matt Riedemannf748c112017-02-03 11:33:11 -050029def _get_task_state(body):
30 return body.get('OS-EXT-STS:task_state', None)
31
32
Attila Fazekas0abbc952013-07-01 19:19:42 +020033# NOTE(afazekas): This function needs to know a token and a subject.
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090034def wait_for_server_status(client, server_id, status, ready_wait=True,
Zhi Kun Liue5401762013-09-11 20:45:48 +080035 extra_timeout=0, raise_on_error=True):
Attila Fazekas0abbc952013-07-01 19:19:42 +020036 """Waits for a server to reach a given status."""
37
Attila Fazekas0abbc952013-07-01 19:19:42 +020038 # NOTE(afazekas): UNKNOWN status possible on ERROR
39 # or in a very early stage.
ghanshyam0f825252015-08-25 16:02:50 +090040 body = client.show_server(server_id)['server']
Attila Fazekas0abbc952013-07-01 19:19:42 +020041 old_status = server_status = body['status']
42 old_task_state = task_state = _get_task_state(body)
43 start_time = int(time.time())
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090044 timeout = client.build_timeout + extra_timeout
Attila Fazekas0abbc952013-07-01 19:19:42 +020045 while True:
46 # NOTE(afazekas): Now the BUILD status only reached
Shane Wang111f86c2014-02-20 16:40:22 +080047 # between the UNKNOWN->ACTIVE transition.
Attila Fazekas0abbc952013-07-01 19:19:42 +020048 # TODO(afazekas): enumerate and validate the stable status set
49 if status == 'BUILD' and server_status != 'UNKNOWN':
50 return
51 if server_status == status:
52 if ready_wait:
53 if status == 'BUILD':
54 return
55 # NOTE(afazekas): The instance is in "ready for action state"
56 # when no task in progress
Ken'ichi Ohmichi534a05e2016-08-03 14:45:15 -070057 if task_state is None:
Attila Fazekas0abbc952013-07-01 19:19:42 +020058 # without state api extension 3 sec usually enough
Sean Dague86bd8422013-12-20 09:56:44 -050059 time.sleep(CONF.compute.ready_wait)
Attila Fazekas0abbc952013-07-01 19:19:42 +020060 return
61 else:
62 return
63
64 time.sleep(client.build_interval)
ghanshyam0f825252015-08-25 16:02:50 +090065 body = client.show_server(server_id)['server']
Attila Fazekas0abbc952013-07-01 19:19:42 +020066 server_status = body['status']
67 task_state = _get_task_state(body)
68 if (server_status != old_status) or (task_state != old_task_state):
69 LOG.info('State transition "%s" ==> "%s" after %d second wait',
70 '/'.join((old_status, str(old_task_state))),
71 '/'.join((server_status, str(task_state))),
72 time.time() - start_time)
Zhi Kun Liue5401762013-09-11 20:45:48 +080073 if (server_status == 'ERROR') and raise_on_error:
Attila Fazekas0462a7f2014-06-20 07:38:06 +020074 if 'fault' in body:
75 raise exceptions.BuildErrorException(body['fault'],
Matthew Treinish1d14c542014-06-17 20:25:40 -040076 server_id=server_id)
Attila Fazekas0462a7f2014-06-20 07:38:06 +020077 else:
78 raise exceptions.BuildErrorException(server_id=server_id)
Attila Fazekas0abbc952013-07-01 19:19:42 +020079
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090080 timed_out = int(time.time()) - start_time >= timeout
Attila Fazekas0abbc952013-07-01 19:19:42 +020081
82 if timed_out:
Matt Riedemann629fa7c2013-12-11 18:20:56 -080083 expected_task_state = 'None' if ready_wait else 'n/a'
84 message = ('Server %(server_id)s failed to reach %(status)s '
85 'status and task state "%(expected_task_state)s" '
86 'within the required time (%(timeout)s s).' %
87 {'server_id': server_id,
88 'status': status,
89 'expected_task_state': expected_task_state,
90 'timeout': timeout})
Attila Fazekas0abbc952013-07-01 19:19:42 +020091 message += ' Current status: %s.' % server_status
Matt Riedemann629fa7c2013-12-11 18:20:56 -080092 message += ' Current task state: %s.' % task_state
zhufl88c89b52016-07-01 18:09:05 +080093 caller = test_utils.find_test_caller()
Matt Riedemann128c23e2014-05-02 13:46:39 -070094 if caller:
95 message = '(%s) %s' % (caller, message)
guo yunxianebb15f22016-11-01 21:03:35 +080096 raise lib_exc.TimeoutException(message)
Attila Fazekas0abbc952013-07-01 19:19:42 +020097 old_status = server_status
98 old_task_state = task_state
Matt Riedemannc00f3262013-12-14 12:03:55 -080099
100
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000101def wait_for_server_termination(client, server_id, ignore_error=False):
102 """Waits for server to reach termination."""
Matt Riedemannf748c112017-02-03 11:33:11 -0500103 try:
104 body = client.show_server(server_id)['server']
105 except lib_exc.NotFound:
106 return
107 old_status = server_status = body['status']
108 old_task_state = task_state = _get_task_state(body)
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000109 start_time = int(time.time())
110 while True:
Matt Riedemannf748c112017-02-03 11:33:11 -0500111 time.sleep(client.build_interval)
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000112 try:
ghanshyam0f825252015-08-25 16:02:50 +0900113 body = client.show_server(server_id)['server']
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000114 except lib_exc.NotFound:
115 return
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000116 server_status = body['status']
Matt Riedemannf748c112017-02-03 11:33:11 -0500117 task_state = _get_task_state(body)
118 if (server_status != old_status) or (task_state != old_task_state):
119 LOG.info('State transition "%s" ==> "%s" after %d second wait',
120 '/'.join((old_status, str(old_task_state))),
121 '/'.join((server_status, str(task_state))),
122 time.time() - start_time)
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000123 if server_status == 'ERROR' and not ignore_error:
124 raise exceptions.BuildErrorException(server_id=server_id)
125
126 if int(time.time()) - start_time >= client.build_timeout:
guo yunxianebb15f22016-11-01 21:03:35 +0800127 raise lib_exc.TimeoutException
Matt Riedemannf748c112017-02-03 11:33:11 -0500128 old_status = server_status
129 old_task_state = task_state
Ken'ichi Ohmichie91a0c62015-08-13 02:09:16 +0000130
131
Matt Riedemannc00f3262013-12-14 12:03:55 -0800132def wait_for_image_status(client, image_id, status):
133 """Waits for an image to reach a given status.
134
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000135 The client should have a show_image(image_id) method to get the image.
Matt Riedemannc00f3262013-12-14 12:03:55 -0800136 The client should also have build_interval and build_timeout attributes.
137 """
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300138 if isinstance(client, images_v1_client.ImagesClient):
139 # The 'check_image' method is used here because the show_image method
140 # returns image details plus the image itself which is very expensive.
141 # The 'check_image' method returns just image details.
Ken'ichi Ohmichi01151e82016-06-10 11:19:52 -0700142 def _show_image_v1(image_id):
143 resp = client.check_image(image_id)
144 return common_image.get_image_meta_from_headers(resp)
145
146 show_image = _show_image_v1
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300147 else:
148 show_image = client.show_image
Matt Riedemannc00f3262013-12-14 12:03:55 -0800149
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300150 current_status = 'An unknown status'
151 start = int(time.time())
152 while int(time.time()) - start < client.build_timeout:
153 image = show_image(image_id)
154 # Compute image client returns response wrapped in 'image' element
Xiangfei Zhua8fd20a2016-07-26 21:28:12 -0700155 # which is not the case with Glance image client.
ghanshyam1756e0b2015-08-18 19:19:05 +0900156 if 'image' in image:
157 image = image['image']
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300158
159 current_status = image['status']
160 if current_status == status:
161 return
162 if current_status.lower() == 'killed':
163 raise exceptions.ImageKilledException(image_id=image_id,
164 status=status)
165 if current_status.lower() == 'error':
Matt Riedemannc00f3262013-12-14 12:03:55 -0800166 raise exceptions.AddImageException(image_id=image_id)
167
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300168 time.sleep(client.build_interval)
Matt Riedemannc00f3262013-12-14 12:03:55 -0800169
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300170 message = ('Image %(image_id)s failed to reach %(status)s state '
171 '(current state %(current_status)s) within the required '
172 'time (%(timeout)s s).' % {'image_id': image_id,
173 'status': status,
174 'current_status': current_status,
175 'timeout': client.build_timeout})
zhufl88c89b52016-07-01 18:09:05 +0800176 caller = test_utils.find_test_caller()
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +0300177 if caller:
178 message = '(%s) %s' % (caller, message)
guo yunxianebb15f22016-11-01 21:03:35 +0800179 raise lib_exc.TimeoutException(message)
Adam Gandelman00682612014-09-02 17:10:36 -0700180
181
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000182def wait_for_volume_status(client, volume_id, status):
183 """Waits for a Volume to reach a given status."""
ghanshyamcb131762015-08-24 18:21:08 +0900184 body = client.show_volume(volume_id)['volume']
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000185 volume_status = body['status']
186 start = int(time.time())
187
188 while volume_status != status:
189 time.sleep(client.build_interval)
ghanshyamcb131762015-08-24 18:21:08 +0900190 body = client.show_volume(volume_id)['volume']
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000191 volume_status = body['status']
Benny Kopilov8a33ee12016-11-09 10:35:23 +0200192 if volume_status == 'error' and status != 'error':
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000193 raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
Matt Riedemannf77e7dc2015-08-10 16:39:39 -0700194 if volume_status == 'error_restoring':
195 raise exceptions.VolumeRestoreErrorException(volume_id=volume_id)
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000196
197 if int(time.time()) - start >= client.build_timeout:
198 message = ('Volume %s failed to reach %s status (current %s) '
199 'within the required time (%s s).' %
200 (volume_id, status, volume_status,
201 client.build_timeout))
guo yunxianebb15f22016-11-01 21:03:35 +0800202 raise lib_exc.TimeoutException(message)
Ken'ichi Ohmichib942be62015-07-08 08:16:12 +0000203
204
scottda61f68ac2016-06-07 12:07:55 -0600205def wait_for_volume_retype(client, volume_id, new_volume_type):
206 """Waits for a Volume to have a new volume type."""
207 body = client.show_volume(volume_id)['volume']
208 current_volume_type = body['volume_type']
209 start = int(time.time())
210
211 while current_volume_type != new_volume_type:
212 time.sleep(client.build_interval)
213 body = client.show_volume(volume_id)['volume']
214 current_volume_type = body['volume_type']
215
216 if int(time.time()) - start >= client.build_timeout:
217 message = ('Volume %s failed to reach %s volume type (current %s) '
218 'within the required time (%s s).' %
219 (volume_id, new_volume_type, current_volume_type,
220 client.build_timeout))
Matt Riedemann74eb3b52017-02-14 11:34:30 -0500221 raise lib_exc.TimeoutException(message)
scottda61f68ac2016-06-07 12:07:55 -0600222
223
Gaozexub9c9d6e2015-09-10 17:08:04 +0800224def wait_for_snapshot_status(client, snapshot_id, status):
225 """Waits for a Snapshot to reach a given status."""
226 body = client.show_snapshot(snapshot_id)['snapshot']
227 snapshot_status = body['status']
228 start = int(time.time())
229
230 while snapshot_status != status:
231 time.sleep(client.build_interval)
232 body = client.show_snapshot(snapshot_id)['snapshot']
233 snapshot_status = body['status']
234 if snapshot_status == 'error':
235 raise exceptions.SnapshotBuildErrorException(
236 snapshot_id=snapshot_id)
237 if int(time.time()) - start >= client.build_timeout:
238 message = ('Snapshot %s failed to reach %s status (current %s) '
239 'within the required time (%s s).' %
240 (snapshot_id, status, snapshot_status,
241 client.build_timeout))
guo yunxianebb15f22016-11-01 21:03:35 +0800242 raise lib_exc.TimeoutException(message)
Gaozexub9c9d6e2015-09-10 17:08:04 +0800243
244
lkuchlan8f321d82016-09-06 10:06:30 +0300245def wait_for_backup_status(client, backup_id, status):
246 """Waits for a Backup to reach a given status."""
247 body = client.show_backup(backup_id)['backup']
248 backup_status = body['status']
249 start = int(time.time())
250
251 while backup_status != status:
252 time.sleep(client.build_interval)
253 body = client.show_backup(backup_id)['backup']
254 backup_status = body['status']
255 if backup_status == 'error' and backup_status != status:
Xinli Guanceb2b462016-10-11 19:34:25 +0000256 raise lib_exc.VolumeBackupException(backup_id=backup_id)
lkuchlan8f321d82016-09-06 10:06:30 +0300257
258 if int(time.time()) - start >= client.build_timeout:
259 message = ('Volume backup %s failed to reach %s status '
260 '(current %s) within the required time (%s s).' %
261 (backup_id, status, backup_status,
262 client.build_timeout))
guo yunxianebb15f22016-11-01 21:03:35 +0800263 raise lib_exc.TimeoutException(message)
lkuchlan8f321d82016-09-06 10:06:30 +0300264
265
lkuchlanec1ba4f2016-09-06 10:28:18 +0300266def wait_for_qos_operations(client, qos_id, operation, args=None):
267 """Waits for a qos operations to be completed.
268
269 NOTE : operation value is required for wait_for_qos_operations()
270 operation = 'qos-key' / 'disassociate' / 'disassociate-all'
271 args = keys[] when operation = 'qos-key'
272 args = volume-type-id disassociated when operation = 'disassociate'
273 args = None when operation = 'disassociate-all'
274 """
275 start_time = int(time.time())
276 while True:
277 if operation == 'qos-key-unset':
278 body = client.show_qos(qos_id)['qos_specs']
279 if not any(key in body['specs'] for key in args):
280 return
281 elif operation == 'disassociate':
282 body = client.show_association_qos(qos_id)['qos_associations']
283 if not any(args in body[i]['id'] for i in range(0, len(body))):
284 return
285 elif operation == 'disassociate-all':
286 body = client.show_association_qos(qos_id)['qos_associations']
287 if not body:
288 return
289 else:
290 msg = (" operation value is either not defined or incorrect.")
291 raise lib_exc.UnprocessableEntity(msg)
292
293 if int(time.time()) - start_time >= client.build_timeout:
guo yunxianebb15f22016-11-01 21:03:35 +0800294 raise lib_exc.TimeoutException
lkuchlanec1ba4f2016-09-06 10:28:18 +0300295 time.sleep(client.build_interval)
zhufl7b638332016-11-14 10:23:30 +0800296
297
298def wait_for_interface_status(client, server, port_id, status):
299 """Waits for an interface to reach a given status."""
300 body = (client.show_interface(server, port_id)
301 ['interfaceAttachment'])
302 interface_status = body['port_state']
303 start = int(time.time())
304
305 while(interface_status != status):
306 time.sleep(client.build_interval)
307 body = (client.show_interface(server, port_id)
308 ['interfaceAttachment'])
309 interface_status = body['port_state']
310
311 timed_out = int(time.time()) - start >= client.build_timeout
312
313 if interface_status != status and timed_out:
314 message = ('Interface %s failed to reach %s status '
315 '(current %s) within the required time (%s s).' %
316 (port_id, status, interface_status,
317 client.build_timeout))
318 raise lib_exc.TimeoutException(message)
319
320 return body