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

Side by Side Diff: appengine/findit/waterfall/identify_try_job_culprit_pipeline.py

Issue 2302223002: [Findit] Change the criteria of sending notification to code review. (Closed)
Patch Set: Address comments Created 4 years, 3 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 unified diff | Download patch
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from collections import defaultdict 5 from collections import defaultdict
6 import logging 6 import logging
7 7
8 from google.appengine.ext import ndb 8 from google.appengine.ext import ndb
9 9
10 from common.git_repository import GitRepository 10 from common.git_repository import GitRepository
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 for failed_test in test_result['failures']: 175 for failed_test in test_result['failures']:
176 # Swarming tests, gets first failed revision for each test. 176 # Swarming tests, gets first failed revision for each test.
177 if failed_test not in culprit_map[step]['tests']: 177 if failed_test not in culprit_map[step]['tests']:
178 culprit_map[step]['tests'][failed_test] = { 178 culprit_map[step]['tests'][failed_test] = {
179 'revision': revision 179 'revision': revision
180 } 180 }
181 181
182 return culprit_map, list(failed_revisions) 182 return culprit_map, list(failed_revisions)
183 183
184 184
185 def _NotifyCulprits(master_name, builder_name, build_number, culprits): 185 def _GetSuspectedCLFoundByHeuristicForCompile(analysis):
186 """For compile failure, gets the suspected revision found by heuristic."""
187 if not analysis or not analysis.result:
188 return None
189 for failure in analysis.result.get('failures', []):
190 if (failure['step_name'].lower() == 'compile' and
191 len(failure['suspected_cls']) == 1):
192 # Based on confidence calculation, suspected_cl found by heuristic for
193 # compile is very likely to be the culprit.
194 # Since the current confidence calculation is for results with single
195 # suspected_cl, we might need to have the same regulation here.
196 return failure['suspected_cls'][0]
197 return None
198
199
200 def _GetHeuristicSuspectedCLs(analysis):
201 """Gets revisions of suspected cls found by heuristic approach."""
202 if analysis and analysis.suspected_cls:
203 return [(cl['repo_name'], cl['revision']) for cl in analysis.suspected_cls]
204 return []
205
206
207 def _StartSendNotificationPipeline(
208 master_name, builder_name, build_number, repo_name, revision):
209 try:
210 pipeline = SendNotificationForCulpritPipeline(
211 master_name, builder_name, build_number, repo_name, revision)
212 pipeline.start()
213 except Exception: # pragma: no cover.
214 logging.exception(
215 'Failed to notify culprits which was found by both approaches.')
216
217
218 def _NotifyCulprits(master_name, builder_name, build_number, culprits,
219 heuristic_cls, compile_suspected_cl):
186 """Sends notifications to the identified culprits.""" 220 """Sends notifications to the identified culprits."""
187 try: 221
188 for culprit in (culprits or {}).itervalues(): 222 if culprits:
Sharu Jiang 2016/09/02 18:00:22 If culprits mean try_job_cls, I think rename it to
chanli 2016/09/02 18:25:59 It is a convention to call a suspected_cl found by
189 pipeline = SendNotificationForCulpritPipeline( 223 # There is try job result, we need to check if any of the culprit
190 master_name, builder_name, build_number, 224 # was also found by heuristic.
191 culprit['repo_name'], culprit['revision']) 225 for culprit in culprits.itervalues():
192 pipeline.start() 226 if (culprit['repo_name'], culprit['revision']) in heuristic_cls:
193 except Exception: # pragma: no cover. 227 _StartSendNotificationPipeline(
194 logging.exception('Failed to notify culprits.') 228 master_name, builder_name, build_number,
229 culprit['repo_name'], culprit['revision'])
230 elif compile_suspected_cl:
231 # Need to check if the failure is compile and heuristic found a culprit.
232 _StartSendNotificationPipeline(
233 master_name, builder_name, build_number,
234 compile_suspected_cl['repo_name'], compile_suspected_cl['revision'])
195 235
196 236
197 class IdentifyTryJobCulpritPipeline(BasePipeline): 237 class IdentifyTryJobCulpritPipeline(BasePipeline):
198 """A pipeline to identify culprit CL info based on try job compile results.""" 238 """A pipeline to identify culprit CL info based on try job compile results."""
199 239
200 def _GetCulpritInfo(self, failed_revisions): 240 def _GetCulpritInfo(self, failed_revisions):
201 """Gets commit_positions and review urls for revisions.""" 241 """Gets commit_positions and review urls for revisions."""
202 culprits = {} 242 culprits = {}
203 # TODO(lijeffrey): remove hard-coded 'chromium' when DEPS file parsing is 243 # TODO(lijeffrey): remove hard-coded 'chromium' when DEPS file parsing is
204 # supported. 244 # supported.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 try_job_result.status = analysis_status.COMPLETED 357 try_job_result.status = analysis_status.COMPLETED
318 try_job_result.put() 358 try_job_result.put()
319 359
320 @ndb.transactional 360 @ndb.transactional
321 def UpdateWfAnalysisWithTryJobResult(): 361 def UpdateWfAnalysisWithTryJobResult():
322 if not culprits: 362 if not culprits:
323 return 363 return
324 364
325 # Update analysis result and suspected CLs with results of this try job if 365 # Update analysis result and suspected CLs with results of this try job if
326 # culprits were found. 366 # culprits were found.
327 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
328 updated_result_status = _GetResultAnalysisStatus(analysis, result) 367 updated_result_status = _GetResultAnalysisStatus(analysis, result)
329 updated_suspected_cls = _GetSuspectedCLs(analysis, result) 368 updated_suspected_cls = _GetSuspectedCLs(analysis, result)
330 369
331 if (analysis.result_status != updated_result_status or 370 if (analysis.result_status != updated_result_status or
332 analysis.suspected_cls != updated_suspected_cls): 371 analysis.suspected_cls != updated_suspected_cls):
333 analysis.result_status = updated_result_status 372 analysis.result_status = updated_result_status
334 analysis.suspected_cls = updated_suspected_cls 373 analysis.suspected_cls = updated_suspected_cls
335 analysis.put() 374 analysis.put()
336 375
337 # Store try-job results. 376 # Store try-job results.
338 UpdateTryJobResult() 377 UpdateTryJobResult()
378
379
Sharu Jiang 2016/09/02 18:00:22 nit: delete one empty line.
chanli 2016/09/02 18:25:59 Done.
380 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
381 heuristic_cls = _GetHeuristicSuspectedCLs(analysis)
382 compile_suspected_cl = (
383 _GetSuspectedCLFoundByHeuristicForCompile(analysis)
384 if try_job_type == failure_type.COMPILE else None)
385
339 # Add try-job results to WfAnalysis. 386 # Add try-job results to WfAnalysis.
340 UpdateWfAnalysisWithTryJobResult() 387 UpdateWfAnalysisWithTryJobResult()
341 388
342 _NotifyCulprits(master_name, builder_name, build_number, culprits) 389 _NotifyCulprits(master_name, builder_name, build_number, culprits,
343 return result.get('culprit') if result else None 390 heuristic_cls, compile_suspected_cl)
391 return result.get('culprit') if result else None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698