Chromium Code Reviews| Index: appengine/findit/waterfall/send_notification_for_culprit_pipeline.py |
| diff --git a/appengine/findit/waterfall/send_notification_for_culprit_pipeline.py b/appengine/findit/waterfall/send_notification_for_culprit_pipeline.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..220c751430a8d97ec168677a1fdb159f3811330a |
| --- /dev/null |
| +++ b/appengine/findit/waterfall/send_notification_for_culprit_pipeline.py |
| @@ -0,0 +1,79 @@ |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import logging |
| +import textwrap |
| + |
| +from google.appengine.ext import ndb |
| + |
| +from common.git_repository import GitRepository |
| +from common.http_client_appengine import HttpClientAppengine as HttpClient |
| +from common.pipeline_wrapper import BasePipeline |
| +from common.rietveld import Rietveld |
| +from model import analysis_status as status |
| +from model.wf_culprit import WfCulprit |
| + |
| + |
| +@ndb.transactional |
| +def _ShouldSendNotification( |
| + master_name, builder_name, build_number, repo_name, revision): |
| + """Returns True if a notification for the culprit should be sent.""" |
| + culprit = WfCulprit.Get(repo_name, revision) |
|
lijeffrey
2016/06/21 00:07:35
nit: how about
culprit = WfCulprit.Get(repo_name,
stgao
2016/06/21 15:14:29
Good idea! Done.
|
| + if not culprit: |
| + culprit = WfCulprit.Create(repo_name, revision) |
| + if [master_name, builder_name, build_number] in culprit.failed_builds: |
| + return False |
| + |
| + culprit.failed_builds.append([master_name, builder_name, build_number]) |
| + # Send notification when the culprit is for 2+ failures in two different |
| + # builds to avoid false positive due to flakiness. |
|
chanli
2016/06/21 17:50:31
Do you have data to back up this idea? What percen
stgao
2016/06/24 16:10:28
This is from data in the InCorrect-Found. Only one
chanli
2016/06/24 23:42:38
I'm not sure about it: I can see quite several cas
|
| + should_send = len(culprit.failed_builds) >= 2 # TODO(stgao): move to config. |
|
lijeffrey
2016/06/21 00:07:34
is it possible to merge these 2?
i.e.
should_sen
stgao
2016/06/21 15:14:29
Done.
|
| + if culprit.notification_status in (status.COMPLETED, status.RUNNING): |
| + should_send = False # Already being processed by another pipeline. |
| + if should_send: |
| + culprit.notification_status = status.RUNNING |
| + culprit.put() |
| + return should_send |
| + |
| + |
| +@ndb.transactional |
| +def _UpdateNotificationStatus(repo_name, revision, new_status): |
| + culprit = WfCulprit.Get(repo_name, revision) |
| + culprit.notification_status = new_status |
| + culprit.put() |
| + |
| + |
| +def _SendNotificationForCulprit(repo_name, revision): |
| + # TODO(stgao): get repo url at runtime based on the given repo name. |
| + repo = GitRepository( |
| + 'https://chromium.googlesource.com/chromium/src.git', HttpClient()) |
| + change_log = repo.GetChangeLog(revision) |
| + sent = False |
| + if change_log.code_review_url: |
| + # Occasionally, a commit was not uploaded for code-review. |
| + culprit = WfCulprit.Get(repo_name, revision) |
| + rietveld = Rietveld() |
| + message = textwrap.dedent(""" |
| + Findit Try-job identified this CL (revision %s) as the culprit for failures |
| + in the build cycle(s) as shown on: |
| + https://findit-for-me.appspot.com/waterfall/culprit?key=%s |
| + """) % (revision, culprit.key().urlsafe()) |
| + sent = rietveld.PostMessage(change_log.code_review_url, message) |
| + else: |
| + logging.error('Can not get code-review url for %s/%s', repo_name, revision) |
| + |
| + _UpdateNotificationStatus(repo_name, revision, |
| + status.COMPLETED if sent else status.ERROR) |
| + return sent |
| + |
| + |
| +class SendNotificationForCulpritPipeline(BasePipeline): |
| + |
| + # Arguments number differs from overridden method - pylint: disable=W0221 |
| + def run(self, master_name, builder_name, build_number, repo_name, revision): |
| + if not _ShouldSendNotification( |
| + master_name, builder_name, build_number, repo_name, revision): |
| + return False |
| + return _SendNotificationForCulprit( |
| + master_name, builder_name, build_number, repo_name, revision) |