add get_queue_item() method

Pass in a queue ID number to discover a job's status, and possibly a job
URL.

Change-Id: I20541ec49cc30e5c74a6c596e02b3f42b2567fa5
Closes-Bug: #1724932
This commit is contained in:
Ken Dreyer 2018-04-17 02:52:51 -06:00
parent 91ab3d9057
commit 284c3d37b7
2 changed files with 74 additions and 0 deletions

View File

@ -101,6 +101,7 @@ JOB_INFO = '%(folder_url)sjob/%(short_name)s/api/json?depth=%(depth)s'
JOB_NAME = '%(folder_url)sjob/%(short_name)s/api/json?tree=name'
ALL_BUILDS = '%(folder_url)sjob/%(short_name)s/api/json?tree=allBuilds[number,url]'
Q_INFO = 'queue/api/json?depth=0'
Q_ITEM = 'queue/item/%(number)d/api/json'
CANCEL_QUEUE = 'queue/cancelItem?id=%(id)s'
CREATE_JOB = '%(folder_url)screateItem?name=%(short_name)s' # also post config.xml
CONFIG_JOB = '%(folder_url)sjob/%(short_name)s/config.xml'
@ -572,6 +573,34 @@ class Jenkins(object):
raise TimeoutException('Error in request: %s' % (e.reason))
raise JenkinsException('Error in request: %s' % (e.reason))
def get_queue_item(self, number):
'''Get information about a queued item (to-be-created job).
The returned dict will have a "why" key if the queued item is still
waiting for an executor.
The returned dict will have an "executable" key if the queued item is
running on an executor, or has completed running. Use this to
determine the job number / URL.
:param name: queue number, ``int``
:returns: dictionary of queued information, ``dict``
'''
url = self._build_url(Q_ITEM, locals())
try:
response = self.jenkins_open(requests.Request('GET', url))
if response:
return json.loads(response)
else:
raise JenkinsException('queue number[%d] does not exist'
% number)
except (req_exc.HTTPError, NotFoundException):
raise JenkinsException('queue number[%d] does not exist' % number)
except ValueError:
raise JenkinsException(
'Could not parse JSON info for queue number[%d]' % number
)
def get_build_info(self, name, number, depth=0):
'''Get build information dictionary.
@ -1172,6 +1201,12 @@ class Jenkins(object):
def build_job(self, name, parameters=None, token=None):
'''Trigger build job.
This method returns a queue item number that you can pass to
:meth:`Jenkins.get_queue_item`. Note that this queue number is only
valid for about five minutes after the job completes, so you should
get/poll the queue information as soon as possible to determine the
job's URL.
:param name: name of job
:param parameters: parameters for job, or ``None``, ``dict``
:param token: Jenkins API token

View File

@ -70,3 +70,42 @@ class JenkinsQueueInfoTest(JenkinsTestBase):
jenkins_mock.call_args[0][0].url,
self.make_url('queue/api/json?depth=0'))
self._check_requests(jenkins_mock.call_args_list)
class JenkinsQueueItemTest(JenkinsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
queue_item_to_return = {
u'_class': u'hudson.model.Queue$LeftItem',
u'actions': [{u'_class': u'hudson.model.CauseAction',
u'causes': [{u'_class': u'hudson.model.Cause$UserIdCause',
u'shortDescription': u'Started by user Bob',
u'userId': u'bsmith',
u'userName': u'Bob'}]}],
u'blocked': False,
u'buildable': False,
u'cancelled': False,
u'executable': {u'_class': u'hudson.model.FreeStyleBuild',
u'number': 198,
u'url': u'http://your_url/job/my_job/198/'},
u'id': 25,
u'inQueueSince': 1507914654469,
u'params': u'',
u'stuck': False,
u'task': {u'_class': u'hudson.model.FreeStyleProject',
u'color': u'red',
u'name': u'my_job',
u'url': u'http://your_url/job/my_job/'},
u'url': u'queue/item/25/',
u'why': None,
}
jenkins_mock.return_value = json.dumps(queue_item_to_return)
queue_item = self.j.get_queue_item(25)
self.assertEqual(queue_item, queue_item_to_return)
self.assertEqual(
jenkins_mock.call_args[0][0].url,
self.make_url('queue/item/25/api/json'))
self._check_requests(jenkins_mock.call_args_list)