| 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 datetime import datetime |
| 5 import logging | 6 import logging |
| 6 | 7 |
| 7 from google.appengine.ext import ndb | 8 from google.appengine.ext import ndb |
| 8 | 9 |
| 9 from common import appengine_util | 10 from common import appengine_util |
| 10 from common import constants | 11 from common import constants |
| 11 from common.waterfall import failure_type | 12 from common.waterfall import failure_type |
| 12 from model import analysis_status | 13 from model import analysis_status |
| 14 from model.wf_build import WfBuild |
| 13 from model.wf_try_job import WfTryJob | 15 from model.wf_try_job import WfTryJob |
| 14 from waterfall import swarming_tasks_to_try_job_pipeline | 16 from waterfall import swarming_tasks_to_try_job_pipeline |
| 15 from waterfall import waterfall_config | 17 from waterfall import waterfall_config |
| 16 from waterfall.try_job_type import TryJobType | 18 from waterfall.try_job_type import TryJobType |
| 17 | 19 |
| 18 | 20 |
| 19 def _CheckFailureForTryJobKey( | 21 def _CheckFailureForTryJobKey( |
| 20 master_name, builder_name, build_number, | 22 master_name, builder_name, build_number, |
| 21 failure_result_map, failed_step_or_test, failure): | 23 failure_result_map, failed_step_or_test, failure): |
| 22 """Compares the current_failure and first_failure for each failed_step/test. | 24 """Compares the current_failure and first_failure for each failed_step/test. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 def _GetSuspectsFromHeuristicResult(heuristic_result): | 140 def _GetSuspectsFromHeuristicResult(heuristic_result): |
| 139 suspected_revisions = set() | 141 suspected_revisions = set() |
| 140 if not heuristic_result: | 142 if not heuristic_result: |
| 141 return list(suspected_revisions) | 143 return list(suspected_revisions) |
| 142 for failure in heuristic_result.get('failures', []): | 144 for failure in heuristic_result.get('failures', []): |
| 143 for cl in failure['suspected_cls']: | 145 for cl in failure['suspected_cls']: |
| 144 suspected_revisions.add(cl['revision']) | 146 suspected_revisions.add(cl['revision']) |
| 145 return list(suspected_revisions) | 147 return list(suspected_revisions) |
| 146 | 148 |
| 147 | 149 |
| 150 def _ShouldBailOutForOutdatedBuild(build): |
| 151 return (datetime.utcnow() - build.start_time).days > 0 |
| 152 |
| 153 |
| 148 def ScheduleTryJobIfNeeded(failure_info, signals, heuristic_result): | 154 def ScheduleTryJobIfNeeded(failure_info, signals, heuristic_result): |
| 149 master_name = failure_info['master_name'] | 155 master_name = failure_info['master_name'] |
| 150 builder_name = failure_info['builder_name'] | 156 builder_name = failure_info['builder_name'] |
| 151 build_number = failure_info['build_number'] | 157 build_number = failure_info['build_number'] |
| 152 failed_steps = failure_info.get('failed_steps', []) | 158 failed_steps = failure_info.get('failed_steps', []) |
| 153 builds = failure_info.get('builds', {}) | 159 builds = failure_info.get('builds', {}) |
| 154 | 160 |
| 161 # Bail out if the build data's timestamp is more than 24 hours old to |
| 162 # avoid using outdated revisions. TODO(lijeffrey): This will also disallow |
| 163 # manually triggering try jobs more than a day old using build_completed=1. |
| 164 # Need to implement a flag to force try jobs regardless of timestamp. |
| 165 build = WfBuild.Get(master_name, builder_name, build_number) |
| 166 if _ShouldBailOutForOutdatedBuild(build): |
| 167 logging.error( |
| 168 'Build time is more than 24 hours old. Try job will not be triggered.') |
| 169 return {} |
| 170 |
| 155 tryserver_mastername, tryserver_buildername = ( | 171 tryserver_mastername, tryserver_buildername = ( |
| 156 waterfall_config.GetTrybotForWaterfallBuilder(master_name, builder_name)) | 172 waterfall_config.GetTrybotForWaterfallBuilder(master_name, builder_name)) |
| 157 | 173 |
| 158 if not tryserver_mastername or not tryserver_buildername: | 174 if not tryserver_mastername or not tryserver_buildername: |
| 159 logging.info('%s, %s is not supported yet.', master_name, builder_name) | 175 logging.info('%s, %s is not supported yet.', master_name, builder_name) |
| 160 return {} | 176 return {} |
| 161 elif (failure_info['failure_type'] == failure_type.TEST and | 177 elif (failure_info['failure_type'] == failure_type.TEST and |
| 162 waterfall_config.ShouldSkipTestTryJobs(master_name, builder_name)): | 178 waterfall_config.ShouldSkipTestTryJobs(master_name, builder_name)): |
| 163 logging.info('Test try jobs on %s, %s are not supported yet.', | 179 logging.info('Test try jobs on %s, %s are not supported yet.', |
| 164 master_name, builder_name) | 180 master_name, builder_name) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 pipeline.pipeline_status_path, try_job_type) | 212 pipeline.pipeline_status_path, try_job_type) |
| 197 else: # pragma: no cover | 213 else: # pragma: no cover |
| 198 logging_str = ( | 214 logging_str = ( |
| 199 'Try job was scheduled for build %s, %s, %s: %s because of %s ' | 215 'Try job was scheduled for build %s, %s, %s: %s because of %s ' |
| 200 'failure.') % ( | 216 'failure.') % ( |
| 201 master_name, builder_name, build_number, | 217 master_name, builder_name, build_number, |
| 202 pipeline.pipeline_status_path, try_job_type) | 218 pipeline.pipeline_status_path, try_job_type) |
| 203 logging.info(logging_str) | 219 logging.info(logging_str) |
| 204 | 220 |
| 205 return failure_result_map | 221 return failure_result_map |
| OLD | NEW |