From 91ab3d90576b3394d18b5c3963bbde74cda4d60f Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Tue, 17 Apr 2018 02:52:48 -0600 Subject: [PATCH] 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 --- jenkins/__init__.py | 10 ++++- tests/jobs/test_build.py | 86 ++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/jenkins/__init__.py b/jenkins/__init__.py index 4da66c1..94b178e 100755 --- a/jenkins/__init__.py +++ b/jenkins/__init__.py @@ -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. diff --git a/tests/jobs/test_build.py b/tests/jobs/test_build.py index 07e17c4..a603bcc 100644 --- a/tests/jobs/test_build.py +++ b/tests/jobs/test_build.py @@ -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)