Fail Jenkins check if job is unknown

Currently, if there is there is no Jenkins job matching
the Cabot check, the check always succeeds.

This is particularly bad when jobs are renamed on Jenkins,
as Cabot stops monitoring it and never alerts on this.

Although Cabot is currently very relaxed when dealing with
Jenkins errors, since 94dcdf9 Cabot did fail on missing job.
This must have stopped working following a Jenkins API change.

Here, we catch the `jenkinsapi` `UnknownJob` exception and
set `status_code` to the value expected by the `run` method.
Also add a unit-test for that behaviour.

This is a quick fix ; but in general the entire run method
may need refactoring to not use `status_code` anymore,
We may want to consider dealiing with the `jenkinsapi` exceptions
in the `run` method rather than catching them in `get_job_status`
and setting the `status_code`.

Closes #537
This commit is contained in:
Jean-Fred Berthelot 2017-08-17 17:46:06 +01:00 committed by Jean-Frédéric
parent 95da5e54f3
commit bc0e0486d6
2 changed files with 37 additions and 15 deletions

View File

@ -1,6 +1,7 @@
from datetime import datetime
from jenkinsapi.jenkins import Jenkins
from jenkinsapi.custom_exceptions import UnknownJob
from celery.utils.log import get_task_logger
from django.conf import settings
from django.utils import timezone
@ -14,23 +15,27 @@ def _get_jenkins_client():
def get_job_status(jobname):
ret = {
'active': True,
'succeeded': False,
'active': None,
'succeeded': None,
'job_number': None,
'blocked_build_time': None,
'status_code': 200
}
client = _get_jenkins_client()
try:
job = client.get_job(jobname)
last_build = job.get_last_build()
job = client.get_job(jobname)
last_build = job.get_last_build()
ret['status_code'] = 200
ret['job_number'] = last_build.get_number()
ret['active'] = job.is_enabled()
ret['succeeded'] = (job.is_enabled()) and last_build.is_good()
ret['job_number'] = last_build.get_number()
ret['active'] = job.is_enabled()
ret['succeeded'] = (job.is_enabled()) and last_build.is_good()
if job.is_queued():
in_queued_since = job._data['queueItem']['inQueueSince'] # job.get_queue_item() crashes
time_blocked_since = datetime.utcfromtimestamp(
float(in_queued_since) / 1000).replace(tzinfo=timezone.utc)
ret['blocked_build_time'] = (timezone.now() - time_blocked_since).total_seconds()
return ret
if job.is_queued():
in_queued_since = job._data['queueItem']['inQueueSince'] # job.get_queue_item() crashes
time_blocked_since = datetime.utcfromtimestamp(
float(in_queued_since) / 1000).replace(tzinfo=timezone.utc)
ret['blocked_build_time'] = (timezone.now() - time_blocked_since).total_seconds()
return ret
except UnknownJob:
ret['status_code'] = 404
return ret

View File

@ -7,6 +7,7 @@ from cabot.cabotapp import jenkins
from django.utils import timezone
from datetime import timedelta
import jenkinsapi
from jenkinsapi.custom_exceptions import UnknownJob
class TestGetStatus(unittest.TestCase):
@ -80,3 +81,19 @@ class TestGetStatus(unittest.TestCase):
'status_code': 200
}
self.assertEqual(status, expected)
@patch("cabot.cabotapp.jenkins._get_jenkins_client")
def test_job_unknown(self, mock_jenkins):
self.mock_client.get_job.side_effect = UnknownJob()
mock_jenkins.return_value = self.mock_client
status = jenkins.get_job_status('unknown-job')
expected = {
'active': None,
'succeeded': None,
'job_number': None,
'blocked_build_time': None,
'status_code': 404
}
self.assertEqual(status, expected)