build_job: return queue item identifier

Since Jenkins version 1.519 (released 2013/06/17), build_job() would
always return an empty string (the empty HTTP body from the POST
request).

Read the HTTP response's Location header and return the queue ID number.

Clients can use this number to query server for the the upcoming job's
status.

Change-Id: I2a1ef3abb7e675e0ad37dd8eb4a377af22f27a03
Closes-Bug: #1724932
This commit is contained in:
Ken Dreyer 2018-04-17 02:52:48 -06:00
parent f3ba366a69
commit 91ab3d9057
2 changed files with 47 additions and 49 deletions

View File

@ -1175,9 +1175,17 @@ class Jenkins(object):
:param name: name of job
:param parameters: parameters for job, or ``None``, ``dict``
:param token: Jenkins API token
:returns: ``int`` queue item
'''
return self.jenkins_open(requests.Request(
response = self.jenkins_request(requests.Request(
'POST', self.build_job_url(name, parameters, token)))
location = response.headers['Location']
# location is a queue item, eg. "http://jenkins/queue/item/25/"
if location.endswith('/'):
location = location[:-1]
parts = location.split('/')
number = int(parts[-1])
return number
def run_script(self, script):
'''Execute a groovy script on the jenkins master.

View File

@ -1,76 +1,66 @@
from mock import patch
import jenkins
from tests.helper import build_response_mock
from tests.jobs.base import JenkinsJobsTestBase
class JenkinsBuildJobTest(JenkinsJobsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
jenkins_mock.side_effect = [
{'foo': 'bar'},
]
@patch('jenkins.requests.Session.send', autospec=True)
def test_simple(self, session_send_mock):
session_send_mock.return_value = build_response_mock(
302, {}, headers={'Location': self.make_url('/queue/item/25/')})
build_info = self.j.build_job(u'Test Job')
queue_id = self.j.build_job(u'Test Job')
self.assertEqual(jenkins_mock.call_args[0][0].url,
self.assertEqual(session_send_mock.call_args[0][1].url,
self.make_url('job/Test%20Job/build'))
self.assertEqual(build_info, {'foo': 'bar'})
self._check_requests(jenkins_mock.call_args_list)
self.assertEqual(queue_id, 25)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_in_folder(self, jenkins_mock):
jenkins_mock.side_effect = [
{'foo': 'bar'},
]
@patch('jenkins.requests.Session.send', autospec=True)
def test_in_folder(self, session_send_mock):
session_send_mock.return_value = build_response_mock(
302, {}, headers={'Location': self.make_url('/queue/item/25/')})
build_info = self.j.build_job(u'a Folder/Test Job')
queue_id = self.j.build_job(u'a Folder/Test Job')
self.assertEqual(jenkins_mock.call_args[0][0].url,
self.assertEqual(session_send_mock.call_args[0][1].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)
self.assertEqual(queue_id, 25)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_with_token(self, jenkins_mock):
jenkins_mock.side_effect = [
{'foo': 'bar'},
]
@patch('jenkins.requests.Session.send', autospec=True)
def test_with_token(self, session_send_mock):
session_send_mock.return_value = build_response_mock(
302, {}, headers={'Location': self.make_url('/queue/item/25/')})
build_info = self.j.build_job(u'TestJob', token='some_token')
queue_id = self.j.build_job(u'TestJob', token='some_token')
self.assertEqual(jenkins_mock.call_args[0][0].url,
self.assertEqual(session_send_mock.call_args[0][1].url,
self.make_url('job/TestJob/build?token=some_token'))
self.assertEqual(build_info, {'foo': 'bar'})
self._check_requests(jenkins_mock.call_args_list)
self.assertEqual(queue_id, 25)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_in_folder_with_token(self, jenkins_mock):
jenkins_mock.side_effect = [
{'foo': 'bar'},
]
@patch('jenkins.requests.Session.send', autospec=True)
def test_in_folder_with_token(self, session_send_mock):
session_send_mock.return_value = build_response_mock(
302, {}, headers={'Location': self.make_url('/queue/item/25/')})
build_info = self.j.build_job(u'a Folder/TestJob', token='some_token')
queue_id = self.j.build_job(u'a Folder/TestJob', token='some_token')
self.assertEqual(jenkins_mock.call_args[0][0].url,
self.assertEqual(session_send_mock.call_args[0][1].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)
self.assertEqual(queue_id, 25)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_with_parameters_and_token(self, jenkins_mock):
jenkins_mock.side_effect = [
{'foo': 'bar'},
]
@patch('jenkins.requests.Session.send', autospec=True)
def test_with_parameters_and_token(self, session_send_mock):
session_send_mock.return_value = build_response_mock(
302, {}, headers={'Location': self.make_url('/queue/item/25/')})
build_info = self.j.build_job(
queue_id = self.j.build_job(
u'TestJob',
parameters={'when': 'now', 'why': 'because I felt like it'},
token='some_token')
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)
self.assertTrue('token=some_token' in session_send_mock.call_args[0][1].url)
self.assertTrue('when=now' in session_send_mock.call_args[0][1].url)
self.assertTrue('why=because+I+felt+like+it' in session_send_mock.call_args[0][1].url)
self.assertEqual(queue_id, 25)