175 lines
7.3 KiB
Python
175 lines
7.3 KiB
Python
# Copyright 2017 GoDaddy
|
|
# Copyright 2018 Rackspace US Inc. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import time
|
|
|
|
from oslo_log import log as logging
|
|
from tempest import config
|
|
from tempest.lib.common.utils import test_utils
|
|
from tempest.lib import exceptions
|
|
|
|
from octavia_tempest_plugin.common import constants as const
|
|
|
|
CONF = config.CONF
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def wait_for_status(show_client, id, status_key, status,
|
|
check_interval, check_timeout, root_tag=None):
|
|
"""Waits for an object to reach a specific status.
|
|
|
|
:param show_client: The tempest service client show method.
|
|
Ex. cls.os_primary.servers_client.show_server
|
|
:param id: The id of the object to query.
|
|
:param status_key: The key of the status field in the response.
|
|
Ex. provisioning_status
|
|
:param status: The status to wait for. Ex. "ACTIVE"
|
|
:check_interval: How often to check the status, in seconds.
|
|
:check_timeout: The maximum time, in seconds, to check the status.
|
|
:root_tag: The root tag on the response to remove, if any.
|
|
:raises CommandFailed: Raised if the object goes into ERROR and ERROR was
|
|
not the desired status.
|
|
:raises TimeoutException: The object did not achieve the status or ERROR in
|
|
the check_timeout period.
|
|
:returns: The object details from the show client.
|
|
"""
|
|
start = int(time.time())
|
|
LOG.info('Waiting for {name} status to update to {status}'.format(
|
|
name=show_client.__name__, status=status))
|
|
while True:
|
|
response = show_client(id)
|
|
if root_tag:
|
|
object_details = response[root_tag]
|
|
else:
|
|
object_details = response
|
|
|
|
if object_details[status_key] == status:
|
|
LOG.info('{name}\'s status updated to {status}.'.format(
|
|
name=show_client.__name__, status=status))
|
|
return object_details
|
|
elif object_details[status_key] == 'ERROR':
|
|
message = ('{name} {field} updated to an invalid state of '
|
|
'ERROR'.format(name=show_client.__name__,
|
|
field=status_key))
|
|
caller = test_utils.find_test_caller()
|
|
if caller:
|
|
message = '({caller}) {message}'.format(caller=caller,
|
|
message=message)
|
|
raise exceptions.UnexpectedResponseCode(message)
|
|
elif int(time.time()) - start >= check_timeout:
|
|
message = (
|
|
'{name} {field} failed to update to {expected_status} within '
|
|
'the required time {timeout}. Current status of {name}: '
|
|
'{status}'.format(
|
|
name=show_client.__name__,
|
|
timeout=check_timeout,
|
|
status=object_details[status_key],
|
|
expected_status=status,
|
|
field=status_key
|
|
))
|
|
caller = test_utils.find_test_caller()
|
|
if caller:
|
|
message = '({caller}) {message}'.format(caller=caller,
|
|
message=message)
|
|
raise exceptions.TimeoutException(message)
|
|
|
|
time.sleep(check_interval)
|
|
|
|
|
|
def wait_for_not_found(delete_func, show_func, *args, **kwargs):
|
|
"""Call the delete function, then wait for it to be 'NotFound'
|
|
|
|
:param delete_func: The delete function to call.
|
|
:param show_func: The show function to call looking for 'NotFound'.
|
|
:param ID: The ID of the object to delete/show.
|
|
:raises TimeoutException: The object did not achieve the status or ERROR in
|
|
the check_timeout period.
|
|
:returns: None
|
|
"""
|
|
try:
|
|
return delete_func(*args, **kwargs)
|
|
except exceptions.NotFound:
|
|
return
|
|
start = int(time.time())
|
|
LOG.info('Waiting for object to be NotFound')
|
|
while True:
|
|
try:
|
|
show_func(*args, **kwargs)
|
|
except exceptions.NotFound:
|
|
return
|
|
if int(time.time()) - start >= CONF.load_balancer.check_timeout:
|
|
message = ('{name} did not raise NotFound in {timeout} '
|
|
'seconds.'.format(
|
|
name=show_func.__name__,
|
|
timeout=CONF.load_balancer.check_timeout))
|
|
raise exceptions.TimeoutException(message)
|
|
time.sleep(CONF.load_balancer.check_interval)
|
|
|
|
|
|
def wait_for_deleted_status_or_not_found(
|
|
show_client, id, status_key, check_interval, check_timeout,
|
|
root_tag=None):
|
|
"""Waits for an object to reach a DELETED status or be not found (404).
|
|
|
|
:param show_client: The tempest service client show method.
|
|
Ex. cls.os_primary.servers_client.show_server
|
|
:param id: The id of the object to query.
|
|
:param status_key: The key of the status field in the response.
|
|
Ex. provisioning_status
|
|
:check_interval: How often to check the status, in seconds.
|
|
:check_timeout: The maximum time, in seconds, to check the status.
|
|
:root_tag: The root tag on the response to remove, if any.
|
|
:raises CommandFailed: Raised if the object goes into ERROR and ERROR was
|
|
not the desired status.
|
|
:raises TimeoutException: The object did not achieve the status or ERROR in
|
|
the check_timeout period.
|
|
:returns: None
|
|
"""
|
|
start = int(time.time())
|
|
LOG.info('Waiting for {name} status to update to DELETED or be not '
|
|
'found(404)'.format(name=show_client.__name__))
|
|
while True:
|
|
try:
|
|
response = show_client(id)
|
|
except exceptions.NotFound:
|
|
return
|
|
|
|
if root_tag:
|
|
object_details = response[root_tag]
|
|
else:
|
|
object_details = response
|
|
|
|
if object_details[status_key] == const.DELETED:
|
|
LOG.info('{name}\'s status updated to DELETED.'.format(
|
|
name=show_client.__name__))
|
|
return
|
|
elif int(time.time()) - start >= check_timeout:
|
|
message = (
|
|
'{name} {field} failed to update to DELETED or become not '
|
|
'found (404) within the required time {timeout}. Current '
|
|
'status of {name}: {status}'.format(
|
|
name=show_client.__name__,
|
|
timeout=check_timeout,
|
|
status=object_details[status_key],
|
|
field=status_key
|
|
))
|
|
caller = test_utils.find_test_caller()
|
|
if caller:
|
|
message = '({caller}) {message}'.format(caller=caller,
|
|
message=message)
|
|
raise exceptions.TimeoutException(message)
|
|
|
|
time.sleep(check_interval)
|