21931edd79
Use 'requests' module for HTTP requests to TestRail
and Jenkins API instead of 'urllib'. It provides a
method which decode response data using proper
character encoding (charset from headers) and returns
unicode string.
Also add one more environment variable to settings,
because it's needed by proboscis for test plan
generation (since I9b9d40a59d24f579502a38dfc9b8c142bc219a06
was merged).
Closes-bug: #1584401
Change-Id: I3d6cde2c8066bd58e735142fe26d56e83d1c90de
(cherry picked from commit 5072b8426c
)
116 lines
3.6 KiB
Python
116 lines
3.6 KiB
Python
# Copyright 2015 Mirantis, Inc.
|
|
#
|
|
# 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.
|
|
#
|
|
# TestRail API binding for Python 2.x (API v2, available since
|
|
# TestRail 3.0)
|
|
#
|
|
# Learn more:
|
|
#
|
|
# http://docs.gurock.com/testrail-api2/start
|
|
# http://docs.gurock.com/testrail-api2/accessing
|
|
#
|
|
# Copyright Gurock Software GmbH. See license.md for details.
|
|
#
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import base64
|
|
import time
|
|
|
|
import requests
|
|
from requests.exceptions import HTTPError
|
|
from requests.packages.urllib3 import disable_warnings
|
|
|
|
from fuelweb_test.testrail.settings import logger
|
|
|
|
|
|
disable_warnings()
|
|
|
|
|
|
def request_retry(codes):
|
|
log_msg = "Got {0} Error! Waiting {1} seconds and trying again..."
|
|
|
|
def retry_request(func):
|
|
def wrapper(*args, **kwargs):
|
|
iter_number = 0
|
|
while True:
|
|
try:
|
|
response = func(*args, **kwargs)
|
|
response.raise_for_status()
|
|
except HTTPError as e:
|
|
error_code = e.response.status_code
|
|
if error_code in codes:
|
|
if iter_number < codes[error_code]:
|
|
wait = 5
|
|
if 'Retry-After' in e.response.headers:
|
|
wait = int(e.response.headers['Retry-after'])
|
|
logger.debug(log_msg.format(error_code, wait))
|
|
time.sleep(wait)
|
|
iter_number += 1
|
|
continue
|
|
raise
|
|
else:
|
|
return response.json()
|
|
return wrapper
|
|
return retry_request
|
|
|
|
|
|
class APIClient(object):
|
|
"""APIClient.""" # TODO documentation
|
|
|
|
def __init__(self, base_url):
|
|
self.user = ''
|
|
self.password = ''
|
|
if not base_url.endswith('/'):
|
|
base_url += '/'
|
|
self.__url = base_url + 'index.php?/api/v2/'
|
|
|
|
def send_get(self, uri):
|
|
return self.__send_request('GET', uri, None)
|
|
|
|
def send_post(self, uri, data):
|
|
return self.__send_request('POST', uri, data)
|
|
|
|
def __send_request(self, method, uri, data):
|
|
retry_codes = {429: 3}
|
|
|
|
@request_retry(codes=retry_codes)
|
|
def __get_response(_url, _headers, _data):
|
|
if method == 'POST':
|
|
return requests.post(_url, json=_data, headers=_headers)
|
|
return requests.get(_url, headers=_headers)
|
|
|
|
url = self.__url + uri
|
|
|
|
auth = base64.encodestring(
|
|
'{0}:{1}'.format(self.user, self.password)).strip()
|
|
|
|
headers = {'Authorization': 'Basic {}'.format(auth),
|
|
'Content-Type': 'application/json'}
|
|
|
|
try:
|
|
return __get_response(url, headers, data)
|
|
except HTTPError as e:
|
|
if e.message:
|
|
error = e.message
|
|
else:
|
|
error = 'No additional error message received'
|
|
raise APIError('TestRail API returned HTTP {0}: "{1}"'.format(
|
|
e.response.status_code, error))
|
|
|
|
|
|
class APIError(Exception):
|
|
"""APIError.""" # TODO documentation
|
|
pass
|