Merge "Migration to using requests"
This commit is contained in:
commit
7166e97eb2
@ -46,7 +46,6 @@
|
||||
See examples at :doc:`examples`
|
||||
'''
|
||||
|
||||
import base64
|
||||
import json
|
||||
import re
|
||||
import socket
|
||||
@ -55,24 +54,18 @@ import time
|
||||
import warnings
|
||||
|
||||
import multi_key_dict
|
||||
import six
|
||||
import requests
|
||||
import requests.exceptions as req_exc
|
||||
from six.moves.http_client import BadStatusLine
|
||||
from six.moves.urllib.error import HTTPError
|
||||
from six.moves.urllib.error import URLError
|
||||
from six.moves.urllib.parse import quote, urlencode, urljoin, urlparse
|
||||
from six.moves.urllib.request import Request, install_opener, build_opener, urlopen
|
||||
|
||||
from jenkins import plugins
|
||||
|
||||
try:
|
||||
import kerberos
|
||||
assert kerberos # pyflakes
|
||||
from jenkins import urllib_kerb
|
||||
opener = build_opener()
|
||||
opener.add_handler(urllib_kerb.HTTPNegotiateHandler())
|
||||
install_opener(opener)
|
||||
import requests_kerberos
|
||||
except ImportError:
|
||||
pass
|
||||
requests_kerberos = None
|
||||
|
||||
|
||||
if sys.version_info < (2, 7, 0):
|
||||
@ -240,17 +233,6 @@ class TimeoutException(JenkinsException):
|
||||
'''A special exception to call out in the case of a socket timeout.'''
|
||||
|
||||
|
||||
def auth_headers(username, password):
|
||||
'''Simple implementation of HTTP Basic Authentication.
|
||||
|
||||
Returns the 'Authentication' header value.
|
||||
'''
|
||||
auth = '%s:%s' % (username, password)
|
||||
if isinstance(auth, six.text_type):
|
||||
auth = auth.encode('utf-8')
|
||||
return b'Basic ' + base64.b64encode(auth)
|
||||
|
||||
|
||||
class Jenkins(object):
|
||||
_timeout_warning_issued = False
|
||||
|
||||
@ -269,12 +251,25 @@ class Jenkins(object):
|
||||
self.server = url
|
||||
else:
|
||||
self.server = url + '/'
|
||||
|
||||
self._auths = [('anonymous', None)]
|
||||
self._auth_resolved = False
|
||||
if username is not None and password is not None:
|
||||
self.auth = auth_headers(username, password)
|
||||
else:
|
||||
self.auth = None
|
||||
self._auths[0] = (
|
||||
'basic',
|
||||
requests.auth.HTTPBasicAuth(
|
||||
username.encode('utf-8'), password.encode('utf-8'))
|
||||
)
|
||||
|
||||
if requests_kerberos is not None:
|
||||
self._auths.append(
|
||||
('kerberos', requests_kerberos.HTTPKerberosAuth())
|
||||
)
|
||||
|
||||
self.auth = None
|
||||
self.crumb = None
|
||||
self.timeout = timeout
|
||||
self._session = requests.Session()
|
||||
|
||||
def _get_encoded_params(self, params):
|
||||
for k, v in params.items():
|
||||
@ -296,14 +291,48 @@ class Jenkins(object):
|
||||
# We don't know yet whether we need a crumb
|
||||
if self.crumb is None:
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(CRUMB_URL)), add_crumb=False)
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(CRUMB_URL)), add_crumb=False)
|
||||
except (NotFoundException, EmptyResponseException):
|
||||
self.crumb = False
|
||||
else:
|
||||
self.crumb = json.loads(response)
|
||||
if self.crumb:
|
||||
req.add_header(self.crumb['crumbRequestField'], self.crumb['crumb'])
|
||||
req.headers[self.crumb['crumbRequestField']] = self.crumb['crumb']
|
||||
|
||||
def _maybe_add_auth(self):
|
||||
|
||||
if self._auth_resolved:
|
||||
return
|
||||
|
||||
if len(self._auths) == 1:
|
||||
# If we only have one auth mechanism specified, just require it
|
||||
self._session.auth = self._auths[0][1]
|
||||
else:
|
||||
# Attempt the list of auth mechanisms and keep the first that works
|
||||
# otherwise default to the first one in the list (last popped).
|
||||
# This is a hack to allow the transparent use of kerberos to work
|
||||
# in future, we should require explicit request to use kerberos
|
||||
failures = []
|
||||
for name, auth in reversed(self._auths):
|
||||
try:
|
||||
self.jenkins_open(
|
||||
requests.Request('GET', self._build_url(INFO),
|
||||
auth=auth),
|
||||
add_crumb=False, resolve_auth=False)
|
||||
self._session.auth = auth
|
||||
break
|
||||
except Exception as exc:
|
||||
# assume authentication failure
|
||||
failures.append("auth(%s) %s" % (name, exc))
|
||||
continue
|
||||
else:
|
||||
raise JenkinsException(
|
||||
'Unable to authenticate with any scheme:\n%s'
|
||||
% '\n'.join(failures))
|
||||
|
||||
self._auth_resolved = True
|
||||
self.auth = self._session.auth
|
||||
|
||||
def _add_missing_builds(self, data):
|
||||
"""Query Jenkins to get all builds of a job.
|
||||
@ -327,8 +356,9 @@ class Jenkins(object):
|
||||
if all_builds_loaded:
|
||||
return data
|
||||
folder_url, short_name = self._get_job_folder(data["name"])
|
||||
response = self.jenkins_open(Request(self._build_url(ALL_BUILDS,
|
||||
locals())))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(ALL_BUILDS, locals())
|
||||
))
|
||||
if response:
|
||||
data["builds"] = json.loads(response)["allBuilds"]
|
||||
else:
|
||||
@ -352,8 +382,8 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(JOB_INFO, locals())
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(JOB_INFO, locals())
|
||||
))
|
||||
if response:
|
||||
if fetch_all_builds:
|
||||
@ -362,7 +392,7 @@ class Jenkins(object):
|
||||
return json.loads(response)
|
||||
else:
|
||||
raise JenkinsException('job[%s] does not exist' % name)
|
||||
except HTTPError:
|
||||
except (req_exc.HTTPError, NotFoundException):
|
||||
raise JenkinsException('job[%s] does not exist' % name)
|
||||
except ValueError:
|
||||
raise JenkinsException(
|
||||
@ -397,8 +427,8 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(JOB_NAME, locals())
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(JOB_NAME, locals())
|
||||
))
|
||||
except NotFoundException:
|
||||
return None
|
||||
@ -415,40 +445,57 @@ class Jenkins(object):
|
||||
for k, v in self.get_job_info(job_name).items():
|
||||
print(k, v)
|
||||
|
||||
def jenkins_open(self, req, add_crumb=True):
|
||||
def _response_handler(self, response):
|
||||
'''Handle response objects'''
|
||||
|
||||
# raise exceptions if occurred
|
||||
response.raise_for_status()
|
||||
|
||||
headers = response.headers
|
||||
if (headers.get('content-length') is None and
|
||||
headers.get('transfer-encoding') is None):
|
||||
# response body should only exist if one of these is provided
|
||||
raise EmptyResponseException(
|
||||
"Error communicating with server[%s]: "
|
||||
"empty response" % self.server)
|
||||
|
||||
# Reponse objects will automatically return unicode encoded
|
||||
# when accessing .text property
|
||||
return response
|
||||
|
||||
def _request(self, req):
|
||||
|
||||
r = self._session.prepare_request(req)
|
||||
return self._session.send(r, timeout=self.timeout)
|
||||
|
||||
def jenkins_open(self, req, add_crumb=True, resolve_auth=True):
|
||||
'''Utility routine for opening an HTTP request to a Jenkins server.
|
||||
|
||||
This should only be used to extends the :class:`Jenkins` API.
|
||||
'''
|
||||
try:
|
||||
if self.auth:
|
||||
req.add_header('Authorization', self.auth)
|
||||
if resolve_auth:
|
||||
self._maybe_add_auth()
|
||||
if add_crumb:
|
||||
self.maybe_add_crumb(req)
|
||||
response = urlopen(req, timeout=self.timeout).read()
|
||||
if response is None:
|
||||
raise EmptyResponseException(
|
||||
"Error communicating with server[%s]: "
|
||||
"empty response" % self.server)
|
||||
return response.decode('utf-8')
|
||||
except HTTPError as e:
|
||||
|
||||
return self._response_handler(
|
||||
self._request(req)).text
|
||||
|
||||
except req_exc.HTTPError as e:
|
||||
# Jenkins's funky authentication means its nigh impossible to
|
||||
# distinguish errors.
|
||||
if e.code in [401, 403, 500]:
|
||||
# six.moves.urllib.error.HTTPError provides a 'reason'
|
||||
# attribute for all python version except for ver 2.6
|
||||
# Falling back to HTTPError.msg since it contains the
|
||||
# same info as reason
|
||||
if e.response.status_code in [401, 403, 500]:
|
||||
raise JenkinsException(
|
||||
'Error in request. ' +
|
||||
'Possibly authentication failed [%s]: %s' % (
|
||||
e.code, e.msg)
|
||||
e.response.status_code, e.response.reason)
|
||||
)
|
||||
elif e.code == 404:
|
||||
elif e.response.status_code == 404:
|
||||
raise NotFoundException('Requested item could not be found')
|
||||
else:
|
||||
raise
|
||||
except socket.timeout as e:
|
||||
except req_exc.Timeout as e:
|
||||
raise TimeoutException('Error in request: %s' % (e))
|
||||
except URLError as e:
|
||||
# python 2.6 compatibility to ensure same exception raised
|
||||
@ -476,15 +523,15 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(BUILD_INFO, locals())
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(BUILD_INFO, locals())
|
||||
))
|
||||
if response:
|
||||
return json.loads(response)
|
||||
else:
|
||||
raise JenkinsException('job[%s] number[%d] does not exist'
|
||||
% (name, number))
|
||||
except HTTPError:
|
||||
except (req_exc.HTTPError, NotFoundException):
|
||||
raise JenkinsException('job[%s] number[%d] does not exist'
|
||||
% (name, number))
|
||||
except ValueError:
|
||||
@ -502,7 +549,7 @@ class Jenkins(object):
|
||||
{u'task': {u'url': u'http://your_url/job/my_job/', u'color': u'aborted_anime', u'name': u'my_job'}, u'stuck': False, u'actions': [{u'causes': [{u'shortDescription': u'Started by timer'}]}], u'buildable': False, u'params': u'', u'buildableStartMilliseconds': 1315087293316, u'why': u'Build #2,532 is already in progress (ETA:10 min)', u'blocked': True}
|
||||
'''
|
||||
return json.loads(self.jenkins_open(
|
||||
Request(self._build_url(Q_INFO))
|
||||
requests.Request('GET', self._build_url(Q_INFO))
|
||||
))['items']
|
||||
|
||||
def cancel_queue(self, id):
|
||||
@ -514,8 +561,9 @@ class Jenkins(object):
|
||||
# https://issues.jenkins-ci.org/browse/JENKINS-21311
|
||||
try:
|
||||
self.jenkins_open(
|
||||
Request(self._build_url(CANCEL_QUEUE, locals()), b'',
|
||||
headers={'Referer': self.server}))
|
||||
requests.Request(
|
||||
'POST', self._build_url(CANCEL_QUEUE, locals()),
|
||||
headers={'Referer': self.server}))
|
||||
except NotFoundException:
|
||||
# Exception is expected; cancel_queue() is a best-effort
|
||||
# mechanism, so ignore it
|
||||
@ -546,9 +594,9 @@ class Jenkins(object):
|
||||
url += query
|
||||
try:
|
||||
return json.loads(self.jenkins_open(
|
||||
Request(self._build_url(url))
|
||||
requests.Request('GET', self._build_url(INFO))
|
||||
))
|
||||
except (HTTPError, BadStatusLine):
|
||||
except (req_exc.HTTPError, BadStatusLine):
|
||||
raise BadHTTPException("Error communicating with server[%s]"
|
||||
% self.server)
|
||||
except ValueError:
|
||||
@ -570,7 +618,9 @@ class Jenkins(object):
|
||||
|
||||
"""
|
||||
try:
|
||||
response = self.jenkins_open(Request(self._build_url(WHOAMI_URL)))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(WHOAMI_URL)
|
||||
))
|
||||
if response is None:
|
||||
raise EmptyResponseException(
|
||||
"Error communicating with server[%s]: "
|
||||
@ -578,7 +628,7 @@ class Jenkins(object):
|
||||
|
||||
return json.loads(response)
|
||||
|
||||
except (HTTPError, BadStatusLine):
|
||||
except (req_exc.HTTPError, BadStatusLine):
|
||||
raise BadHTTPException("Error communicating with server[%s]"
|
||||
% self.server)
|
||||
|
||||
@ -595,21 +645,13 @@ class Jenkins(object):
|
||||
|
||||
"""
|
||||
try:
|
||||
request = Request(self._build_url(''))
|
||||
request.add_header('X-Jenkins', '0.0')
|
||||
response = urlopen(request, timeout=self.timeout)
|
||||
if response is None:
|
||||
raise EmptyResponseException(
|
||||
"Error communicating with server[%s]: "
|
||||
"empty response" % self.server)
|
||||
request = requests.Request('GET', self._build_url(''))
|
||||
request.headers['X-Jenkins'] = '0.0'
|
||||
response = self._response_handler(self._request(request))
|
||||
|
||||
if six.PY2:
|
||||
return response.info().getheader('X-Jenkins')
|
||||
return response.headers['X-Jenkins']
|
||||
|
||||
if six.PY3:
|
||||
return response.getheader('X-Jenkins')
|
||||
|
||||
except (HTTPError, BadStatusLine):
|
||||
except (req_exc.HTTPError, BadStatusLine):
|
||||
raise BadHTTPException("Error communicating with server[%s]"
|
||||
% self.server)
|
||||
|
||||
@ -711,8 +753,8 @@ class Jenkins(object):
|
||||
|
||||
try:
|
||||
plugins_info_json = json.loads(self.jenkins_open(
|
||||
Request(self._build_url(PLUGIN_INFO, locals()))))
|
||||
except (HTTPError, BadStatusLine):
|
||||
requests.Request('GET', self._build_url(PLUGIN_INFO, locals()))))
|
||||
except (req_exc.HTTPError, BadStatusLine):
|
||||
raise BadHTTPException("Error communicating with server[%s]"
|
||||
% self.server)
|
||||
except ValueError:
|
||||
@ -758,7 +800,7 @@ class Jenkins(object):
|
||||
"""
|
||||
|
||||
if view_name:
|
||||
return self._get_view_jobs(view_name=view_name)
|
||||
return self._get_view_jobs(name=view_name)
|
||||
else:
|
||||
return self.get_all_jobs(folder_depth=folder_depth)
|
||||
|
||||
@ -848,8 +890,9 @@ class Jenkins(object):
|
||||
raise JenkinsException('copy[%s to %s] failed, source and destination '
|
||||
'folder must be the same' % (from_name, to_name))
|
||||
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(COPY_JOB, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(COPY_JOB, locals())
|
||||
))
|
||||
self.assert_job_exists(to_name, 'create[%s] failed')
|
||||
|
||||
def rename_job(self, from_name, to_name):
|
||||
@ -868,8 +911,9 @@ class Jenkins(object):
|
||||
if from_folder_url != to_folder_url:
|
||||
raise JenkinsException('rename[%s to %s] failed, source and destination folder '
|
||||
'must be the same' % (from_name, to_name))
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(RENAME_JOB, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(RENAME_JOB, locals())
|
||||
))
|
||||
self.assert_job_exists(to_name, 'rename[%s] failed')
|
||||
|
||||
def delete_job(self, name):
|
||||
@ -878,8 +922,9 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins job, ``str``
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(DELETE_JOB, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(DELETE_JOB, locals())
|
||||
))
|
||||
if self.job_exists(name):
|
||||
raise JenkinsException('delete[%s] failed' % (name))
|
||||
|
||||
@ -889,8 +934,9 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins job, ``str``
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(ENABLE_JOB, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(ENABLE_JOB, locals())
|
||||
))
|
||||
|
||||
def disable_job(self, name):
|
||||
'''Disable Jenkins job.
|
||||
@ -900,8 +946,9 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins job, ``str``
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(DISABLE_JOB, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(DISABLE_JOB, locals())
|
||||
))
|
||||
|
||||
def set_next_build_number(self, name, number):
|
||||
'''Set a job's next build number.
|
||||
@ -924,9 +971,9 @@ class Jenkins(object):
|
||||
>>> server.set_next_build_number('job_name', next_bn + 50)
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
self.jenkins_open(
|
||||
Request(self._build_url(SET_JOB_BUILD_NUMBER, locals()),
|
||||
("nextBuildNumber=%d" % number).encode('utf-8')))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(SET_JOB_BUILD_NUMBER, locals()),
|
||||
data=("nextBuildNumber=%d" % number).encode('utf-8')))
|
||||
|
||||
def job_exists(self, name):
|
||||
'''Check whether a job exists
|
||||
@ -984,9 +1031,11 @@ class Jenkins(object):
|
||||
raise JenkinsException('job[%s] already exists' % (name))
|
||||
|
||||
try:
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(CREATE_JOB, locals()),
|
||||
config_xml.encode('utf-8'), DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(CREATE_JOB, locals()),
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
except NotFoundException:
|
||||
raise JenkinsException('Cannot create job[%s] because folder '
|
||||
'for the job does not exist' % (name))
|
||||
@ -999,7 +1048,7 @@ class Jenkins(object):
|
||||
:returns: job configuration (XML format)
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
request = Request(self._build_url(CONFIG_JOB, locals()))
|
||||
request = requests.Request('GET', self._build_url(CONFIG_JOB, locals()))
|
||||
return self.jenkins_open(request)
|
||||
|
||||
def reconfig_job(self, name, config_xml):
|
||||
@ -1012,8 +1061,11 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
reconfig_url = self._build_url(CONFIG_JOB, locals())
|
||||
self.jenkins_open(Request(reconfig_url, config_xml.encode('utf-8'),
|
||||
DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', reconfig_url,
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
|
||||
def build_job_url(self, name, parameters=None, token=None):
|
||||
'''Get URL to trigger build job.
|
||||
@ -1044,8 +1096,8 @@ class Jenkins(object):
|
||||
:param parameters: parameters for job, or ``None``, ``dict``
|
||||
:param token: Jenkins API token
|
||||
'''
|
||||
return self.jenkins_open(Request(
|
||||
self.build_job_url(name, parameters, token), b''))
|
||||
return self.jenkins_open(requests.Request(
|
||||
'POST', self.build_job_url(name, parameters, token)))
|
||||
|
||||
def run_script(self, script):
|
||||
'''Execute a groovy script on the jenkins master.
|
||||
@ -1061,8 +1113,10 @@ class Jenkins(object):
|
||||
Plugin:mailer, Plugin:jquery, Plugin:antisamy-markup-formatter,
|
||||
Plugin:maven-plugin, Plugin:pam-auth]'
|
||||
'''
|
||||
return self.jenkins_open(Request(self._build_url(SCRIPT_TEXT),
|
||||
"script=".encode('utf-8') + quote(script).encode('utf-8')))
|
||||
return self.jenkins_open(
|
||||
requests.Request(
|
||||
'POST', self._build_url(SCRIPT_TEXT),
|
||||
data="script=".encode('utf-8') + quote(script).encode('utf-8')))
|
||||
|
||||
def install_plugin(self, name, include_dependencies=True):
|
||||
'''Install a plugin and its dependencies from the Jenkins public
|
||||
@ -1104,8 +1158,9 @@ class Jenkins(object):
|
||||
:param number: Jenkins build number for the job, ``int``
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(STOP_BUILD, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(STOP_BUILD, locals())
|
||||
))
|
||||
|
||||
def get_running_builds(self):
|
||||
'''Return list of running builds.
|
||||
@ -1164,10 +1219,11 @@ class Jenkins(object):
|
||||
:returns: List of nodes, ``[ { str: str, str: bool} ]``
|
||||
'''
|
||||
try:
|
||||
nodes_data = json.loads(self.jenkins_open(Request(self._build_url(NODE_LIST))))
|
||||
nodes_data = json.loads(self.jenkins_open(
|
||||
requests.Request('GET', self._build_url(NODE_LIST))))
|
||||
return [{'name': c["displayName"], 'offline': c["offline"]}
|
||||
for c in nodes_data["computer"]]
|
||||
except (HTTPError, BadStatusLine):
|
||||
except (req_exc.HTTPError, BadStatusLine):
|
||||
raise BadHTTPException("Error communicating with server[%s]"
|
||||
% self.server)
|
||||
except ValueError:
|
||||
@ -1182,13 +1238,14 @@ class Jenkins(object):
|
||||
:returns: Dictionary of node info, ``dict``
|
||||
'''
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(NODE_INFO, locals())))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(NODE_INFO, locals())
|
||||
))
|
||||
if response:
|
||||
return json.loads(response)
|
||||
else:
|
||||
raise JenkinsException('node[%s] does not exist' % name)
|
||||
except HTTPError:
|
||||
except (req_exc.HTTPError, NotFoundException):
|
||||
raise JenkinsException('node[%s] does not exist' % name)
|
||||
except ValueError:
|
||||
raise JenkinsException("Could not parse JSON info for node[%s]"
|
||||
@ -1224,8 +1281,9 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins node, ``str``
|
||||
'''
|
||||
self.get_node_info(name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(DELETE_NODE, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(DELETE_NODE, locals())
|
||||
))
|
||||
if self.node_exists(name):
|
||||
raise JenkinsException('delete[%s] failed' % (name))
|
||||
|
||||
@ -1238,8 +1296,9 @@ class Jenkins(object):
|
||||
info = self.get_node_info(name)
|
||||
if info['offline']:
|
||||
return
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(TOGGLE_OFFLINE, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(TOGGLE_OFFLINE, locals())
|
||||
))
|
||||
|
||||
def enable_node(self, name):
|
||||
'''Enable a node
|
||||
@ -1250,8 +1309,9 @@ class Jenkins(object):
|
||||
if not info['offline']:
|
||||
return
|
||||
msg = ''
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(TOGGLE_OFFLINE, locals()), b''))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(TOGGLE_OFFLINE, locals())
|
||||
))
|
||||
|
||||
def create_node(self, name, numExecutors=2, nodeDescription=None,
|
||||
remoteFS='/var/lib/jenkins', labels=None, exclusive=False,
|
||||
@ -1296,9 +1356,9 @@ class Jenkins(object):
|
||||
'json': json.dumps(inner_params)
|
||||
}
|
||||
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(CREATE_NODE, locals()),
|
||||
urlencode(params).encode('utf-8')))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(CREATE_NODE, locals()), data=params)
|
||||
)
|
||||
|
||||
self.assert_node_exists(name, 'create[%s] failed')
|
||||
|
||||
@ -1308,7 +1368,7 @@ class Jenkins(object):
|
||||
:param name: Jenkins node name, ``str``
|
||||
'''
|
||||
get_config_url = self._build_url(CONFIG_NODE, locals())
|
||||
return self.jenkins_open(Request(get_config_url))
|
||||
return self.jenkins_open(requests.Request('GET', get_config_url))
|
||||
|
||||
def reconfig_node(self, name, config_xml):
|
||||
'''Change the configuration for an existing node.
|
||||
@ -1317,7 +1377,11 @@ class Jenkins(object):
|
||||
:param config_xml: New XML configuration, ``str``
|
||||
'''
|
||||
reconfig_url = self._build_url(CONFIG_NODE, locals())
|
||||
self.jenkins_open(Request(reconfig_url, config_xml.encode('utf-8'), DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', reconfig_url,
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
|
||||
def get_build_console_output(self, name, number):
|
||||
'''Get build console text.
|
||||
@ -1328,15 +1392,15 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(BUILD_CONSOLE_OUTPUT, locals())
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(BUILD_CONSOLE_OUTPUT, locals())
|
||||
))
|
||||
if response:
|
||||
return response
|
||||
else:
|
||||
raise JenkinsException('job[%s] number[%d] does not exist'
|
||||
% (name, number))
|
||||
except HTTPError:
|
||||
except (req_exc.HTTPError, NotFoundException):
|
||||
raise JenkinsException('job[%s] number[%d] does not exist'
|
||||
% (name, number))
|
||||
|
||||
@ -1358,7 +1422,7 @@ class Jenkins(object):
|
||||
|
||||
return folder_url, short_name
|
||||
|
||||
def _get_view_jobs(self, view_name):
|
||||
def _get_view_jobs(self, name):
|
||||
'''Get list of jobs on the view specified.
|
||||
|
||||
Each job is a dictionary with 'name', 'url', 'color' and 'fullname'
|
||||
@ -1374,18 +1438,18 @@ class Jenkins(object):
|
||||
'''
|
||||
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(VIEW_JOBS, {u'name': view_name})
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(VIEW_JOBS, locals())
|
||||
))
|
||||
if response:
|
||||
jobs = json.loads(response)['jobs']
|
||||
else:
|
||||
raise JenkinsException('view[%s] does not exist' % view_name)
|
||||
except HTTPError:
|
||||
raise JenkinsException('view[%s] does not exist' % view_name)
|
||||
raise JenkinsException('view[%s] does not exist' % name)
|
||||
except NotFoundException:
|
||||
raise JenkinsException('view[%s] does not exist' % name)
|
||||
except ValueError:
|
||||
raise JenkinsException(
|
||||
'Could not parse JSON info for view[%s]' % view_name)
|
||||
'Could not parse JSON info for view[%s]' % name)
|
||||
|
||||
for job_dict in jobs:
|
||||
job_dict.update({u'fullname': job_dict[u'name']})
|
||||
@ -1403,8 +1467,8 @@ class Jenkins(object):
|
||||
:returns: Name of view or None
|
||||
'''
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(VIEW_NAME, locals())))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(VIEW_NAME, locals())))
|
||||
except NotFoundException:
|
||||
return None
|
||||
else:
|
||||
@ -1425,7 +1489,7 @@ class Jenkins(object):
|
||||
:throws: :class:`JenkinsException` whenever the view does not exist
|
||||
'''
|
||||
if not self.view_exists(name):
|
||||
raise JenkinsException(exception_message % name)
|
||||
raise NotFoundException(exception_message % name)
|
||||
|
||||
def view_exists(self, name):
|
||||
'''Check whether a view exists
|
||||
@ -1450,8 +1514,8 @@ class Jenkins(object):
|
||||
|
||||
:param name: Name of Jenkins view, ``str``
|
||||
'''
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(DELETE_VIEW, locals()), b''
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(DELETE_VIEW, locals())
|
||||
))
|
||||
if self.view_exists(name):
|
||||
raise JenkinsException('delete[%s] failed' % (name))
|
||||
@ -1465,9 +1529,11 @@ class Jenkins(object):
|
||||
if self.view_exists(name):
|
||||
raise JenkinsException('view[%s] already exists' % (name))
|
||||
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(CREATE_VIEW, locals()),
|
||||
config_xml.encode('utf-8'), DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(CREATE_VIEW, locals()),
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
self.assert_view_exists(name, 'create[%s] failed')
|
||||
|
||||
def reconfig_view(self, name, config_xml):
|
||||
@ -1479,8 +1545,11 @@ class Jenkins(object):
|
||||
:param config_xml: New XML configuration, ``str``
|
||||
'''
|
||||
reconfig_url = self._build_url(CONFIG_VIEW, locals())
|
||||
self.jenkins_open(Request(reconfig_url, config_xml.encode('utf-8'),
|
||||
DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', reconfig_url,
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
|
||||
def get_view_config(self, name):
|
||||
'''Get configuration of existing Jenkins view.
|
||||
@ -1488,7 +1557,7 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins view, ``str``
|
||||
:returns: view configuration (XML format)
|
||||
'''
|
||||
request = Request(self._build_url(CONFIG_VIEW, locals()))
|
||||
request = requests.Request('GET', self._build_url(CONFIG_VIEW, locals()))
|
||||
return self.jenkins_open(request)
|
||||
|
||||
def get_promotion_name(self, name, job_name):
|
||||
@ -1504,8 +1573,8 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(PROMOTION_NAME, locals())))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(PROMOTION_NAME, locals())))
|
||||
except NotFoundException:
|
||||
return None
|
||||
else:
|
||||
@ -1549,13 +1618,13 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
try:
|
||||
response = self.jenkins_open(Request(
|
||||
self._build_url(PROMOTION_INFO, locals())))
|
||||
response = self.jenkins_open(requests.Request(
|
||||
'GET', self._build_url(PROMOTION_INFO, locals())))
|
||||
if response:
|
||||
return json.loads(response)
|
||||
else:
|
||||
raise JenkinsException('job[%s] does not exist' % job_name)
|
||||
except HTTPError:
|
||||
except req_exc.HTTPError:
|
||||
raise JenkinsException('job[%s] does not exist' % job_name)
|
||||
except ValueError:
|
||||
raise JenkinsException("Could not parse JSON info for "
|
||||
@ -1578,8 +1647,8 @@ class Jenkins(object):
|
||||
:param name: Name of Jenkins promotion, ``str``
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(DELETE_PROMOTION, locals()), b''
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(DELETE_PROMOTION, locals())
|
||||
))
|
||||
if self.promotion_exists(name, job_name):
|
||||
raise JenkinsException('delete[%s] from job[%s] failed' %
|
||||
@ -1597,9 +1666,9 @@ class Jenkins(object):
|
||||
% (name, job_name))
|
||||
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(CREATE_PROMOTION, locals()),
|
||||
config_xml.encode('utf-8'), DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', self._build_url(CREATE_PROMOTION, locals()),
|
||||
data=config_xml.encode('utf-8'), headers=DEFAULT_HEADERS))
|
||||
self.assert_promotion_exists(name, job_name, 'create[%s] at '
|
||||
'job[%s] failed')
|
||||
|
||||
@ -1614,8 +1683,11 @@ class Jenkins(object):
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
reconfig_url = self._build_url(CONFIG_PROMOTION, locals())
|
||||
self.jenkins_open(Request(reconfig_url, config_xml.encode('utf-8'),
|
||||
DEFAULT_HEADERS))
|
||||
self.jenkins_open(requests.Request(
|
||||
'POST', reconfig_url,
|
||||
data=config_xml.encode('utf-8'),
|
||||
headers=DEFAULT_HEADERS
|
||||
))
|
||||
|
||||
def get_promotion_config(self, name, job_name):
|
||||
'''Get configuration of existing Jenkins promotion.
|
||||
@ -1625,7 +1697,8 @@ class Jenkins(object):
|
||||
:returns: promotion configuration (XML format)
|
||||
'''
|
||||
folder_url, short_name = self._get_job_folder(job_name)
|
||||
request = Request(self._build_url(CONFIG_PROMOTION, locals()))
|
||||
request = requests.Request(
|
||||
'GET', self._build_url(CONFIG_PROMOTION, locals()))
|
||||
return self.jenkins_open(request)
|
||||
|
||||
def quiet_down(self):
|
||||
@ -1634,7 +1707,7 @@ class Jenkins(object):
|
||||
No new builds will be started allowing running builds to complete
|
||||
prior to shutdown of the server.
|
||||
'''
|
||||
request = Request(self._build_url(QUIET_DOWN))
|
||||
request = requests.Request('POST', self._build_url(QUIET_DOWN))
|
||||
self.jenkins_open(request)
|
||||
info = self.get_info()
|
||||
if not info['quietingDown']:
|
||||
|
@ -1,121 +0,0 @@
|
||||
# Copyright (C) 2015 OpenStack Foundation
|
||||
#
|
||||
# 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 logging
|
||||
import re
|
||||
|
||||
import kerberos
|
||||
from six.moves.urllib import error, request
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HTTPNegotiateHandler(request.BaseHandler):
|
||||
handler_order = 490 # before Digest auth
|
||||
|
||||
def __init__(self, max_tries=5):
|
||||
self.krb_context = None
|
||||
self.tries = 0
|
||||
self.max_tries = max_tries
|
||||
self.re_extract_auth = re.compile('.*?Negotiate\s*([^,]*)', re.I)
|
||||
|
||||
def http_error_401(self, req, fp, code, msg, headers):
|
||||
logger.debug("INSIDE http_error_401")
|
||||
try:
|
||||
try:
|
||||
krb_req = self._extract_krb_value(headers)
|
||||
except ValueError:
|
||||
# Negotiate header not found or a similar error
|
||||
# we can't handle this, let the next handler have a go
|
||||
return None
|
||||
|
||||
if not krb_req:
|
||||
# First reply from server (no neg value)
|
||||
self.tries = 0
|
||||
krb_req = ""
|
||||
else:
|
||||
if self.tries > self.max_tries:
|
||||
raise error.HTTPError(
|
||||
req.get_full_url(), 401, "Negotiate auth failed",
|
||||
headers, None)
|
||||
|
||||
self.tries += 1
|
||||
try:
|
||||
krb_resp = self._krb_response(req.host, krb_req)
|
||||
|
||||
req.add_unredirected_header('Authorization',
|
||||
"Negotiate %s" % krb_resp)
|
||||
|
||||
resp = self.parent.open(req, timeout=req.timeout)
|
||||
self._authenticate_server(resp.headers)
|
||||
return resp
|
||||
|
||||
except kerberos.GSSError as err:
|
||||
try:
|
||||
msg = err.args[1][0]
|
||||
except Exception:
|
||||
msg = "Negotiate auth failed"
|
||||
logger.debug(msg)
|
||||
return None # let the next handler (if any) have a go
|
||||
|
||||
finally:
|
||||
if self.krb_context is not None:
|
||||
kerberos.authGSSClientClean(self.krb_context)
|
||||
self.krb_context = None
|
||||
|
||||
def _krb_response(self, host, krb_val):
|
||||
logger.debug("INSIDE _krb_response")
|
||||
|
||||
_dummy, self.krb_context = kerberos.authGSSClientInit("HTTP@%s" % host)
|
||||
kerberos.authGSSClientStep(self.krb_context, krb_val)
|
||||
response = kerberos.authGSSClientResponse(self.krb_context)
|
||||
|
||||
logger.debug("kerb auth successful")
|
||||
|
||||
return response
|
||||
|
||||
def _authenticate_server(self, headers):
|
||||
logger.debug("INSIDE _authenticate_server")
|
||||
try:
|
||||
val = self._extract_krb_value(headers)
|
||||
except ValueError:
|
||||
logger.critical("Server authentication failed."
|
||||
"Auth value couldn't be extracted from headers.")
|
||||
return None
|
||||
if not val:
|
||||
logger.critical("Server authentication failed."
|
||||
"Empty 'Negotiate' value.")
|
||||
return None
|
||||
|
||||
kerberos.authGSSClientStep(self.krb_context, val)
|
||||
|
||||
def _extract_krb_value(self, headers):
|
||||
logger.debug("INSIDE _extract_krb_value")
|
||||
header = headers.get('www-authenticate', None)
|
||||
|
||||
if header is None:
|
||||
msg = "www-authenticate header not found"
|
||||
logger.debug(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
if "negotiate" in header.lower():
|
||||
matches = self.re_extract_auth.search(header)
|
||||
if matches:
|
||||
return matches.group(1)
|
||||
else:
|
||||
return ""
|
||||
else:
|
||||
msg = "Negotiate not in www-authenticate header (%s)" % header
|
||||
logger.debug(msg)
|
||||
raise ValueError(msg)
|
@ -1,3 +1,4 @@
|
||||
six>=1.3.0
|
||||
pbr>=0.8.2
|
||||
multi_key_dict
|
||||
requests
|
||||
|
@ -1,9 +1,10 @@
|
||||
coverage>=3.6
|
||||
hacking>=0.5.6,<0.11
|
||||
kerberos>=1.2.4
|
||||
mock<1.1
|
||||
unittest2
|
||||
python-subunit
|
||||
requests-mock>=1.4.0
|
||||
requests-kerberos
|
||||
sphinx>=1.2,<1.3.0
|
||||
testrepository
|
||||
testscenarios
|
||||
|
@ -1,6 +1,5 @@
|
||||
import sys
|
||||
|
||||
from six.moves.urllib.request import build_opener
|
||||
from testscenarios import TestWithScenarios
|
||||
|
||||
import jenkins
|
||||
@ -25,7 +24,8 @@ class JenkinsTestBase(TestWithScenarios, unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(JenkinsTestBase, self).setUp()
|
||||
self.opener = build_opener()
|
||||
# TODO(darragh) would be useful if this could be mocked
|
||||
jenkins.requests_kerberos = None
|
||||
|
||||
self.j = jenkins.Jenkins(self.base_url, 'test', 'test')
|
||||
|
||||
@ -35,17 +35,4 @@ class JenkinsTestBase(TestWithScenarios, unittest.TestCase):
|
||||
def _check_requests(self, requests):
|
||||
|
||||
for req in requests:
|
||||
self._check_request(req[0][0])
|
||||
|
||||
def _check_request(self, request):
|
||||
|
||||
# taken from opener.open() in request
|
||||
# attribute request.type is only set automatically for python 3
|
||||
# requests, must use request.get_type() for python 2.7
|
||||
protocol = request.type or request.get_type()
|
||||
|
||||
# check that building the request doesn't throw any exception
|
||||
meth_name = protocol + "_request"
|
||||
for processor in self.opener.process_request.get(protocol, []):
|
||||
meth = getattr(processor, meth_name)
|
||||
request = meth(request)
|
||||
req[0][0].prepare()
|
||||
|
@ -1,8 +1,11 @@
|
||||
import functools
|
||||
import json
|
||||
from multiprocessing import Process
|
||||
from multiprocessing import Queue
|
||||
import traceback
|
||||
|
||||
from mock import Mock
|
||||
import requests
|
||||
from six.moves import socketserver
|
||||
|
||||
|
||||
@ -73,3 +76,31 @@ class NullServer(socketserver.TCPServer):
|
||||
socketserver.TCPServer.__init__(
|
||||
self, server_address, socketserver.BaseRequestHandler,
|
||||
*args, **kwargs)
|
||||
|
||||
|
||||
def build_response_mock(status_code, json_body=None, headers=None, **kwargs):
|
||||
real_response = requests.Response()
|
||||
real_response.status_code = status_code
|
||||
|
||||
text = None
|
||||
if json_body is not None:
|
||||
text = json.dumps(json_body)
|
||||
if headers is not {}:
|
||||
real_response.headers['content-length'] = len(text)
|
||||
|
||||
if headers is not None:
|
||||
for k, v in headers.items():
|
||||
real_response.headers[k] = v
|
||||
|
||||
for k, v in kwargs.items():
|
||||
setattr(real_response, k, v)
|
||||
|
||||
response = Mock(wraps=real_response, autospec=True)
|
||||
if text:
|
||||
response.text = text
|
||||
|
||||
# for some reason, wraps cannot handle attributes which are dicts
|
||||
# and accessed by key
|
||||
response.headers = real_response.headers
|
||||
|
||||
return response
|
||||
|
@ -14,7 +14,7 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
||||
|
||||
build_info = self.j.build_job(u'Test Job')
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/build'))
|
||||
self.assertEqual(build_info, {'foo': 'bar'})
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -27,7 +27,7 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
||||
|
||||
build_info = self.j.build_job(u'a Folder/Test Job')
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/build'))
|
||||
self.assertEqual(build_info, {'foo': 'bar'})
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -40,7 +40,7 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
||||
|
||||
build_info = self.j.build_job(u'TestJob', token='some_token')
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/build?token=some_token'))
|
||||
self.assertEqual(build_info, {'foo': 'bar'})
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -53,7 +53,7 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
||||
|
||||
build_info = self.j.build_job(u'a Folder/TestJob', token='some_token')
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/build?token=some_token'))
|
||||
self.assertEqual(build_info, {'foo': 'bar'})
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -69,8 +69,8 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
||||
parameters={'when': 'now', 'why': 'because I felt like it'},
|
||||
token='some_token')
|
||||
|
||||
self.assertTrue('token=some_token' in jenkins_mock.call_args[0][0].get_full_url())
|
||||
self.assertTrue('when=now' in jenkins_mock.call_args[0][0].get_full_url())
|
||||
self.assertTrue('why=because+I+felt+like+it' in jenkins_mock.call_args[0][0].get_full_url())
|
||||
self.assertTrue('token=some_token' in jenkins_mock.call_args[0][0].url)
|
||||
self.assertTrue('when=now' in jenkins_mock.call_args[0][0].url)
|
||||
self.assertTrue('why=because+I+felt+like+it' in jenkins_mock.call_args[0][0].url)
|
||||
self.assertEqual(build_info, {'foo': 'bar'})
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -11,7 +11,7 @@ class JenkinsGetJobConfigTest(JenkinsJobsTestBase):
|
||||
self.j.get_job_config(u'Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -20,6 +20,6 @@ class JenkinsGetJobConfigTest(JenkinsJobsTestBase):
|
||||
self.j.get_job_config(u'a folder/Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20folder/job/Test%20Job/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -18,7 +18,7 @@ class JenkinsCopyJobTest(JenkinsJobsTestBase):
|
||||
self.j.copy_job(u'Test Job', u'Test Job_2')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('createItem?name=Test%20Job_2&mode=copy&from=Test%20Job'))
|
||||
self.assertTrue(self.j.job_exists('Test Job_2'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -34,7 +34,7 @@ class JenkinsCopyJobTest(JenkinsJobsTestBase):
|
||||
self.j.copy_job(u'a Folder/Test Job', u'a Folder/Test Job_2')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/createItem?name=Test%20Job_2'
|
||||
'&mode=copy&from=Test%20Job'))
|
||||
self.assertTrue(self.j.job_exists('a Folder/Test Job_2'))
|
||||
@ -50,7 +50,7 @@ class JenkinsCopyJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.copy_job(u'TestJob', u'TestJob_2')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('createItem?name=TestJob_2&mode=copy&from=TestJob'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -67,7 +67,7 @@ class JenkinsCopyJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.copy_job(u'a Folder/TestJob', u'a Folder/TestJob_2')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/createItem?name=TestJob_2&mode=copy'
|
||||
'&from=TestJob'))
|
||||
self.assertEqual(
|
||||
|
@ -18,7 +18,7 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
self.j.create_job(u'Test Job', self.config_xml)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('createItem?name=Test%20Job'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -33,7 +33,7 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
self.j.create_job(u'a Folder/Test Job', self.config_xml)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/a%20Folder/createItem?name=Test%20Job'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -47,7 +47,7 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_job(u'TestJob', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -64,7 +64,7 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_job(u'a Folder/TestJob', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -82,10 +82,10 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_job(u'TestJob', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('createItem?name=TestJob'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -103,10 +103,10 @@ class JenkinsCreateJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_job(u'a Folder/TestJob', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/a%20Folder/createItem?name=TestJob'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
|
@ -20,7 +20,7 @@ class JenkinsDebugJobInfoTest(JenkinsJobsTestBase):
|
||||
self.j.debug_job_info(u'Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -37,6 +37,6 @@ class JenkinsDebugJobInfoTest(JenkinsJobsTestBase):
|
||||
self.j.debug_job_info(u'a Folder/Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -17,7 +17,7 @@ class JenkinsDeleteJobTest(JenkinsJobsTestBase):
|
||||
self.j.delete_job(u'Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/Test%20Job/doDelete'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -31,7 +31,7 @@ class JenkinsDeleteJobTest(JenkinsJobsTestBase):
|
||||
self.j.delete_job(u'a Folder/Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/doDelete'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -46,7 +46,7 @@ class JenkinsDeleteJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.delete_job(u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/doDelete'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -64,7 +64,7 @@ class JenkinsDeleteJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.delete_job(u'a Folder/TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/doDelete'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
|
@ -17,7 +17,7 @@ class JenkinsDisableJobTest(JenkinsJobsTestBase):
|
||||
self.j.disable_job(u'Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/Test%20Job/disable'))
|
||||
self.assertTrue(self.j.job_exists('Test Job'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -32,7 +32,7 @@ class JenkinsDisableJobTest(JenkinsJobsTestBase):
|
||||
self.j.disable_job(u'a Folder/Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/disable'))
|
||||
self.assertTrue(self.j.job_exists('a Folder/Test Job'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -17,7 +17,7 @@ class JenkinsEnableJobTest(JenkinsJobsTestBase):
|
||||
self.j.enable_job(u'TestJob')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/enable'))
|
||||
self.assertTrue(self.j.job_exists('TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -32,7 +32,7 @@ class JenkinsEnableJobTest(JenkinsJobsTestBase):
|
||||
self.j.enable_job(u'a Folder/TestJob')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/enable'))
|
||||
self.assertTrue(self.j.job_exists('a Folder/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -2,6 +2,7 @@ import json
|
||||
from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.helper import build_response_mock
|
||||
from tests.jobs.base import build_jobs_list_responses
|
||||
from tests.jobs.base import JenkinsGetJobsTestBase
|
||||
|
||||
@ -23,8 +24,8 @@ class JenkinsGetJobsTest(JenkinsGetJobsTestBase):
|
||||
jobs[u'fullname'] = jobs[u'name']
|
||||
self.assertEqual(job_info, [jobs])
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.make_url('api/json?tree=jobs[url,color,name,jobs]'))
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
@ -79,7 +80,7 @@ class JenkinsGetJobsTest(JenkinsGetJobsTestBase):
|
||||
self.assertEqual(view_jobs[1][u'name'], u'community.first')
|
||||
self.assertEqual(view_jobs[1][u'name'], view_jobs[1][u'fullname'])
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url(
|
||||
'view/Test%20View/api/json?tree=jobs[url,color,name]'
|
||||
))
|
||||
@ -93,7 +94,7 @@ class JenkinsGetJobsTest(JenkinsGetJobsTestBase):
|
||||
self.j.get_jobs(view_name=u'Test View')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url(
|
||||
'view/Test%20View/api/json?tree=jobs[url,color,name]'
|
||||
))
|
||||
@ -110,7 +111,7 @@ class JenkinsGetJobsTest(JenkinsGetJobsTestBase):
|
||||
self.j.get_jobs(view_name=u'Test View')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url(
|
||||
'view/Test%20View/api/json?tree=jobs[url,color,name]'
|
||||
))
|
||||
@ -119,25 +120,21 @@ class JenkinsGetJobsTest(JenkinsGetJobsTestBase):
|
||||
'Could not parse JSON info for view[Test View]')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_get_view_jobs_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url(
|
||||
'view/Test%20View/api/json?tree=jobs[url,color,name]'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_get_view_jobs_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_jobs(view_name=u'Test View')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url(
|
||||
'view/Test%20View/api/json?tree=jobs[url,color,name]'
|
||||
))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'view[Test View] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -2,6 +2,7 @@ import json
|
||||
from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.helper import build_response_mock
|
||||
from tests.jobs.base import JenkinsJobsTestBase
|
||||
|
||||
|
||||
@ -21,7 +22,7 @@ class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_info, job_info_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -48,10 +49,10 @@ class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_info, expected)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/Test%20Job/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url(
|
||||
'job/Test%20Job/api/json?tree=allBuilds[number,url]'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -70,7 +71,7 @@ class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_info, job_info_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -101,7 +102,7 @@ class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_info(u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -115,47 +116,41 @@ class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_info(u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for job[TestJob]')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob/api/json?depth=0'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_info(u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('job/TestJob/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[TestJob] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_in_folder_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?depth=0'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_in_folder_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_info(u'a Folder/TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[a Folder/TestJob] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -16,7 +16,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_name, 'Test Job')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -29,7 +29,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_name, 'Test Job')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -41,7 +41,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_name, None)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -53,7 +53,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
|
||||
self.assertEqual(job_name, None)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -65,7 +65,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_name(u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -81,7 +81,7 @@ class JenkinsGetJobNameTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_job_name(u'a Folder/TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
|
@ -16,7 +16,7 @@ class JenkinsReconfigJobTest(JenkinsJobsTestBase):
|
||||
|
||||
self.j.reconfig_job(u'Test Job', self.config_xml)
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -29,6 +29,6 @@ class JenkinsReconfigJobTest(JenkinsJobsTestBase):
|
||||
|
||||
self.j.reconfig_job(u'a Folder/Test Job', self.config_xml)
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -18,7 +18,7 @@ class JenkinsRenameJobTest(JenkinsJobsTestBase):
|
||||
self.j.rename_job(u'Test Job', u'Test Job_2')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/Test%20Job/doRename?newName=Test%20Job_2'))
|
||||
self.assertTrue(self.j.job_exists('Test Job_2'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -34,7 +34,7 @@ class JenkinsRenameJobTest(JenkinsJobsTestBase):
|
||||
self.j.rename_job(u'a Folder/Test Job', u'a Folder/Test Job_2')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/doRename?newName=Test%20Job_2'))
|
||||
self.assertTrue(self.j.job_exists('Test Job_2'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -49,7 +49,7 @@ class JenkinsRenameJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.rename_job(u'TestJob', u'TestJob_2')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/doRename?newName=TestJob_2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -66,7 +66,7 @@ class JenkinsRenameJobTest(JenkinsJobsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.rename_job(u'a Folder/TestJob', u'a Folder/TestJob_2')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/doRename?newName=TestJob_2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
|
@ -11,7 +11,7 @@ class JenkinsSetNextBuildNumberTest(JenkinsJobsTestBase):
|
||||
self.j.set_next_build_number('TestJob', 1234)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/nextbuildnumber/submit'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].data,
|
||||
|
@ -3,6 +3,7 @@ from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsBuildConsoleTest(JenkinsTestBase):
|
||||
@ -15,7 +16,7 @@ class JenkinsBuildConsoleTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(build_info, jenkins_mock.return_value)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/52/consoleText'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -27,7 +28,7 @@ class JenkinsBuildConsoleTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(build_info, jenkins_mock.return_value)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/52/consoleText'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -59,45 +60,38 @@ class JenkinsBuildConsoleTest(JenkinsTestBase):
|
||||
|
||||
console_output = self.j.get_build_console_output(u'TestJob', number=52)
|
||||
self.assertEqual(console_output, jenkins_mock.return_value)
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob/52/consoleText'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send')
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_build_console_output(u'TestJob', number=52)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/TestJob/52/consoleText'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[TestJob] number[52] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_in_folder_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/a%20Folder/job/TestJob/52/consoleText'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send')
|
||||
def test_in_folder_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_build_console_output(u'a Folder/TestJob', number=52)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/a%20Folder/job/TestJob/52/consoleText'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[a Folder/TestJob] number[52] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsBuildInfoTest(JenkinsTestBase):
|
||||
@ -116,7 +110,7 @@ class JenkinsBuildInfoTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(build_info, build_info_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/52/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -134,7 +128,7 @@ class JenkinsBuildInfoTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(build_info, build_info_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/52/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -160,37 +154,31 @@ class JenkinsBuildInfoTest(JenkinsTestBase):
|
||||
'Could not parse JSON info for job[TestJob] number[52]')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob/api/json?depth=0'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_build_info(u'TestJob', number=52)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[TestJob] number[52] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_in_folder_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/a%20Folder/job/TestJob/api/json?depth=0'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_in_folder_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(404, reason="Not Found"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_build_info(u'a Folder/TestJob', number=52)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'job[a Folder/TestJob] number[52] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsStopBuildTest(JenkinsTestBase):
|
||||
@ -200,7 +188,7 @@ class JenkinsStopBuildTest(JenkinsTestBase):
|
||||
self.j.stop_build(u'Test Job', number=52)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/52/stop'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -210,7 +198,7 @@ class JenkinsStopBuildTest(JenkinsTestBase):
|
||||
self.j.stop_build(u'a Folder/Test Job', number=52)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/a%20Folder/job/Test%20Job/52/stop'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
@ -3,6 +3,7 @@ from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsInfoTest(JenkinsTestBase):
|
||||
@ -22,28 +23,25 @@ class JenkinsInfoTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(job_info, job_info_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob/api/json?depth=0'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(499, reason="Unhandled Error"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
'Error communicating with server[{0}]'.format(self.make_url('')))
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_BadStatusLine(self, jenkins_mock):
|
||||
@ -52,11 +50,11 @@ class JenkinsInfoTest(JenkinsTestBase):
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
'Error communicating with server[{0}]'.format(self.make_url('')))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
@ -66,26 +64,26 @@ class JenkinsInfoTest(JenkinsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for server[{0}/]'.format(self.base_url))
|
||||
'Could not parse JSON info for server[{0}]'.format(self.make_url('')))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_return_empty_response(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.JenkinsException(
|
||||
"Error communicating with server[{0}/]: empty response".
|
||||
format(self.base_url))
|
||||
"Error communicating with server[{0}]: empty response".
|
||||
format(self.make_url('')))
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]: '
|
||||
'empty response'.format(self.base_url))
|
||||
'Error communicating with server[{0}]: '
|
||||
'empty response'.format(self.make_url('')))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -1,12 +1,13 @@
|
||||
import json
|
||||
import socket
|
||||
|
||||
from mock import patch, Mock
|
||||
from mock import patch
|
||||
import six
|
||||
from six.moves.urllib.error import HTTPError
|
||||
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
import jenkins
|
||||
from tests.base import JenkinsTestBase
|
||||
|
||||
|
||||
def get_mock_urlopen_return_value(a_dict=None):
|
||||
@ -17,19 +18,28 @@ def get_mock_urlopen_return_value(a_dict=None):
|
||||
|
||||
class JenkinsConstructorTest(JenkinsTestBase):
|
||||
|
||||
def setUp(self):
|
||||
super(JenkinsConstructorTest, self).setUp()
|
||||
self.req = jenkins.requests.Request('GET', self.base_url)
|
||||
self.j._maybe_add_auth()
|
||||
|
||||
def test_url_with_trailing_slash(self):
|
||||
self.assertEqual(self.j.server, self.make_url(''))
|
||||
self.assertEqual(self.j.auth, b'Basic dGVzdDp0ZXN0')
|
||||
self.assertEqual(self.j.auth(self.req).headers['Authorization'],
|
||||
'Basic dGVzdDp0ZXN0')
|
||||
self.assertEqual(self.j.crumb, None)
|
||||
|
||||
def test_url_without_trailing_slash(self):
|
||||
j = jenkins.Jenkins(self.base_url, 'test', 'test')
|
||||
j._maybe_add_auth()
|
||||
self.assertEqual(j.server, self.make_url(''))
|
||||
self.assertEqual(j.auth, b'Basic dGVzdDp0ZXN0')
|
||||
self.assertEqual(j.auth(self.req).headers['Authorization'],
|
||||
'Basic dGVzdDp0ZXN0')
|
||||
self.assertEqual(j.crumb, None)
|
||||
|
||||
def test_without_user_or_password(self):
|
||||
j = jenkins.Jenkins('{0}'.format(self.base_url))
|
||||
j._maybe_add_auth()
|
||||
self.assertEqual(j.server, self.make_url(''))
|
||||
self.assertEqual(j.auth, None)
|
||||
self.assertEqual(j.crumb, None)
|
||||
@ -38,8 +48,10 @@ class JenkinsConstructorTest(JenkinsTestBase):
|
||||
j = jenkins.Jenkins('{0}'.format(self.base_url),
|
||||
six.u('nonascii'),
|
||||
six.u('\xe9\u20ac'))
|
||||
j._maybe_add_auth()
|
||||
self.assertEqual(j.server, self.make_url(''))
|
||||
self.assertEqual(j.auth, b'Basic bm9uYXNjaWk6w6nigqw=')
|
||||
self.assertEqual(j.auth(self.req).headers['Authorization'],
|
||||
'Basic bm9uYXNjaWk6w6nigqw=')
|
||||
self.assertEqual(j.crumb, None)
|
||||
|
||||
def test_long_user_or_password(self):
|
||||
@ -47,9 +59,11 @@ class JenkinsConstructorTest(JenkinsTestBase):
|
||||
long_str_b64 = 'YWFh' * 20
|
||||
|
||||
j = jenkins.Jenkins('{0}'.format(self.base_url), long_str, long_str)
|
||||
j._maybe_add_auth()
|
||||
|
||||
self.assertNotIn(b"\n", j.auth)
|
||||
self.assertEqual(j.auth.decode('utf-8'), 'Basic %s' % (
|
||||
auth_header = j.auth(self.req).headers['Authorization']
|
||||
self.assertNotIn("\n", auth_header)
|
||||
self.assertEqual(auth_header, 'Basic %s' % (
|
||||
long_str_b64 + 'Om' + long_str_b64[2:] + 'YQ=='))
|
||||
|
||||
def test_default_timeout(self):
|
||||
@ -63,80 +77,74 @@ class JenkinsConstructorTest(JenkinsTestBase):
|
||||
|
||||
class JenkinsMaybeAddCrumbTest(JenkinsTestBase):
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_simple(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.NotFoundException()
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_simple(self, session_send_mock):
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
404, reason="Not Found")
|
||||
request = jenkins.requests.Request('http://example.com/job/TestJob')
|
||||
|
||||
self.j.maybe_add_crumb(request)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('crumbIssuer/api/json'))
|
||||
self.assertFalse(self.j.crumb)
|
||||
self.assertFalse('.crumb' in request.headers)
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_with_data(self, jenkins_mock):
|
||||
jenkins_mock.return_value = get_mock_urlopen_return_value(self.crumb_data)
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_with_data(self, session_send_mock):
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
200, self.crumb_data)
|
||||
request = jenkins.requests.Request('GET', 'http://example.com/job/TestJob')
|
||||
|
||||
self.j.maybe_add_crumb(request)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('crumbIssuer/api/json'))
|
||||
self.assertEqual(self.j.crumb, self.crumb_data)
|
||||
self.assertEqual(request.headers['.crumb'], self.crumb_data['crumb'])
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_return_empty_response(self, jenkins_mock):
|
||||
"Don't try to create crumb header from an empty response"
|
||||
jenkins_mock.side_effect = jenkins.EmptyResponseException("empty response")
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
request = jenkins.requests.Request('GET', 'http://example.com/job/TestJob')
|
||||
|
||||
self.j.maybe_add_crumb(request)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('crumbIssuer/api/json'))
|
||||
self.assertFalse(self.j.crumb)
|
||||
self.assertFalse('.crumb' in request.headers)
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsOpenTest(JenkinsTestBase):
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_simple(self, jenkins_mock):
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_simple(self, session_send_mock):
|
||||
data = {'foo': 'bar'}
|
||||
jenkins_mock.side_effect = [
|
||||
get_mock_urlopen_return_value(self.crumb_data),
|
||||
get_mock_urlopen_return_value(data),
|
||||
]
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(200, self.crumb_data),
|
||||
build_response_mock(200, data),
|
||||
])
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
|
||||
response = self.j.jenkins_open(request)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self.assertEqual(response, json.dumps(data))
|
||||
self.assertEqual(self.j.crumb, self.crumb_data)
|
||||
self.assertEqual(request.headers['.crumb'], self.crumb_data['crumb'])
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_response_403(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_response_403(self, session_send_mock):
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
401, reason="basic auth failed")
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.jenkins_open(request, add_crumb=False)
|
||||
@ -145,19 +153,14 @@ class JenkinsOpenTest(JenkinsTestBase):
|
||||
'Error in request. Possibly authentication failed [401]: '
|
||||
'basic auth failed')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_response_404(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob'),
|
||||
code=404,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_response_404(self, session_send_mock):
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
404, reason="basic auth failed")
|
||||
|
||||
with self.assertRaises(jenkins.NotFoundException) as context_manager:
|
||||
self.j.jenkins_open(request, add_crumb=False)
|
||||
@ -165,53 +168,46 @@ class JenkinsOpenTest(JenkinsTestBase):
|
||||
str(context_manager.exception),
|
||||
'Requested item could not be found')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_empty_response(self, jenkins_mock):
|
||||
jenkins_mock.return_value = Mock(**{'read.return_value': None})
|
||||
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_empty_response(self, session_send_mock):
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
401, reason="basic auth failed")
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.jenkins_open(request, False)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]: '
|
||||
'empty response'.format(self.base_url))
|
||||
'Error in request. Possibly authentication failed [401]: '
|
||||
'basic auth failed')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_response_501(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob'),
|
||||
code=501,
|
||||
msg="Not implemented",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_response_501(self, session_send_mock):
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
501, reason="Not implemented")
|
||||
|
||||
with self.assertRaises(HTTPError) as context_manager:
|
||||
with self.assertRaises(jenkins.req_exc.HTTPError) as context_manager:
|
||||
self.j.jenkins_open(request, add_crumb=False)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'HTTP Error 501: Not implemented')
|
||||
'501 Server Error: Not implemented for url: None')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_timeout(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.URLError(
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_timeout(self, session_send_mock):
|
||||
session_send_mock.side_effect = jenkins.URLError(
|
||||
reason="timed out")
|
||||
j = jenkins.Jenkins(self.make_url(''), 'test', 'test', timeout=1)
|
||||
request = jenkins.Request(self.make_url('job/TestJob'))
|
||||
request = jenkins.requests.Request('GET', self.make_url('job/TestJob'))
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
j.jenkins_open(request, add_crumb=False)
|
||||
@ -219,9 +215,8 @@ class JenkinsOpenTest(JenkinsTestBase):
|
||||
str(context_manager.exception),
|
||||
'Error in request: timed out')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args[0][1].url,
|
||||
self.make_url('job/TestJob'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open',
|
||||
return_value=json.dumps({'mode': 'NORMAL'}))
|
||||
|
@ -23,8 +23,8 @@ class JenkinsRequestTimeoutTests(testtools.TestCase):
|
||||
def test_jenkins_open_timeout(self):
|
||||
j = jenkins.Jenkins("http://%s:%s" % self.server.server_address,
|
||||
None, None, timeout=0.1)
|
||||
request = jenkins.Request('http://%s:%s/job/TestJob' %
|
||||
self.server.server_address)
|
||||
request = jenkins.requests.Request('GET', 'http://%s:%s/job/TestJob' %
|
||||
self.server.server_address)
|
||||
|
||||
# assert our request times out when no response
|
||||
with testtools.ExpectedException(jenkins.TimeoutException):
|
||||
@ -33,8 +33,8 @@ class JenkinsRequestTimeoutTests(testtools.TestCase):
|
||||
def test_jenkins_open_no_timeout(self):
|
||||
j = jenkins.Jenkins("http://%s:%s" % self.server.server_address,
|
||||
None, None)
|
||||
request = jenkins.Request('http://%s:%s/job/TestJob' %
|
||||
self.server.server_address)
|
||||
request = jenkins.requests.Request('GET', 'http://%s:%s/job/TestJob' %
|
||||
self.server.server_address)
|
||||
|
||||
# assert we don't timeout quickly like previous test when
|
||||
# no timeout defined.
|
||||
|
@ -1,124 +0,0 @@
|
||||
import kerberos
|
||||
assert kerberos # pyflakes
|
||||
from mock import patch, Mock
|
||||
from six.moves.urllib.request import Request
|
||||
import testtools
|
||||
|
||||
from jenkins import urllib_kerb
|
||||
|
||||
|
||||
class KerberosTests(testtools.TestCase):
|
||||
|
||||
@patch('kerberos.authGSSClientResponse')
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
@patch('kerberos.authGSSClientInit')
|
||||
@patch('kerberos.authGSSClientClean')
|
||||
def test_http_error_401_simple(self, clean_mock, init_mock, step_mock, response_mock):
|
||||
headers_from_server = {'www-authenticate': 'Negotiate xxx'}
|
||||
|
||||
init_mock.side_effect = lambda x: (x, "context")
|
||||
response_mock.return_value = "foo"
|
||||
|
||||
parent_mock = Mock()
|
||||
parent_return_mock = Mock()
|
||||
parent_return_mock.headers = {'www-authenticate': "Negotiate bar"}
|
||||
parent_mock.open.return_value = parent_return_mock
|
||||
|
||||
request_mock = Mock(spec=self._get_dummy_request())
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
h.add_parent(parent_mock)
|
||||
rv = h.http_error_401(request_mock, "", "", "", headers_from_server)
|
||||
|
||||
init_mock.assert_called()
|
||||
step_mock.assert_any_call("context", "xxx")
|
||||
# verify authGSSClientStep was called for response as well
|
||||
step_mock.assert_any_call("context", "bar")
|
||||
response_mock.assert_called_with("context")
|
||||
request_mock.add_unredirected_header.assert_called_with(
|
||||
'Authorization', 'Negotiate %s' % "foo")
|
||||
self.assertEqual(rv, parent_return_mock)
|
||||
clean_mock.assert_called_with("context")
|
||||
|
||||
@patch('kerberos.authGSSClientResponse')
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
@patch('kerberos.authGSSClientInit')
|
||||
@patch('kerberos.authGSSClientClean')
|
||||
def test_http_error_401_gsserror(self, clean_mock, init_mock, step_mock, response_mock):
|
||||
headers_from_server = {'www-authenticate': 'Negotiate xxx'}
|
||||
|
||||
init_mock.side_effect = kerberos.GSSError
|
||||
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
rv = h.http_error_401(Mock(spec=self._get_dummy_request()), "", "", "",
|
||||
headers_from_server)
|
||||
self.assertEqual(rv, None)
|
||||
|
||||
@patch('kerberos.authGSSClientResponse')
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
@patch('kerberos.authGSSClientInit')
|
||||
@patch('kerberos.authGSSClientClean')
|
||||
def test_http_error_401_empty(self, clean_mock, init_mock, step_mock, response_mock):
|
||||
headers_from_server = {}
|
||||
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
rv = h.http_error_401(Mock(spec=self._get_dummy_request()), "", "", "",
|
||||
headers_from_server)
|
||||
self.assertEqual(rv, None)
|
||||
|
||||
@patch('kerberos.authGSSClientResponse')
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
@patch('kerberos.authGSSClientInit')
|
||||
def test_krb_response_simple(self, init_mock, step_mock, response_mock):
|
||||
response_mock.return_value = "foo"
|
||||
init_mock.return_value = ("bar", "context")
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
rv = h._krb_response("host", "xxx")
|
||||
self.assertEqual(rv, "foo")
|
||||
|
||||
@patch('kerberos.authGSSClientResponse')
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
@patch('kerberos.authGSSClientInit')
|
||||
def test_krb_response_gsserror(self, init_mock, step_mock, response_mock):
|
||||
response_mock.side_effect = kerberos.GSSError
|
||||
init_mock.return_value = ("bar", "context")
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
with testtools.ExpectedException(kerberos.GSSError):
|
||||
h._krb_response("host", "xxx")
|
||||
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
def test_authenticate_server_simple(self, step_mock):
|
||||
headers_from_server = {'www-authenticate': 'Negotiate xxx'}
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
h.krb_context = "foo"
|
||||
h._authenticate_server(headers_from_server)
|
||||
step_mock.assert_called_with("foo", "xxx")
|
||||
|
||||
@patch('kerberos.authGSSClientStep')
|
||||
def test_authenticate_server_empty(self, step_mock):
|
||||
headers_from_server = {'www-authenticate': 'Negotiate'}
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
rv = h._authenticate_server(headers_from_server)
|
||||
self.assertEqual(rv, None)
|
||||
|
||||
def test_extract_krb_value_simple(self):
|
||||
headers_from_server = {'www-authenticate': 'Negotiate xxx'}
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
rv = h._extract_krb_value(headers_from_server)
|
||||
self.assertEqual(rv, "xxx")
|
||||
|
||||
def test_extract_krb_value_empty(self):
|
||||
headers_from_server = {}
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
with testtools.ExpectedException(ValueError):
|
||||
h._extract_krb_value(headers_from_server)
|
||||
|
||||
def test_extract_krb_value_invalid(self):
|
||||
headers_from_server = {'www-authenticate': 'Foo-&#@^%:; bar'}
|
||||
h = urllib_kerb.HTTPNegotiateHandler()
|
||||
with testtools.ExpectedException(ValueError):
|
||||
h._extract_krb_value(headers_from_server)
|
||||
|
||||
def _get_dummy_request(self):
|
||||
r = Request('http://example.com')
|
||||
r.timeout = 10
|
||||
return r
|
@ -2,7 +2,9 @@ import json
|
||||
from mock import patch
|
||||
|
||||
import jenkins
|
||||
import requests_mock
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsNodesTestBase(JenkinsTestBase):
|
||||
@ -42,41 +44,41 @@ class JenkinsGetNodesTest(JenkinsNodesTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_nodes()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for server[{0}/]'.format(self.base_url))
|
||||
'Could not parse JSON info for server[{0}]'.format(
|
||||
self.make_url('')))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_raise_BadStatusLine(self, urlopen_mock):
|
||||
urlopen_mock.side_effect = jenkins.BadStatusLine('not a valid status line')
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_BadStatusLine(self, session_send_mock):
|
||||
session_send_mock.side_effect = jenkins.BadStatusLine(
|
||||
'not a valid status line')
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_nodes()
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(urlopen_mock.call_args_list)
|
||||
'Error communicating with server[{0}]'.format(
|
||||
self.make_url('')))
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(499, reason="Unhandled Error"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_nodes()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('computer/api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
'Error communicating with server[{0}]'.format(
|
||||
self.make_url('')))
|
||||
|
||||
|
||||
class JenkinsGetNodeInfoTest(JenkinsNodesTestBase):
|
||||
@ -87,11 +89,11 @@ class JenkinsGetNodeInfoTest(JenkinsNodesTestBase):
|
||||
json.dumps(self.node_info),
|
||||
]
|
||||
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
self.assertEqual(self.j.get_node_info('test node'), self.node_info)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test%20node/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_return_invalid_json(self, jenkins_mock):
|
||||
@ -101,32 +103,30 @@ class JenkinsGetNodeInfoTest(JenkinsNodesTestBase):
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_node_info('test_node')
|
||||
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test_node/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for node[test_node]')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/TestJob'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(499, reason="Unhandled Error"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_node_info('test_node')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('computer/test_node/api/json?depth=0'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'node[test_node] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsAssertNodeExistsTest(JenkinsNodesTestBase):
|
||||
@ -137,10 +137,11 @@ class JenkinsAssertNodeExistsTest(JenkinsNodesTestBase):
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.assert_node_exists('NonExistentNode')
|
||||
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'node[NonExistentNode] does not exist')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_node_exists(self, jenkins_mock):
|
||||
@ -164,11 +165,11 @@ class JenkinsDeleteNodeTest(JenkinsNodesTestBase):
|
||||
|
||||
self.j.delete_node('test node')
|
||||
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('computer/test%20node/doDelete'))
|
||||
self.assertFalse(self.j.node_exists('test node'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_failed(self, jenkins_mock):
|
||||
@ -180,42 +181,55 @@ class JenkinsDeleteNodeTest(JenkinsNodesTestBase):
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.delete_node('test_node')
|
||||
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('computer/test_node/doDelete'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'delete[test_node] failed')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsCreateNodeTest(JenkinsNodesTestBase):
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_simple(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = [
|
||||
None,
|
||||
None,
|
||||
json.dumps(self.node_info),
|
||||
json.dumps(self.node_info),
|
||||
]
|
||||
@requests_mock.Mocker()
|
||||
def test_simple(self, req_mock):
|
||||
req_mock.get(self.make_url(jenkins.CRUMB_URL))
|
||||
req_mock.post(self.make_url(jenkins.CREATE_NODE), status_code=200,
|
||||
text='success', headers={'content-length': '7'})
|
||||
req_mock.get(
|
||||
self.make_url('computer/test%20node/api/json?depth=0'),
|
||||
[{'status_code': 404, 'headers': {'content-length': '9'},
|
||||
'text': 'NOT FOUND'},
|
||||
{'status_code': 200, 'json': {'displayName': 'test%20node'},
|
||||
'headers': {'content-length': '20'}}
|
||||
])
|
||||
|
||||
self.j.create_node('test node', exclusive=True)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url().split('?')[0],
|
||||
self.make_url('computer/doCreateItem'))
|
||||
actual = req_mock.request_history[2]
|
||||
self.assertEqual(actual.url, self.make_url('computer/doCreateItem'))
|
||||
self.assertIn('name=test+node', actual.body)
|
||||
self.assertTrue(self.j.node_exists('test node'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_urlencode(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = [
|
||||
None,
|
||||
None,
|
||||
json.dumps(self.node_info),
|
||||
json.dumps(self.node_info),
|
||||
]
|
||||
@requests_mock.Mocker()
|
||||
def test_urlencode(self, req_mock):
|
||||
# resp 0 (don't care about this succeeding)
|
||||
req_mock.get(self.make_url(jenkins.CRUMB_URL))
|
||||
# resp 2
|
||||
req_mock.post(self.make_url(jenkins.CREATE_NODE), status_code=200,
|
||||
text='success', headers={'content-length': '7'})
|
||||
# resp 1 & 3
|
||||
req_mock.get(
|
||||
self.make_url('computer/10.0.0.1%2Btest-node/api/json?depth=0'),
|
||||
[{'status_code': 404, 'headers': {'content-length': '9'},
|
||||
'text': 'NOT FOUND'},
|
||||
{'status_code': 200,
|
||||
'json': {'displayName': '10.0.0.1+test-node'},
|
||||
'headers': {'content-length': '20'}}
|
||||
])
|
||||
|
||||
params = {
|
||||
'port': '22',
|
||||
'username': 'juser',
|
||||
@ -232,11 +246,10 @@ class JenkinsCreateNodeTest(JenkinsNodesTestBase):
|
||||
launcher=jenkins.LAUNCHER_SSH,
|
||||
launcher_params=params)
|
||||
|
||||
actual = jenkins_mock.call_args_list[1][0][0].data.decode('utf-8')
|
||||
actual = req_mock.request_history[2].body
|
||||
# As python dicts do not guarantee order so the parameters get
|
||||
# re-ordered when it gets processed by _get_encoded_params(),
|
||||
# verify sections of the URL with self.assertIn() instead of
|
||||
# the entire URL
|
||||
# re-ordered when it gets processed by requests, verify sections
|
||||
# of the URL with self.assertIn() instead of the entire URL
|
||||
self.assertIn(u'name=10.0.0.1%2Btest-node', actual)
|
||||
self.assertIn(u'type=hudson.slaves.DumbSlave%24DescriptorImpl', actual)
|
||||
self.assertIn(u'username%22%3A+%22juser', actual)
|
||||
@ -250,20 +263,21 @@ class JenkinsCreateNodeTest(JenkinsNodesTestBase):
|
||||
self.assertIn(u'port%22%3A+%2222', actual)
|
||||
self.assertIn(u'remoteFS%22%3A+%22%2Fhome%2Fjuser', actual)
|
||||
self.assertIn(u'labelString%22%3A+%22precise', actual)
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_already_exists(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = [
|
||||
json.dumps(self.node_info),
|
||||
]
|
||||
@requests_mock.Mocker()
|
||||
def test_already_exists(self, req_mock):
|
||||
req_mock.get(self.make_url(jenkins.CRUMB_URL))
|
||||
req_mock.get(
|
||||
self.make_url('computer/test_node/api/json?depth=0'),
|
||||
status_code=200, json=self.node_info,
|
||||
headers={'content-length': '20'}
|
||||
)
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_node('test_node')
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'node[test_node] already exists')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_failed(self, jenkins_mock):
|
||||
@ -277,7 +291,7 @@ class JenkinsCreateNodeTest(JenkinsNodesTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_node('test_node')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url().split('?')[0],
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('computer/doCreateItem'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -297,9 +311,9 @@ class JenkinsEnableNodeTest(JenkinsNodesTestBase):
|
||||
self.j.enable_node('test node')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
'{0}/computer/test%20node/'
|
||||
'toggleOffline?offlineMessage='.format(self.base_url))
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test%20node/'
|
||||
'toggleOffline?offlineMessage='))
|
||||
|
||||
jenkins_mock.side_effect = [json.dumps(self.online_node_info)]
|
||||
node_info = self.j.get_node_info('test node')
|
||||
@ -318,7 +332,7 @@ class JenkinsEnableNodeTest(JenkinsNodesTestBase):
|
||||
# Node was not offline; so enable_node skips toggle
|
||||
# Last call to jenkins was to check status
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test_node/api/json?depth=0'))
|
||||
|
||||
jenkins_mock.side_effect = [json.dumps(self.online_node_info)]
|
||||
@ -339,9 +353,9 @@ class JenkinsDisableNodeTest(JenkinsNodesTestBase):
|
||||
self.j.disable_node('test node')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
'{0}/computer/test%20node/'
|
||||
'toggleOffline?offlineMessage='.format(self.base_url))
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test%20node/'
|
||||
'toggleOffline?offlineMessage='))
|
||||
|
||||
jenkins_mock.side_effect = [json.dumps(self.offline_node_info)]
|
||||
node_info = self.j.get_node_info('test node')
|
||||
@ -360,7 +374,7 @@ class JenkinsDisableNodeTest(JenkinsNodesTestBase):
|
||||
# Node was already offline; so disable_node skips toggle
|
||||
# Last call to jenkins was to check status
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('computer/test_node/api/json?depth=0'))
|
||||
|
||||
jenkins_mock.side_effect = [json.dumps(self.offline_node_info)]
|
||||
|
@ -38,6 +38,7 @@ from testscenarios.scenarios import multiply_scenarios
|
||||
import jenkins
|
||||
from jenkins import plugins
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsPluginsBase(JenkinsTestBase):
|
||||
@ -83,7 +84,7 @@ class JenkinsPluginsInfoTest(JenkinsPluginsBase):
|
||||
plugins_info = self.j.get_plugins_info()
|
||||
self.assertEqual(plugins_info, self.plugin_info_json['plugins'])
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=2'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -103,7 +104,7 @@ class JenkinsPluginsInfoTest(JenkinsPluginsBase):
|
||||
|
||||
self.j.get_plugins_info(depth=1)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=1'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -114,7 +115,7 @@ class JenkinsPluginsInfoTest(JenkinsPluginsBase):
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_plugins_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -128,28 +129,23 @@ class JenkinsPluginsInfoTest(JenkinsPluginsBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_plugins_info()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/pluginManager/api/json?depth=2'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
499, reason="Unhandled Error")
|
||||
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_plugins_info(depth=52)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsPluginInfoTest(JenkinsPluginsBase):
|
||||
@ -209,7 +205,7 @@ class JenkinsPluginInfoTest(JenkinsPluginsBase):
|
||||
|
||||
self.j.get_plugin_info('test', depth=1)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=1'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -220,7 +216,7 @@ class JenkinsPluginInfoTest(JenkinsPluginsBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_plugin_info('test')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -234,28 +230,25 @@ class JenkinsPluginInfoTest(JenkinsPluginsBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_plugin_info('test')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('pluginManager/api/json?depth=2'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Could not parse JSON info for server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('job/pluginManager/api/json?depth=2'),
|
||||
code=401,
|
||||
msg="basic auth failed",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(499, reason="Unhandled Error"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_plugin_info(u'TestPlugin', depth=52)
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class PluginsTestScenarios(JenkinsPluginsBase):
|
||||
|
@ -24,7 +24,7 @@ class JenkinsGetPromotionNameTest(JenkinsPromotionsTestBase):
|
||||
|
||||
self.assertEqual(promotion_name, 'Test Promotion')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/promotion/process/'
|
||||
'Test%20Promotion/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -38,7 +38,7 @@ class JenkinsGetPromotionNameTest(JenkinsPromotionsTestBase):
|
||||
|
||||
self.assertEqual(promotion_name, None)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/promotion/process/'
|
||||
'TestPromotion/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -51,7 +51,7 @@ class JenkinsGetPromotionNameTest(JenkinsPromotionsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_promotion_name(u'TestPromotion', u'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/process/TestPromotion'
|
||||
'/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
@ -122,7 +122,7 @@ class JenkinsGetPromotionsTest(JenkinsPromotionsTestBase):
|
||||
|
||||
self.assertEqual(promotion_info, promotions)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/TestJob/promotion/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -164,7 +164,7 @@ class JenkinsDeletePromotionTest(JenkinsPromotionsTestBase):
|
||||
self.j.delete_promotion(u'Test Promotion', 'TestJob')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/process/'
|
||||
'Test%20Promotion/doDelete'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -180,7 +180,7 @@ class JenkinsDeletePromotionTest(JenkinsPromotionsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.delete_promotion(u'TestPromotion', 'TestJob')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/process/'
|
||||
'TestPromotion/doDelete'))
|
||||
self.assertEqual(
|
||||
@ -202,7 +202,7 @@ class JenkinsCreatePromotionTest(JenkinsPromotionsTestBase):
|
||||
self.j.create_promotion(u'Test Promotion', 'Test Job', self.config_xml)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/Test%20Job/promotion/'
|
||||
'createProcess?name=Test%20Promotion'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -218,7 +218,7 @@ class JenkinsCreatePromotionTest(JenkinsPromotionsTestBase):
|
||||
self.j.create_promotion(u'TestPromotion', 'TestJob',
|
||||
self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/process/'
|
||||
'TestPromotion/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
@ -238,11 +238,11 @@ class JenkinsCreatePromotionTest(JenkinsPromotionsTestBase):
|
||||
self.j.create_promotion(u'TestPromotion', 'TestJob',
|
||||
self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/process/'
|
||||
'TestPromotion/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('job/TestJob/promotion/'
|
||||
'createProcess?name=TestPromotion'))
|
||||
self.assertEqual(
|
||||
@ -263,7 +263,7 @@ class JenkinsReconfigPromotionTest(JenkinsPromotionsTestBase):
|
||||
self.j.reconfig_promotion(u'Test Promotion', u'Test Job',
|
||||
self.config_xml)
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/promotion/process/'
|
||||
'Test%20Promotion/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -276,7 +276,7 @@ class JenkinsGetPromotionConfigTest(JenkinsPromotionsTestBase):
|
||||
self.j.get_promotion_config(u'Test Promotion', u'Test Job')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('job/Test%20Job/promotion/process/'
|
||||
'Test%20Promotion/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -15,7 +15,7 @@ class JenkinsCancelQueueTest(JenkinsTestBase):
|
||||
self.j.cancel_queue(52)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('queue/cancelItem?id=52'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -28,7 +28,7 @@ class JenkinsCancelQueueTest(JenkinsTestBase):
|
||||
self.j.cancel_queue(52)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('queue/cancelItem?id=52'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -67,6 +67,6 @@ class JenkinsQueueInfoTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(queue_info, queue_info_to_return['items'])
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('queue/api/json?depth=0'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -16,10 +16,10 @@ class JenkinsQuietDownTest(JenkinsTestBase):
|
||||
self.j.quiet_down()
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('quietDown'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -34,10 +34,10 @@ class JenkinsQuietDownTest(JenkinsTestBase):
|
||||
self.j.quiet_down()
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('quietDown'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -54,6 +54,6 @@ class JenkinsQuietDownTest(JenkinsTestBase):
|
||||
self.j.quiet_down()
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('quietDown'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -12,7 +12,7 @@ class JenkinsScriptTest(JenkinsTestBase):
|
||||
self.j.run_script(u'println(\"Hello World!\")')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('scriptText'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -21,7 +21,7 @@ class JenkinsScriptTest(JenkinsTestBase):
|
||||
self.j.run_script(u'if (a == b && c ==d) { println(\"Yes\")}')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('scriptText'))
|
||||
self.assertIn(quote('&&'), jenkins_mock.call_args[0][0].data.decode('utf8'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
@ -33,7 +33,7 @@ class JenkinsScriptTest(JenkinsTestBase):
|
||||
j = jenkins.Jenkins(self.make_url(''), 'test', 'test')
|
||||
j.install_plugin("jabber")
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('scriptText'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
@ -1,57 +1,46 @@
|
||||
from mock import patch, Mock
|
||||
import six
|
||||
from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsVersionTest(JenkinsTestBase):
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_some_version(self, urlopen_mock):
|
||||
mock_response = Mock()
|
||||
if six.PY2:
|
||||
config = {'info.return_value.getheader.return_value': 'Version42'}
|
||||
|
||||
if six.PY3:
|
||||
config = {'getheader.return_value': 'Version42'}
|
||||
|
||||
mock_response.configure_mock(**config)
|
||||
urlopen_mock.side_effect = [mock_response]
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_some_version(self, session_send_mock):
|
||||
session_send_mock.return_value = build_response_mock(
|
||||
200, headers={'X-Jenkins': 'Version42', 'Content-Length': 0})
|
||||
self.assertEqual(self.j.get_version(), 'Version42')
|
||||
self._check_requests(urlopen_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_raise_HTTPError(self, urlopen_mock):
|
||||
urlopen_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url(''),
|
||||
code=503,
|
||||
msg="internal server error",
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(499, reason="Unhandled Error"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_version()
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(urlopen_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen')
|
||||
def test_raise_BadStatusLine(self, urlopen_mock):
|
||||
urlopen_mock.side_effect = jenkins.BadStatusLine('not a valid status line')
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_BadStatusLine(self, session_send_mock):
|
||||
session_send_mock.side_effect = jenkins.BadStatusLine('not a valid status line')
|
||||
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
|
||||
self.j.get_version()
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]'.format(self.base_url))
|
||||
self._check_requests(urlopen_mock.call_args_list)
|
||||
|
||||
@patch('jenkins.urlopen', return_value=None)
|
||||
def test_return_empty_response(self, urlopen_mock):
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_return_empty_response(self, session_send_mock):
|
||||
session_send_mock.return_value = build_response_mock(0)
|
||||
with self.assertRaises(jenkins.EmptyResponseException) as context_manager:
|
||||
self.j.get_version()
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
'Error communicating with server[{0}/]:'
|
||||
' empty response'.format(self.base_url))
|
||||
self._check_requests(urlopen_mock.call_args_list)
|
||||
|
@ -24,7 +24,7 @@ class JenkinsGetViewNameTest(JenkinsViewsTestBase):
|
||||
|
||||
self.assertEqual(view_name, 'Test View')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('view/Test%20View/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -36,7 +36,7 @@ class JenkinsGetViewNameTest(JenkinsViewsTestBase):
|
||||
|
||||
self.assertEqual(view_name, None)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('view/TestView/api/json?tree=name'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -48,7 +48,7 @@ class JenkinsGetViewNameTest(JenkinsViewsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.get_view_name(u'TestView')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('view/TestView/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -94,7 +94,7 @@ class JenkinsGetViewsTest(JenkinsViewsTestBase):
|
||||
|
||||
self.assertEqual(view_info, views)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -111,7 +111,7 @@ class JenkinsDeleteViewTest(JenkinsViewsTestBase):
|
||||
self.j.delete_view(u'Test View')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('view/Test%20View/doDelete'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -126,7 +126,7 @@ class JenkinsDeleteViewTest(JenkinsViewsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.delete_view(u'TestView')
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('view/TestView/doDelete'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -147,7 +147,7 @@ class JenkinsCreateViewTest(JenkinsViewsTestBase):
|
||||
self.j.create_view(u'Test View', self.config_xml)
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('createView?name=Test%20View'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -161,7 +161,7 @@ class JenkinsCreateViewTest(JenkinsViewsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_view(u'TestView', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('view/TestView/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -179,10 +179,10 @@ class JenkinsCreateViewTest(JenkinsViewsTestBase):
|
||||
with self.assertRaises(jenkins.JenkinsException) as context_manager:
|
||||
self.j.create_view(u'TestView', self.config_xml)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[0][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[0][0][0].url,
|
||||
self.make_url('view/TestView/api/json?tree=name'))
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args_list[1][0][0].get_full_url(),
|
||||
jenkins_mock.call_args_list[1][0][0].url,
|
||||
self.make_url('createView?name=TestView'))
|
||||
self.assertEqual(
|
||||
str(context_manager.exception),
|
||||
@ -201,7 +201,7 @@ class JenkinsReconfigViewTest(JenkinsViewsTestBase):
|
||||
|
||||
self.j.reconfig_view(u'Test View', self.config_xml)
|
||||
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
|
||||
self.assertEqual(jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('view/Test%20View/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@ -213,6 +213,6 @@ class JenkinsGetViewConfigTest(JenkinsViewsTestBase):
|
||||
self.j.get_view_config(u'Test View')
|
||||
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('view/Test%20View/config.xml'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
@ -3,6 +3,7 @@ from mock import patch
|
||||
|
||||
import jenkins
|
||||
from tests.base import JenkinsTestBase
|
||||
from tests.helper import build_response_mock
|
||||
|
||||
|
||||
class JenkinsWhoamiTest(JenkinsTestBase):
|
||||
@ -29,22 +30,19 @@ class JenkinsWhoamiTest(JenkinsTestBase):
|
||||
|
||||
self.assertEqual(user, user_to_return)
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
jenkins_mock.call_args[0][0].url,
|
||||
self.make_url('me/api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'jenkins_open')
|
||||
def test_raise_HTTPError(self, jenkins_mock):
|
||||
jenkins_mock.side_effect = jenkins.HTTPError(
|
||||
self.make_url('me/api/json'),
|
||||
code=401,
|
||||
msg='basic auth failed',
|
||||
hdrs=[],
|
||||
fp=None)
|
||||
@patch('jenkins.requests.Session.send', autospec=True)
|
||||
def test_raise_HTTPError(self, session_send_mock):
|
||||
session_send_mock.side_effect = iter([
|
||||
build_response_mock(404, reason="Not Found"), # crumb
|
||||
build_response_mock(401, reason="Basic Auth Failed"), # request
|
||||
])
|
||||
|
||||
with self.assertRaises(jenkins.JenkinsException):
|
||||
self.j.get_whoami()
|
||||
self.assertEqual(
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
session_send_mock.call_args_list[1][0][1].url,
|
||||
self.make_url('me/api/json'))
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
Loading…
Reference in New Issue
Block a user