| Jude Cross | 986e3f5 | 2017-07-24 14:57:20 -0700 | [diff] [blame] | 1 | # Copyright 2017 GoDaddy | 
 | 2 | # Copyright 2017 Catalyst IT Ltd | 
 | 3 | # Copyright 2018 Rackspace US Inc.  All rights reserved. | 
 | 4 | # | 
 | 5 | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | 
 | 6 | #    not use this file except in compliance with the License. You may obtain | 
 | 7 | #    a copy of the License at | 
 | 8 | # | 
 | 9 | #         http://www.apache.org/licenses/LICENSE-2.0 | 
 | 10 | # | 
 | 11 | #    Unless required by applicable law or agreed to in writing, software | 
 | 12 | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
 | 13 | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
 | 14 | #    License for the specific language governing permissions and limitations | 
 | 15 | #    under the License. | 
 | 16 |  | 
 | 17 | import requests | 
 | 18 | import time | 
 | 19 |  | 
 | 20 | from oslo_log import log as logging | 
 | 21 | from tempest import config | 
 | 22 | from tempest.lib import exceptions | 
 | 23 |  | 
 | 24 | CONF = config.CONF | 
 | 25 | LOG = logging.getLogger(__name__) | 
 | 26 |  | 
 | 27 |  | 
 | 28 | def validate_URL_response(URL, expected_status_code=200, | 
 | 29 |                           expected_body=None, HTTPS_verify=True, | 
 | 30 |                           client_cert_path=None, CA_certs_path=None, | 
 | 31 |                           request_interval=CONF.load_balancer.build_interval, | 
 | 32 |                           request_timeout=CONF.load_balancer.build_timeout): | 
 | 33 |     """Check a URL response (HTTP or HTTPS). | 
 | 34 |  | 
 | 35 |     :param URL: The URL to query. | 
 | 36 |     :param expected_status_code: The expected HTTP status code. | 
 | 37 |     :param expected_body: The expected response text, None will not compare. | 
 | 38 |     :param HTTPS_verify: Should we verify the HTTPS server. | 
 | 39 |     :param client_cert_path: Filesystem path to a file with the client private | 
 | 40 |                              key and certificate. | 
 | 41 |     :param CA_certs_path: Filesystem path to a file containing CA certificates | 
 | 42 |                           to use for HTTPS validation. | 
 | 43 |     :param request_interval: Time, in seconds, to timeout a request. | 
 | 44 |     :param request_timeout: The maximum time, in seconds, to attempt requests. | 
 | 45 |                             Failed validation of expected results does not | 
 | 46 |                             result in a retry. | 
 | 47 |     :raises InvalidHttpSuccessCode: The expected_status_code did not match. | 
 | 48 |     :raises InvalidHTTPResponseBody: The response body did not match the | 
 | 49 |                                      expected content. | 
 | 50 |     :raises TimeoutException: The request timed out. | 
 | 51 |     :returns: None | 
 | 52 |     """ | 
 | 53 |     with requests.Session() as session: | 
 | 54 |         session_kwargs = {} | 
 | 55 |         if not HTTPS_verify: | 
 | 56 |             session_kwargs['verify'] = False | 
 | 57 |         if CA_certs_path: | 
 | 58 |             session_kwargs['verify'] = CA_certs_path | 
 | 59 |         if client_cert_path: | 
 | 60 |             session_kwargs['cert'] = client_cert_path | 
 | 61 |         session_kwargs['timeout'] = request_interval | 
 | 62 |         start = time.time() | 
 | 63 |         while time.time() - start < request_timeout: | 
 | 64 |             try: | 
 | 65 |                 response = session.get(URL, **session_kwargs) | 
 | 66 |                 if response.status_code != expected_status_code: | 
 | 67 |                     raise exceptions.InvalidHttpSuccessCode( | 
 | 68 |                         '{0} is not the expected code {1}'.format( | 
 | 69 |                             response.status_code, expected_status_code)) | 
 | 70 |                 if expected_body and response.text != expected_body: | 
 | 71 |                     details = '{} does not match expected {}'.format( | 
 | 72 |                         response.text, expected_body) | 
 | 73 |                     raise exceptions.InvalidHTTPResponseBody( | 
 | 74 |                         resp_body=details) | 
 | 75 |                 return | 
 | 76 |             except requests.exceptions.Timeout: | 
 | 77 |                 # Don't sleep as we have already waited the interval. | 
| Jonathan Rosser | 7654d2e | 2019-06-24 14:55:17 +0100 | [diff] [blame] | 78 |                 LOG.info('Request for {} timed out. Retrying.'.format(URL)) | 
| Jude Cross | 986e3f5 | 2017-07-24 14:57:20 -0700 | [diff] [blame] | 79 |             except (exceptions.InvalidHttpSuccessCode, | 
 | 80 |                     exceptions.InvalidHTTPResponseBody, | 
 | 81 |                     requests.exceptions.SSLError): | 
 | 82 |                 raise | 
 | 83 |             except Exception as e: | 
 | 84 |                 LOG.info('Validate URL got exception: {0}. ' | 
 | 85 |                          'Retrying.'.format(e)) | 
 | 86 |                 time.sleep(request_interval) | 
 | 87 |         raise exceptions.TimeoutException() |