blob: bdbd6bc8be1cdff027ef7cbdbfecd0e82ddcea36 [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 -050017from tempest_lib.common.utils import misc as misc_utils
18
Attila Fazekas0abbc952013-07-01 19:19:42 +020019from tempest import config
20from tempest import exceptions
Attila Fazekas0abbc952013-07-01 19:19:42 +020021
Sean Dague86bd8422013-12-20 09:56:44 -050022CONF = config.CONF
Attila Fazekas0abbc952013-07-01 19:19:42 +020023LOG = logging.getLogger(__name__)
24
25
26# NOTE(afazekas): This function needs to know a token and a subject.
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090027def wait_for_server_status(client, server_id, status, ready_wait=True,
Zhi Kun Liue5401762013-09-11 20:45:48 +080028 extra_timeout=0, raise_on_error=True):
Attila Fazekas0abbc952013-07-01 19:19:42 +020029 """Waits for a server to reach a given status."""
30
31 def _get_task_state(body):
Ken'ichi Ohmichia58c1562014-12-15 00:39:55 +000032 return body.get('OS-EXT-STS:task_state', None)
Attila Fazekas0abbc952013-07-01 19:19:42 +020033
34 # NOTE(afazekas): UNKNOWN status possible on ERROR
35 # or in a very early stage.
Ken'ichi Ohmichi76800242015-07-03 05:12:31 +000036 body = client.show_server(server_id)
Attila Fazekas0abbc952013-07-01 19:19:42 +020037 old_status = server_status = body['status']
38 old_task_state = task_state = _get_task_state(body)
39 start_time = int(time.time())
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090040 timeout = client.build_timeout + extra_timeout
Attila Fazekas0abbc952013-07-01 19:19:42 +020041 while True:
42 # NOTE(afazekas): Now the BUILD status only reached
Shane Wang111f86c2014-02-20 16:40:22 +080043 # between the UNKNOWN->ACTIVE transition.
Attila Fazekas0abbc952013-07-01 19:19:42 +020044 # TODO(afazekas): enumerate and validate the stable status set
45 if status == 'BUILD' and server_status != 'UNKNOWN':
46 return
47 if server_status == status:
48 if ready_wait:
49 if status == 'BUILD':
50 return
51 # NOTE(afazekas): The instance is in "ready for action state"
52 # when no task in progress
53 # NOTE(afazekas): Converted to string bacuse of the XML
54 # responses
55 if str(task_state) == "None":
56 # without state api extension 3 sec usually enough
Sean Dague86bd8422013-12-20 09:56:44 -050057 time.sleep(CONF.compute.ready_wait)
Attila Fazekas0abbc952013-07-01 19:19:42 +020058 return
59 else:
60 return
61
62 time.sleep(client.build_interval)
Ken'ichi Ohmichi76800242015-07-03 05:12:31 +000063 body = client.show_server(server_id)
Attila Fazekas0abbc952013-07-01 19:19:42 +020064 server_status = body['status']
65 task_state = _get_task_state(body)
66 if (server_status != old_status) or (task_state != old_task_state):
67 LOG.info('State transition "%s" ==> "%s" after %d second wait',
68 '/'.join((old_status, str(old_task_state))),
69 '/'.join((server_status, str(task_state))),
70 time.time() - start_time)
Zhi Kun Liue5401762013-09-11 20:45:48 +080071 if (server_status == 'ERROR') and raise_on_error:
Attila Fazekas0462a7f2014-06-20 07:38:06 +020072 if 'fault' in body:
73 raise exceptions.BuildErrorException(body['fault'],
Matthew Treinish1d14c542014-06-17 20:25:40 -040074 server_id=server_id)
Attila Fazekas0462a7f2014-06-20 07:38:06 +020075 else:
76 raise exceptions.BuildErrorException(server_id=server_id)
Attila Fazekas0abbc952013-07-01 19:19:42 +020077
Ken'ichi Ohmichi39437e22013-10-06 00:21:38 +090078 timed_out = int(time.time()) - start_time >= timeout
Attila Fazekas0abbc952013-07-01 19:19:42 +020079
80 if timed_out:
Matt Riedemann629fa7c2013-12-11 18:20:56 -080081 expected_task_state = 'None' if ready_wait else 'n/a'
82 message = ('Server %(server_id)s failed to reach %(status)s '
83 'status and task state "%(expected_task_state)s" '
84 'within the required time (%(timeout)s s).' %
85 {'server_id': server_id,
86 'status': status,
87 'expected_task_state': expected_task_state,
88 'timeout': timeout})
Attila Fazekas0abbc952013-07-01 19:19:42 +020089 message += ' Current status: %s.' % server_status
Matt Riedemann629fa7c2013-12-11 18:20:56 -080090 message += ' Current task state: %s.' % task_state
Matt Riedemann128c23e2014-05-02 13:46:39 -070091 caller = misc_utils.find_test_caller()
92 if caller:
93 message = '(%s) %s' % (caller, message)
Attila Fazekas0abbc952013-07-01 19:19:42 +020094 raise exceptions.TimeoutException(message)
95 old_status = server_status
96 old_task_state = task_state
Matt Riedemannc00f3262013-12-14 12:03:55 -080097
98
99def wait_for_image_status(client, image_id, status):
100 """Waits for an image to reach a given status.
101
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000102 The client should have a show_image(image_id) method to get the image.
Matt Riedemannc00f3262013-12-14 12:03:55 -0800103 The client should also have build_interval and build_timeout attributes.
104 """
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000105 image = client.show_image(image_id)
Matt Riedemannc00f3262013-12-14 12:03:55 -0800106 start = int(time.time())
107
108 while image['status'] != status:
109 time.sleep(client.build_interval)
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000110 image = client.show_image(image_id)
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200111 status_curr = image['status']
112 if status_curr == 'ERROR':
Matt Riedemannc00f3262013-12-14 12:03:55 -0800113 raise exceptions.AddImageException(image_id=image_id)
114
115 # check the status again to avoid a false negative where we hit
116 # the timeout at the same time that the image reached the expected
117 # status
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200118 if status_curr == status:
Matt Riedemannc00f3262013-12-14 12:03:55 -0800119 return
120
121 if int(time.time()) - start >= client.build_timeout:
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200122 message = ('Image %(image_id)s failed to reach %(status)s state'
123 '(current state %(status_curr)s) '
124 'within the required time (%(timeout)s s).' %
Matt Riedemannc00f3262013-12-14 12:03:55 -0800125 {'image_id': image_id,
126 'status': status,
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200127 'status_curr': status_curr,
Matt Riedemannc00f3262013-12-14 12:03:55 -0800128 'timeout': client.build_timeout})
Matt Riedemann128c23e2014-05-02 13:46:39 -0700129 caller = misc_utils.find_test_caller()
130 if caller:
131 message = '(%s) %s' % (caller, message)
Matt Riedemannc00f3262013-12-14 12:03:55 -0800132 raise exceptions.TimeoutException(message)
Adam Gandelman00682612014-09-02 17:10:36 -0700133
134
135def wait_for_bm_node_status(client, node_id, attr, status):
136 """Waits for a baremetal node attribute to reach given status.
137
138 The client should have a show_node(node_uuid) method to get the node.
139 """
140 _, node = client.show_node(node_id)
141 start = int(time.time())
142
143 while node[attr] != status:
144 time.sleep(client.build_interval)
145 _, node = client.show_node(node_id)
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200146 status_curr = node[attr]
147 if status_curr == status:
Adam Gandelman00682612014-09-02 17:10:36 -0700148 return
149
150 if int(time.time()) - start >= client.build_timeout:
151 message = ('Node %(node_id)s failed to reach %(attr)s=%(status)s '
152 'within the required time (%(timeout)s s).' %
153 {'node_id': node_id,
154 'attr': attr,
155 'status': status,
156 'timeout': client.build_timeout})
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200157 message += ' Current state of %s: %s.' % (attr, status_curr)
Adam Gandelman00682612014-09-02 17:10:36 -0700158 caller = misc_utils.find_test_caller()
159 if caller:
160 message = '(%s) %s' % (caller, message)
161 raise exceptions.TimeoutException(message)