Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 | |
| 190 for failure in analysis.result.get('failures', []): | |
| 191 if (failure['step_name'].lower() == 'compile' and | |
| 192 len(failure['suspected_cls']) == 1): | |
| 193 # Based on confidence calculation, suspected_cl found by heuristic for | |
| 194 # compile is very likely to be the culprit. | |
| 195 # Since the current confidence calculation is for results with single | |
| 196 # suspected_cl, we might need to have the same regulation here. | |
| 197 return failure['suspected_cls'][0] | |
| 198 return None | |
| 199 | |
| 200 | |
| 201 def _GetHeuristicSuspectedCLs(analysis): | |
| 202 """Gets revisions of suspected cls found by heuristic approach.""" | |
| 203 if analysis and analysis.suspected_cls: | |
| 204 return [(cl['repo_name'], cl['revision']) for cl in analysis.suspected_cls] | |
| 205 return [] | |
| 206 | |
| 207 | |
| 208 def _StartSendNotificationPipeline( | |
| 209 master_name, builder_name, build_number, repo_name, revision, | |
| 210 send_notification_right_now): | |
| 211 try: | |
| 212 pipeline = SendNotificationForCulpritPipeline( | |
| 213 master_name, builder_name, build_number, repo_name, revision, | |
| 214 send_notification_right_now) | |
| 215 pipeline.start() | |
| 216 except Exception: # pragma: no cover. | |
| 217 logging.exception('Failed to notify culprit.') | |
| 218 | |
| 219 | |
| 220 def _NotifyCulprits(master_name, builder_name, build_number, culprits, | |
| 221 heuristic_cls, compile_suspected_cl): | |
| 186 """Sends notifications to the identified culprits.""" | 222 """Sends notifications to the identified culprits.""" |
| 187 try: | 223 |
| 188 for culprit in (culprits or {}).itervalues(): | 224 if culprits: |
| 189 pipeline = SendNotificationForCulpritPipeline( | 225 # There is a try job result, so check if any of the culprits |
| 226 # was also found by heuristic analysis. | |
| 227 for culprit in culprits.itervalues(): | |
| 228 send_notification_right_now = False | |
| 229 if (culprit['repo_name'], culprit['revision']) in heuristic_cls: | |
| 230 send_notification_right_now = True | |
|
stgao
2016/09/08 21:20:46
Just do:
flag = data in list
chanli
2016/09/08 22:05:01
Done.
| |
| 231 _StartSendNotificationPipeline( | |
| 190 master_name, builder_name, build_number, | 232 master_name, builder_name, build_number, |
| 191 culprit['repo_name'], culprit['revision']) | 233 culprit['repo_name'], culprit['revision'], |
| 192 pipeline.start() | 234 send_notification_right_now) |
| 193 except Exception: # pragma: no cover. | 235 elif compile_suspected_cl: |
| 194 logging.exception('Failed to notify culprits.') | 236 # Need to check if the failure is compile and heuristic found a culprit. |
|
stgao
2016/09/08 21:20:46
What's this comment for?
chanli
2016/09/08 22:05:01
To explain the special case where try job didn't f
| |
| 237 _StartSendNotificationPipeline( | |
| 238 master_name, builder_name, build_number, | |
| 239 compile_suspected_cl['repo_name'], compile_suspected_cl['revision'], | |
| 240 send_notification_right_now=True) | |
| 195 | 241 |
| 196 | 242 |
| 197 class IdentifyTryJobCulpritPipeline(BasePipeline): | 243 class IdentifyTryJobCulpritPipeline(BasePipeline): |
| 198 """A pipeline to identify culprit CL info based on try job compile results.""" | 244 """A pipeline to identify culprit CL info based on try job compile results.""" |
| 199 | 245 |
| 200 def _GetCulpritInfo(self, failed_revisions): | 246 def _GetCulpritInfo(self, failed_revisions): |
| 201 """Gets commit_positions and review urls for revisions.""" | 247 """Gets commit_positions and review urls for revisions.""" |
| 202 culprits = {} | 248 culprits = {} |
| 203 # TODO(lijeffrey): remove hard-coded 'chromium' when DEPS file parsing is | 249 # TODO(lijeffrey): remove hard-coded 'chromium' when DEPS file parsing is |
| 204 # supported. | 250 # supported. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 try_job_result.status = analysis_status.COMPLETED | 363 try_job_result.status = analysis_status.COMPLETED |
| 318 try_job_result.put() | 364 try_job_result.put() |
| 319 | 365 |
| 320 @ndb.transactional | 366 @ndb.transactional |
| 321 def UpdateWfAnalysisWithTryJobResult(): | 367 def UpdateWfAnalysisWithTryJobResult(): |
| 322 if not culprits: | 368 if not culprits: |
| 323 return | 369 return |
| 324 | 370 |
| 325 # Update analysis result and suspected CLs with results of this try job if | 371 # Update analysis result and suspected CLs with results of this try job if |
| 326 # culprits were found. | 372 # culprits were found. |
| 327 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | |
| 328 updated_result_status = _GetResultAnalysisStatus(analysis, result) | 373 updated_result_status = _GetResultAnalysisStatus(analysis, result) |
| 329 updated_suspected_cls = _GetSuspectedCLs(analysis, result) | 374 updated_suspected_cls = _GetSuspectedCLs(analysis, result) |
| 330 | 375 |
| 331 if (analysis.result_status != updated_result_status or | 376 if (analysis.result_status != updated_result_status or |
| 332 analysis.suspected_cls != updated_suspected_cls): | 377 analysis.suspected_cls != updated_suspected_cls): |
| 333 analysis.result_status = updated_result_status | 378 analysis.result_status = updated_result_status |
| 334 analysis.suspected_cls = updated_suspected_cls | 379 analysis.suspected_cls = updated_suspected_cls |
| 335 analysis.put() | 380 analysis.put() |
| 336 | 381 |
| 337 # Store try-job results. | 382 # Store try-job results. |
| 338 UpdateTryJobResult() | 383 UpdateTryJobResult() |
| 384 | |
| 385 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | |
|
stgao
2016/09/08 21:20:46
nit: need a comment for this as discussed.
chanli
2016/09/08 22:05:01
Done.
| |
| 386 heuristic_cls = _GetHeuristicSuspectedCLs(analysis) | |
| 387 compile_suspected_cl = ( | |
| 388 _GetSuspectedCLFoundByHeuristicForCompile(analysis) | |
| 389 if try_job_type == failure_type.COMPILE else None) | |
| 390 | |
| 339 # Add try-job results to WfAnalysis. | 391 # Add try-job results to WfAnalysis. |
| 340 UpdateWfAnalysisWithTryJobResult() | 392 UpdateWfAnalysisWithTryJobResult() |
| 341 | 393 |
| 342 _NotifyCulprits(master_name, builder_name, build_number, culprits) | 394 _NotifyCulprits(master_name, builder_name, build_number, culprits, |
| 343 return result.get('culprit') if result else None | 395 heuristic_cls, compile_suspected_cl) |
| 396 return result.get('culprit') if result else None | |
| OLD | NEW |