Map failed jobs to bugs in gerrit comment

Instead of just listing which bugs were seen in an entire gerrit event
(multiple jenkins/zuul jobs), list which bugs were seen in which job.
If one of the jobs has an unrecognized error don't display the comment
about running recheck, just list which bugs were seen on which jobs (and
which has an unrecognized error)

Change-Id: I55b2eb8f0efe43ab22540294150d4bc9f5885510
This commit is contained in:
Joe Gordon 2014-02-04 15:26:24 -08:00
parent 2308b4a947
commit 61190329f7
2 changed files with 74 additions and 8 deletions

View File

@ -112,13 +112,41 @@ class FailEvent(object):
def name(self):
return "%s,%s" % (self.change, self.rev)
def bug_urls(self):
if not self.get_all_bugs():
def bug_urls(self, bugs=None):
if bugs is None:
bugs = self.get_all_bugs()
if not bugs:
return None
urls = ['https://bugs.launchpad.net/bugs/%s' % x for
x in self.get_all_bugs()]
x in bugs]
return urls
def bug_urls_map(self):
"""Produce map of which jobs failed due to which bugs."""
if not self.get_all_bugs():
return None
bug_map = {}
for job in self.failed_jobs:
if len(job.bugs) is 0:
bug_map[job.name] = None
else:
bug_map[job.name] = ', '.join(self.bug_urls(job.bugs))
bug_list = []
for job in bug_map:
if bug_map[job] is None:
bug_list.append("%s: unrecognized error" % job)
else:
bug_list.append("%s: %s" % (job, bug_map[job]))
return bug_list
def is_fully_classified(self):
if self.get_all_bugs() is None:
return True
for job in self.failed_jobs:
if len(job.bugs) is 0:
return False
return True
def queue(self):
# Assume one queue per gerrit event
if len(self.failed_jobs) == 0:
@ -288,19 +316,23 @@ class Stream(object):
def leave_comment(self, event, debug=False):
if event.get_all_bugs():
message = """I noticed tempest failed, I think you hit bug(s):
message = """I noticed jenkins failed, I think you hit bug(s):
- %(bugs)s
""" % {'bugs': "\n- ".join(event.bug_urls_map())}
if event.is_fully_classified():
message += """
We don't automatically recheck or reverify, so please consider
doing that manually if someone hasn't already. For a code review
which is not yet approved, you can recheck by leaving a code
review comment with just the text:
recheck bug %(bug)s""" % {'bugs': "\n- ".join(event.bug_urls()),
'bug': list(event.get_all_bugs())[0]}
recheck bug %(bug)s""" % {'bug': list(event.get_all_bugs())[0]}
else:
message += """
You have some unrecognized errors."""
else:
message = ("I noticed tempest failed, refer to: "
message = ("I noticed jenkins failed, refer to: "
"https://wiki.openstack.org/wiki/"
"GerritJenkinsGithub#Test_Failures")
LOG.debug("Compiled comment for commit %s:\n%s" %

View File

@ -50,10 +50,12 @@ class TestStream(tests.TestCase):
self.assertTrue(event.is_openstack_project())
self.assertEqual(event.queue(), "check")
self.assertEqual(event.bug_urls(), None)
self.assertEqual(event.bug_urls_map(), None)
self.assertEqual(sorted(event.failed_job_names()),
['gate-keystone-python26',
'gate-keystone-python27'])
self.assertEqual(event.get_all_bugs(), None)
self.assertTrue(event.is_fully_classified())
event = stream.get_failed_tempest()
self.assertEqual(event.change, "63078")
@ -108,3 +110,35 @@ class TestStream(tests.TestCase):
self.assertNotIn('gate-tempest-dsvm-neutron-large-ops', job_names)
self.assertNotIn('check-grenade-dsvm', job_names)
self.assertNotIn('check-swift-dsvm-functional', job_names)
def test_event(self):
with mock.patch.object(
elasticRecheck.Stream, '_does_es_have_data') as mock_data:
mock_data.return_value = True
stream = elasticRecheck.Stream("", "", "")
event = stream.get_failed_tempest()
# Add bugs
for job in event.failed_jobs:
if job.name == 'gate-keystone-python26':
job.bugs = ['123456']
self.assertEqual(event.change, "64749")
self.assertEqual(event.rev, "6")
self.assertEqual(event.project, "openstack/keystone")
self.assertEqual(event.name(), "64749,6")
self.assertEqual(event.url, "https://review.openstack.org/64749")
self.assertEqual(sorted(event.short_build_uuids()),
["5dd41fe", "d3fd328"])
self.assertTrue(event.is_openstack_project())
self.assertEqual(event.queue(), "check")
self.assertEqual(event.bug_urls(),
['https://bugs.launchpad.net/bugs/123456'])
self.assertEqual(event.bug_urls_map(),
['gate-keystone-python27: unrecognized error',
'gate-keystone-python26: '
'https://bugs.launchpad.net/bugs/123456'])
self.assertEqual(sorted(event.failed_job_names()),
['gate-keystone-python26',
'gate-keystone-python27'])
self.assertEqual(event.get_all_bugs(), ['123456'])
self.assertFalse(event.is_fully_classified())