| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import base64 | 5 import base64 |
| 6 import json | 6 import json |
| 7 | 7 |
| 8 from common import constants | 8 from common import constants |
| 9 from common.http_client_appengine import HttpClientAppengine as HttpClient | 9 from common.http_client_appengine import HttpClientAppengine as HttpClient |
| 10 from common.pipeline_wrapper import BasePipeline | 10 from common.pipeline_wrapper import BasePipeline |
| 11 from common.pipeline_wrapper import pipeline | 11 from common.pipeline_wrapper import pipeline |
| 12 from common.waterfall import failure_type | 12 from common.waterfall import failure_type |
| 13 from model.wf_analysis import WfAnalysis | 13 from model.wf_analysis import WfAnalysis |
| 14 from model.wf_step import WfStep | 14 from model.wf_step import WfStep |
| 15 from waterfall import build_util | 15 from waterfall import build_util |
| 16 from waterfall import buildbot | 16 from waterfall import buildbot |
| 17 from waterfall import swarming_util | 17 from waterfall import swarming_util |
| 18 | 18 |
| 19 | 19 |
| 20 _MAX_BUILDS_TO_CHECK = 20 | 20 _MAX_BUILDS_TO_CHECK = 20 |
| 21 _NON_FAILURE_STATUS = ['SUCCESS', 'SKIPPED', 'UNKNOWN'] |
| 21 | 22 |
| 22 | 23 |
| 23 class DetectFirstFailurePipeline(BasePipeline): | 24 class DetectFirstFailurePipeline(BasePipeline): |
| 24 """A pipeline to detect first failure of each step. | 25 """A pipeline to detect first failure of each step. |
| 25 | 26 |
| 26 TODO(stgao): do test-level detection for gtest. | 27 TODO(stgao): do test-level detection for gtest. |
| 27 """ | 28 """ |
| 28 | 29 |
| 29 def _ExtractBuildInfo(self, master_name, builder_name, build_number): | 30 def _ExtractBuildInfo(self, master_name, builder_name, build_number): |
| 30 """Returns a BuildInfo instance for the specified build.""" | 31 """Returns a BuildInfo instance for the specified build.""" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 self, json_data, step, failed_step=None): | 175 self, json_data, step, failed_step=None): |
| 175 """Parses the json data and saves all the reliable failures to the step.""" | 176 """Parses the json data and saves all the reliable failures to the step.""" |
| 176 failed_test_log = {} | 177 failed_test_log = {} |
| 177 if failed_step: | 178 if failed_step: |
| 178 failed_step['tests'] = {} | 179 failed_step['tests'] = {} |
| 179 | 180 |
| 180 for iteration in json_data.get('per_iteration_data'): | 181 for iteration in json_data.get('per_iteration_data'): |
| 181 for test_name in iteration.keys(): | 182 for test_name in iteration.keys(): |
| 182 is_reliable_failure = True | 183 is_reliable_failure = True |
| 183 | 184 |
| 184 if any(test['status'] == 'SUCCESS' for test in iteration[test_name]): | 185 if (any(test['status'] in _NON_FAILURE_STATUS |
| 185 # Ignore the test if any of the attempts were 'SUCCESS'. | 186 for test in iteration[test_name])): |
| 187 # Ignore the test if any of the attempts didn't fail. |
| 188 # If a test is skipped, that means it was not run at all. |
| 189 # Treats it as success since the status cannot be determined. |
| 186 is_reliable_failure = False | 190 is_reliable_failure = False |
| 187 | 191 |
| 188 if is_reliable_failure: | 192 if is_reliable_failure: |
| 189 if failed_step: | 193 if failed_step: |
| 190 # Adds the test to failed_step. | 194 # Adds the test to failed_step. |
| 191 failed_step['tests'][test_name] = { | 195 failed_step['tests'][test_name] = { |
| 192 'current_failure': failed_step['current_failure'], | 196 'current_failure': failed_step['current_failure'], |
| 193 'first_failure': failed_step['current_failure'], | 197 'first_failure': failed_step['current_failure'], |
| 194 } | 198 } |
| 195 if failed_step.get('last_pass'): | 199 if failed_step.get('last_pass'): |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 | 466 |
| 463 failure_info['builds'] = builds | 467 failure_info['builds'] = builds |
| 464 failure_info['failed_steps'] = failed_steps | 468 failure_info['failed_steps'] = failed_steps |
| 465 | 469 |
| 466 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | 470 analysis = WfAnalysis.Get(master_name, builder_name, build_number) |
| 467 analysis.not_passed_steps = build_info.not_passed_steps | 471 analysis.not_passed_steps = build_info.not_passed_steps |
| 468 analysis.build_failure_type = build_failure_type | 472 analysis.build_failure_type = build_failure_type |
| 469 analysis.put() | 473 analysis.put() |
| 470 | 474 |
| 471 return failure_info | 475 return failure_info |
| OLD | NEW |