| 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 |
| 11 from common.http_client_appengine import HttpClientAppengine as HttpClient | 11 from common.http_client_appengine import HttpClientAppengine as HttpClient |
| 12 from common.pipeline_wrapper import BasePipeline | 12 from common.pipeline_wrapper import BasePipeline |
| 13 from common.waterfall import failure_type |
| 13 from model import analysis_status | 14 from model import analysis_status |
| 14 from model import result_status | 15 from model import result_status |
| 15 from model.wf_analysis import WfAnalysis | 16 from model.wf_analysis import WfAnalysis |
| 16 from model.wf_try_job import WfTryJob | 17 from model.wf_try_job import WfTryJob |
| 17 from model.wf_try_job_data import WfTryJobData | 18 from model.wf_try_job_data import WfTryJobData |
| 18 from waterfall.try_job_type import TryJobType | |
| 19 from waterfall.send_notification_for_culprit_pipeline import ( | 19 from waterfall.send_notification_for_culprit_pipeline import ( |
| 20 SendNotificationForCulpritPipeline) | 20 SendNotificationForCulpritPipeline) |
| 21 | 21 |
| 22 | 22 |
| 23 GIT_REPO = GitRepository( | 23 GIT_REPO = GitRepository( |
| 24 'https://chromium.googlesource.com/chromium/src.git', HttpClient()) | 24 'https://chromium.googlesource.com/chromium/src.git', HttpClient()) |
| 25 | 25 |
| 26 | 26 |
| 27 def _GetResultAnalysisStatus(analysis, result): | 27 def _GetResultAnalysisStatus(analysis, result): |
| 28 """Returns the analysis status based on existing status and try job result. | 28 """Returns the analysis status based on existing status and try job result. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 def run( | 273 def run( |
| 274 self, master_name, builder_name, build_number, blame_list, try_job_type, | 274 self, master_name, builder_name, build_number, blame_list, try_job_type, |
| 275 try_job_id, result): | 275 try_job_id, result): |
| 276 """Identifies the information for failed revisions. | 276 """Identifies the information for failed revisions. |
| 277 | 277 |
| 278 Please refer to try_job_result_format.md for format check. | 278 Please refer to try_job_result_format.md for format check. |
| 279 """ | 279 """ |
| 280 culprits = None | 280 culprits = None |
| 281 if result and result.get('report'): | 281 if result and result.get('report'): |
| 282 try_job_data = WfTryJobData.Get(try_job_id) | 282 try_job_data = WfTryJobData.Get(try_job_id) |
| 283 if try_job_type == TryJobType.COMPILE: | 283 if try_job_type == failure_type.COMPILE: |
| 284 # For compile failures, the try job will stop if one revision fails, so | 284 # For compile failures, the try job will stop if one revision fails, so |
| 285 # the culprit will be the last revision in the result. | 285 # the culprit will be the last revision in the result. |
| 286 failed_revision = _GetFailedRevisionFromCompileResult(result) | 286 failed_revision = _GetFailedRevisionFromCompileResult(result) |
| 287 failed_revisions = [failed_revision] if failed_revision else [] | 287 failed_revisions = [failed_revision] if failed_revision else [] |
| 288 culprits = self._GetCulpritInfo(failed_revisions) | 288 culprits = self._GetCulpritInfo(failed_revisions) |
| 289 if culprits: | 289 if culprits: |
| 290 result['culprit'] = { | 290 result['culprit'] = { |
| 291 'compile': culprits[failed_revision] | 291 'compile': culprits[failed_revision] |
| 292 } | 292 } |
| 293 try_job_data.culprits = {'compile': failed_revision} | 293 try_job_data.culprits = {'compile': failed_revision} |
| 294 else: # try_job_type is 'test'. | 294 else: # try_job_type is 'test'. |
| 295 culprit_map, failed_revisions = self._FindCulpritForEachTestFailure( | 295 culprit_map, failed_revisions = self._FindCulpritForEachTestFailure( |
| 296 blame_list, result) | 296 blame_list, result) |
| 297 culprits = self._GetCulpritInfo(failed_revisions) | 297 culprits = self._GetCulpritInfo(failed_revisions) |
| 298 if culprits: | 298 if culprits: |
| 299 self._UpdateCulpritMapWithCulpritInfo(culprit_map, culprits) | 299 self._UpdateCulpritMapWithCulpritInfo(culprit_map, culprits) |
| 300 result['culprit'] = culprit_map | 300 result['culprit'] = culprit_map |
| 301 try_job_data.culprits = self._GetCulpritDataForTest(culprit_map) | 301 try_job_data.culprits = self._GetCulpritDataForTest(culprit_map) |
| 302 try_job_data.put() | 302 try_job_data.put() |
| 303 | 303 |
| 304 @ndb.transactional | 304 @ndb.transactional |
| 305 def UpdateTryJobResult(): | 305 def UpdateTryJobResult(): |
| 306 try_job_result = WfTryJob.Get(master_name, builder_name, build_number) | 306 try_job_result = WfTryJob.Get(master_name, builder_name, build_number) |
| 307 if culprits: | 307 if culprits: |
| 308 result_to_update = ( | 308 result_to_update = ( |
| 309 try_job_result.compile_results if | 309 try_job_result.compile_results if |
| 310 try_job_type == TryJobType.COMPILE else | 310 try_job_type == failure_type.COMPILE else |
| 311 try_job_result.test_results) | 311 try_job_result.test_results) |
| 312 if (result_to_update and | 312 if (result_to_update and |
| 313 result_to_update[-1]['try_job_id'] == try_job_id): | 313 result_to_update[-1]['try_job_id'] == try_job_id): |
| 314 result_to_update[-1].update(result) | 314 result_to_update[-1].update(result) |
| 315 else: # pragma: no cover | 315 else: # pragma: no cover |
| 316 result_to_update.append(result) | 316 result_to_update.append(result) |
| 317 try_job_result.status = analysis_status.COMPLETED | 317 try_job_result.status = analysis_status.COMPLETED |
| 318 try_job_result.put() | 318 try_job_result.put() |
| 319 | 319 |
| 320 @ndb.transactional | 320 @ndb.transactional |
| (...skipping 13 matching lines...) Expand all Loading... |
| 334 analysis.suspected_cls = updated_suspected_cls | 334 analysis.suspected_cls = updated_suspected_cls |
| 335 analysis.put() | 335 analysis.put() |
| 336 | 336 |
| 337 # Store try-job results. | 337 # Store try-job results. |
| 338 UpdateTryJobResult() | 338 UpdateTryJobResult() |
| 339 # Add try-job results to WfAnalysis. | 339 # Add try-job results to WfAnalysis. |
| 340 UpdateWfAnalysisWithTryJobResult() | 340 UpdateWfAnalysisWithTryJobResult() |
| 341 | 341 |
| 342 _NotifyCulprits(master_name, builder_name, build_number, culprits) | 342 _NotifyCulprits(master_name, builder_name, build_number, culprits) |
| 343 return result.get('culprit') if result else None | 343 return result.get('culprit') if result else None |
| OLD | NEW |