Check for 'Location' header in the response
If the keep_alive is not available because of using reverse proxy, the header 'Content-Lenght' may not be available, causing the exception: Error communicating with server[...]: empty response However, if 'Location' header is present, the response is valid. Add unit tests: - build_job must pass even if no 'content-lenght' in response header - build_job must fail if no 'location' in response header Change-Id: I4da6dd19f9d8302a76652a3686a9377f9a2503a6 Closes-Bug:#1775047
This commit is contained in:
parent
f7fa4ce059
commit
f420d6de01
@ -513,6 +513,7 @@ class Jenkins(object):
|
|||||||
headers = response.headers
|
headers = response.headers
|
||||||
if (headers.get('content-length') is None and
|
if (headers.get('content-length') is None and
|
||||||
headers.get('transfer-encoding') is None and
|
headers.get('transfer-encoding') is None and
|
||||||
|
headers.get('location') is None and
|
||||||
(response.content is None or len(response.content) <= 0)):
|
(response.content is None or len(response.content) <= 0)):
|
||||||
# response body should only exist if one of these is provided
|
# response body should only exist if one of these is provided
|
||||||
raise EmptyResponseException(
|
raise EmptyResponseException(
|
||||||
@ -1274,6 +1275,12 @@ class Jenkins(object):
|
|||||||
'''
|
'''
|
||||||
response = self.jenkins_request(requests.Request(
|
response = self.jenkins_request(requests.Request(
|
||||||
'POST', self.build_job_url(name, parameters, token)))
|
'POST', self.build_job_url(name, parameters, token)))
|
||||||
|
|
||||||
|
if 'Location' not in response.headers:
|
||||||
|
raise EmptyResponseException(
|
||||||
|
"Header 'Location' not found in "
|
||||||
|
"response from server[%s]" % self.server)
|
||||||
|
|
||||||
location = response.headers['Location']
|
location = response.headers['Location']
|
||||||
# location is a queue item, eg. "http://jenkins/queue/item/25/"
|
# location is a queue item, eg. "http://jenkins/queue/item/25/"
|
||||||
if location.endswith('/'):
|
if location.endswith('/'):
|
||||||
|
@ -78,14 +78,15 @@ class NullServer(socketserver.TCPServer):
|
|||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def build_response_mock(status_code, json_body=None, headers=None, **kwargs):
|
def build_response_mock(status_code, json_body=None, headers=None,
|
||||||
|
add_content_length=True, **kwargs):
|
||||||
real_response = requests.Response()
|
real_response = requests.Response()
|
||||||
real_response.status_code = status_code
|
real_response.status_code = status_code
|
||||||
|
|
||||||
text = None
|
text = None
|
||||||
if json_body is not None:
|
if json_body is not None:
|
||||||
text = json.dumps(json_body)
|
text = json.dumps(json_body)
|
||||||
if headers is not {}:
|
if add_content_length and headers is not {}:
|
||||||
real_response.headers['content-length'] = len(text)
|
real_response.headers['content-length'] = len(text)
|
||||||
|
|
||||||
if headers is not None:
|
if headers is not None:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
|
||||||
|
import jenkins
|
||||||
from six.moves.urllib.parse import quote
|
from six.moves.urllib.parse import quote
|
||||||
from tests.helper import build_response_mock
|
from tests.helper import build_response_mock
|
||||||
from tests.jobs.base import JenkinsJobsTestBase
|
from tests.jobs.base import JenkinsJobsTestBase
|
||||||
@ -19,6 +20,49 @@ class JenkinsBuildJobTest(JenkinsJobsTestBase):
|
|||||||
self.make_url(quote(u'job/Test Jøb/build'.encode('utf8'))))
|
self.make_url(quote(u'job/Test Jøb/build'.encode('utf8'))))
|
||||||
self.assertEqual(queue_id, 25)
|
self.assertEqual(queue_id, 25)
|
||||||
|
|
||||||
|
@patch('jenkins.requests.Session.send', autospec=True)
|
||||||
|
def test_assert_no_location(self, session_send_mock):
|
||||||
|
session_send_mock.return_value = build_response_mock(302, {})
|
||||||
|
|
||||||
|
with self.assertRaises(jenkins.EmptyResponseException) as context_mgr:
|
||||||
|
self.j.build_job(u'Test Job')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context_mgr.exception),
|
||||||
|
"Header 'Location' not found in response from server[{0}]".format(
|
||||||
|
self.make_url('')))
|
||||||
|
|
||||||
|
@patch.object(jenkins.Jenkins, 'maybe_add_crumb')
|
||||||
|
@patch('jenkins.requests.Session.send', autospec=True)
|
||||||
|
def test_simple_no_content_lenght(self, session_send_mock,
|
||||||
|
maybe_add_crumb_mock):
|
||||||
|
maybe_add_crumb_mock.return_value = None
|
||||||
|
session_send_mock.return_value = build_response_mock(
|
||||||
|
201, None, add_content_length=False,
|
||||||
|
headers={'Location': self.make_url('/queue/item/25/')})
|
||||||
|
|
||||||
|
queue_id = self.j.build_job(u'Test Job')
|
||||||
|
|
||||||
|
self.assertEqual(session_send_mock.call_args[0][1].url,
|
||||||
|
self.make_url('job/Test%20Job/build'))
|
||||||
|
self.assertEqual(queue_id, 25)
|
||||||
|
|
||||||
|
@patch.object(jenkins.Jenkins, 'maybe_add_crumb')
|
||||||
|
@patch('jenkins.requests.Session.send', autospec=True)
|
||||||
|
def test_assert_no_content_lenght_no_location(self, session_send_mock,
|
||||||
|
maybe_add_crumb_mock):
|
||||||
|
maybe_add_crumb_mock.return_value = None
|
||||||
|
session_send_mock.return_value = build_response_mock(
|
||||||
|
201, None, add_content_length=False)
|
||||||
|
|
||||||
|
with self.assertRaises(jenkins.EmptyResponseException) as context_mgr:
|
||||||
|
self.j.build_job(u'Test Job')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context_mgr.exception),
|
||||||
|
'Error communicating with server[{0}]: empty response'.format(
|
||||||
|
self.make_url('')))
|
||||||
|
|
||||||
@patch('jenkins.requests.Session.send', autospec=True)
|
@patch('jenkins.requests.Session.send', autospec=True)
|
||||||
def test_in_folder(self, session_send_mock):
|
def test_in_folder(self, session_send_mock):
|
||||||
session_send_mock.return_value = build_response_mock(
|
session_send_mock.return_value = build_response_mock(
|
||||||
|
Loading…
Reference in New Issue
Block a user