Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2081)

Unified Diff: appengine/findit/waterfall/identify_try_job_culprit_pipeline.py

Issue 2230103002: [Findit] Pipeline change to save suspected cls to data store. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@0808-resubmit-suspected_cl_model
Patch Set: rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine/findit/waterfall/identify_try_job_culprit_pipeline.py
diff --git a/appengine/findit/waterfall/identify_try_job_culprit_pipeline.py b/appengine/findit/waterfall/identify_try_job_culprit_pipeline.py
index 3116dbc8d12e6205eb085232b4c38b5be27e13d7..303211272cda6091271e46bd25d7d8ba5aab47f0 100644
--- a/appengine/findit/waterfall/identify_try_job_culprit_pipeline.py
+++ b/appengine/findit/waterfall/identify_try_job_culprit_pipeline.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
from collections import defaultdict
+import copy
import logging
from google.appengine.ext import ndb
@@ -11,6 +12,7 @@ from common.git_repository import GitRepository
from common.http_client_appengine import HttpClientAppengine as HttpClient
from common.pipeline_wrapper import BasePipeline
from common.waterfall import failure_type
+from model import analysis_approach_type
from model import analysis_status
from model import result_status
from model.wf_analysis import WfAnalysis
@@ -18,6 +20,7 @@ from model.wf_try_job import WfTryJob
from model.wf_try_job_data import WfTryJobData
from waterfall.send_notification_for_culprit_pipeline import (
SendNotificationForCulpritPipeline)
+from waterfall import suspected_cl_util
GIT_REPO = GitRepository(
@@ -51,13 +54,14 @@ def _GetResultAnalysisStatus(analysis, result):
return old_result_status
-def _GetSuspectedCLs(analysis, result):
+def _GetSuspectedCLs(analysis, try_job_type, result, culprits):
"""Returns a list of suspected CLs.
Args:
analysis: The WfAnalysis entity corresponding to this try job.
- result: A result dict containing the culprit from the results of
- this try job.
+ try_job_type: Try job type, COMPILE or TEST, the same with failure type.
+ result: A result dict containing the result of this try job.
+ culprits: A list of suspected CLs found by the try job.
Returns:
A combined list of suspected CLs from those already in analysis and those
@@ -65,37 +69,19 @@ def _GetSuspectedCLs(analysis, result):
"""
suspected_cls = analysis.suspected_cls[:] if analysis.suspected_cls else []
suspected_cl_revisions = [cl['revision'] for cl in suspected_cls]
- culprit = result.get('culprit')
- compile_cl_info = culprit.get('compile')
- if compile_cl_info:
- # Suspected CL is from compile failure.
- revision = compile_cl_info.get('revision')
+ for revision, try_job_suspected_cl in culprits.iteritems():
+ suspected_cl_copy = copy.deepcopy(try_job_suspected_cl)
if revision not in suspected_cl_revisions:
suspected_cl_revisions.append(revision)
- suspected_cls.append(compile_cl_info)
- return suspected_cls
-
- # Suspected CLs are from test failures.
- for results in culprit.itervalues():
- if results.get('revision'):
- # Non swarming test failures, only have step level failure info.
- revision = results.get('revision')
- cl_info = {
- 'url': results.get('url'),
- 'repo_name': results.get('repo_name'),
- 'revision': results.get('revision'),
- 'commit_position': results.get('commit_position')
- }
- if revision not in suspected_cl_revisions:
- suspected_cl_revisions.append(revision)
- suspected_cls.append(cl_info)
- else:
- for test_cl_info in results['tests'].values():
- revision = test_cl_info.get('revision')
- if revision not in suspected_cl_revisions:
- suspected_cl_revisions.append(revision)
- suspected_cls.append(test_cl_info)
+ if try_job_type == failure_type.COMPILE:
+ failures = {'compile': []}
+ else:
+ failures = _GetTestFailureCausedByCL(
+ result.get('report', {}).get('result', {}).get(revision))
+ suspected_cl_copy['failures'] = failures
+ suspected_cl_copy['top_score'] = None
+ suspected_cls.append(suspected_cl_copy)
return suspected_cls
@@ -168,10 +154,6 @@ def _GetCulpritsForTestsFromResultsDict(blame_list, test_results):
culprit_map[step] = {
'tests': {}
}
- if (not test_result['failures'] and
- not culprit_map[step].get('revision')):
- # Non swarming test failures, only have step level failure info.
- culprit_map[step]['revision'] = revision
for failed_test in test_result['failures']:
# Swarming tests, gets first failed revision for each test.
if failed_test not in culprit_map[step]['tests']:
@@ -241,6 +223,18 @@ def _NotifyCulprits(master_name, builder_name, build_number, culprits,
send_notification_right_now=True)
+def _GetTestFailureCausedByCL(result):
+ if not result:
+ return None
+
+ failures = {}
+ for step_name, step_result in result.iteritems():
+ if step_result['status'] == 'failed':
+ failures[step_name] = step_result['failures']
+
+ return failures
+
+
class IdentifyTryJobCulpritPipeline(BasePipeline):
"""A pipeline to identify culprit CL info based on try job compile results."""
@@ -270,7 +264,7 @@ class IdentifyTryJobCulpritPipeline(BasePipeline):
culprit_map = defaultdict(dict)
failed_revisions = set()
- # Recipe should return culprits with the farmat as:
+ # Recipe should return culprits with the format as:
# 'culprits': {
# 'step1': {
# 'test1': 'rev1',
@@ -295,11 +289,6 @@ class IdentifyTryJobCulpritPipeline(BasePipeline):
def _UpdateCulpritMapWithCulpritInfo(self, culprit_map, culprits):
"""Fills in commit_position and review url for each failed rev in map."""
for step_culprit in culprit_map.values():
- if step_culprit.get('revision'):
- culprit = culprits[step_culprit['revision']]
- step_culprit['commit_position'] = culprit['commit_position']
- step_culprit['url'] = culprit['url']
- step_culprit['repo_name'] = culprit['repo_name']
for test_culprit in step_culprit.get('tests', {}).values():
test_revision = test_culprit['revision']
test_culprit.update(culprits[test_revision])
@@ -308,12 +297,9 @@ class IdentifyTryJobCulpritPipeline(BasePipeline):
"""Gets culprit revision for each failure for try job metadata."""
culprit_data = {}
for step, step_culprit in culprit_map.iteritems():
- if step_culprit['tests']:
- culprit_data[step] = {}
- for test, test_culprit in step_culprit['tests'].iteritems():
- culprit_data[step][test] = test_culprit['revision']
- else:
- culprit_data[step] = step_culprit['revision']
+ culprit_data[step] = {}
+ for test, test_culprit in step_culprit['tests'].iteritems():
+ culprit_data[step][test] = test_culprit['revision']
return culprit_data
# Arguments number differs from overridden method - pylint: disable=W0221
@@ -373,14 +359,32 @@ class IdentifyTryJobCulpritPipeline(BasePipeline):
# Update analysis result and suspected CLs with results of this try job if
# culprits were found.
updated_result_status = _GetResultAnalysisStatus(analysis, result)
- updated_suspected_cls = _GetSuspectedCLs(analysis, result)
-
+ updated_suspected_cls = _GetSuspectedCLs(
+ analysis, try_job_type, result, culprits)
if (analysis.result_status != updated_result_status or
analysis.suspected_cls != updated_suspected_cls):
analysis.result_status = updated_result_status
analysis.suspected_cls = updated_suspected_cls
analysis.put()
+ def UpdateSuspectedCLs():
+ if not culprits:
+ return
+
+ # Creates or updates each suspected_cl.
+ for culprit in culprits.values():
+ revision = culprit['revision']
+ if try_job_type == failure_type.COMPILE:
+ failures = {'compile': []}
+ else:
+ failures = _GetTestFailureCausedByCL(
+ result.get('report', {}).get('result', {}).get(revision))
+
+ suspected_cl_util.UpdateSuspectedCL(
+ culprit['repo_name'], revision, culprit.get('commit_position'),
+ analysis_approach_type.TRY_JOB, master_name, builder_name,
+ build_number, try_job_type, failures, None)
+
# Store try-job results.
UpdateTryJobResult()
@@ -395,6 +399,11 @@ class IdentifyTryJobCulpritPipeline(BasePipeline):
# Add try-job results to WfAnalysis.
UpdateWfAnalysisWithTryJobResult()
+ # TODO (chanli): Update suspected_cl for builds in the same group with
+ # current build.
+ # Updates suspected_cl.
+ UpdateSuspectedCLs()
+
_NotifyCulprits(master_name, builder_name, build_number, culprits,
heuristic_cls, compile_suspected_cl)
return result.get('culprit') if result else None
« no previous file with comments | « appengine/findit/waterfall/identify_culprit_pipeline.py ('k') | appengine/findit/waterfall/suspected_cl_util.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698