blob: 7825782d923b6215cba86db8da27494c529fc841 [file] [log] [blame]
Jude Cross986e3f52017-07-24 14:57:20 -07001# Copyright 2017 GoDaddy
2# Copyright 2018 Rackspace US Inc. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import time
17
18from oslo_log import log as logging
19from tempest import config
20from tempest.lib.common.utils import test_utils
21from tempest.lib import exceptions
22
23from octavia_tempest_plugin.common import constants as const
24
25CONF = config.CONF
26LOG = logging.getLogger(__name__)
27
28
29def wait_for_status(show_client, id, status_key, status,
30 check_interval, check_timeout, root_tag=None):
31 """Waits for an object to reach a specific status.
32
33 :param show_client: The tempest service client show method.
34 Ex. cls.os_primary.servers_client.show_server
35 :param id: The id of the object to query.
36 :param status_key: The key of the status field in the response.
37 Ex. provisioning_status
38 :param status: The status to wait for. Ex. "ACTIVE"
39 :check_interval: How often to check the status, in seconds.
40 :check_timeout: The maximum time, in seconds, to check the status.
41 :root_tag: The root tag on the response to remove, if any.
42 :raises CommandFailed: Raised if the object goes into ERROR and ERROR was
43 not the desired status.
44 :raises TimeoutException: The object did not achieve the status or ERROR in
45 the check_timeout period.
46 :returns: The object details from the show client.
47 """
48 start = int(time.time())
49 LOG.info('Waiting for {name} status to update to {status}'.format(
50 name=show_client.__name__, status=status))
51 while True:
52 response = show_client(id)
53 if root_tag:
54 object_details = response[root_tag]
55 else:
56 object_details = response
57
58 if object_details[status_key] == status:
59 LOG.info('{name}\'s status updated to {status}.'.format(
60 name=show_client.__name__, status=status))
61 return object_details
62 elif object_details[status_key] == 'ERROR':
63 message = ('{name} {field} updated to an invalid state of '
64 'ERROR'.format(name=show_client.__name__,
65 field=status_key))
66 caller = test_utils.find_test_caller()
67 if caller:
68 message = '({caller}) {message}'.format(caller=caller,
69 message=message)
70 raise exceptions.UnexpectedResponseCode(message)
71 elif int(time.time()) - start >= check_timeout:
72 message = (
73 '{name} {field} failed to update to {expected_status} within '
74 'the required time {timeout}. Current status of {name}: '
75 '{status}'.format(
76 name=show_client.__name__,
77 timeout=check_timeout,
78 status=object_details[status_key],
79 expected_status=status,
80 field=status_key
81 ))
82 caller = test_utils.find_test_caller()
83 if caller:
84 message = '({caller}) {message}'.format(caller=caller,
85 message=message)
86 raise exceptions.TimeoutException(message)
87
88 time.sleep(check_interval)
89
90
91def wait_for_not_found(delete_func, show_func, *args, **kwargs):
92 """Call the delete function, then wait for it to be 'NotFound'
93
94 :param delete_func: The delete function to call.
95 :param show_func: The show function to call looking for 'NotFound'.
96 :param ID: The ID of the object to delete/show.
97 :raises TimeoutException: The object did not achieve the status or ERROR in
98 the check_timeout period.
99 :returns: None
100 """
101 try:
102 return delete_func(*args, **kwargs)
103 except exceptions.NotFound:
104 return
105 start = int(time.time())
106 LOG.info('Waiting for object to be NotFound')
107 while True:
108 try:
109 show_func(*args, **kwargs)
110 except exceptions.NotFound:
111 return
112 if int(time.time()) - start >= CONF.load_balancer.check_timeout:
113 message = ('{name} did not raise NotFound in {timeout} '
114 'seconds.'.format(
115 name=show_func.__name__,
116 timeout=CONF.load_balancer.check_timeout))
117 raise exceptions.TimeoutException(message)
118 time.sleep(CONF.load_balancer.check_interval)
119
120
121def wait_for_deleted_status_or_not_found(
122 show_client, id, status_key, check_interval, check_timeout,
123 root_tag=None):
124 """Waits for an object to reach a DELETED status or be not found (404).
125
126 :param show_client: The tempest service client show method.
127 Ex. cls.os_primary.servers_client.show_server
128 :param id: The id of the object to query.
129 :param status_key: The key of the status field in the response.
130 Ex. provisioning_status
131 :check_interval: How often to check the status, in seconds.
132 :check_timeout: The maximum time, in seconds, to check the status.
133 :root_tag: The root tag on the response to remove, if any.
134 :raises CommandFailed: Raised if the object goes into ERROR and ERROR was
135 not the desired status.
136 :raises TimeoutException: The object did not achieve the status or ERROR in
137 the check_timeout period.
138 :returns: None
139 """
140 start = int(time.time())
141 LOG.info('Waiting for {name} status to update to DELETED or be not '
142 'found(404)'.format(name=show_client.__name__))
143 while True:
144 try:
145 response = show_client(id)
146 except exceptions.NotFound:
147 return
148
149 if root_tag:
150 object_details = response[root_tag]
151 else:
152 object_details = response
153
154 if object_details[status_key] == const.DELETED:
155 LOG.info('{name}\'s status updated to DELETED.'.format(
156 name=show_client.__name__))
157 return
158 elif int(time.time()) - start >= check_timeout:
159 message = (
160 '{name} {field} failed to update to DELETED or become not '
161 'found (404) within the required time {timeout}. Current '
162 'status of {name}: {status}'.format(
163 name=show_client.__name__,
164 timeout=check_timeout,
165 status=object_details[status_key],
166 field=status_key
167 ))
168 caller = test_utils.find_test_caller()
169 if caller:
170 message = '({caller}) {message}'.format(caller=caller,
171 message=message)
172 raise exceptions.TimeoutException(message)
173
174 time.sleep(check_interval)