| 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 """Task queue endpoints for creating and updating issues on issue tracker.""" | 5 """Task queue endpoints for creating and updating issues on issue tracker.""" |
| 6 | 6 |
| 7 import datetime | 7 import datetime |
| 8 import json | 8 import json |
| 9 import logging | 9 import logging |
| 10 import urllib2 | 10 import urllib2 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 Flake, FlakeOccurrence, FlakeUpdate, FlakeUpdateSingleton, FlakyRun) | 22 Flake, FlakeOccurrence, FlakeUpdate, FlakeUpdateSingleton, FlakyRun) |
| 23 from model.build_run import BuildRun | 23 from model.build_run import BuildRun |
| 24 from status import build_result, util | 24 from status import build_result, util |
| 25 from test_results.util import normalize_test_type, flatten_tests_trie | 25 from test_results.util import normalize_test_type, flatten_tests_trie |
| 26 | 26 |
| 27 | 27 |
| 28 MAX_UPDATED_ISSUES_PER_DAY = 10 | 28 MAX_UPDATED_ISSUES_PER_DAY = 10 |
| 29 MAX_TIME_DIFFERENCE_SECONDS = 12 * 60 * 60 | 29 MAX_TIME_DIFFERENCE_SECONDS = 12 * 60 * 60 |
| 30 MIN_REQUIRED_FLAKY_RUNS = 3 | 30 MIN_REQUIRED_FLAKY_RUNS = 3 |
| 31 DAYS_TILL_STALE = 30 | 31 DAYS_TILL_STALE = 30 |
| 32 USE_MONORAIL = True | |
| 33 DAYS_TO_REOPEN_ISSUE = 3 | 32 DAYS_TO_REOPEN_ISSUE = 3 |
| 34 MAX_INDIVIDUAL_FLAKES_PER_STEP = 50 | 33 MAX_INDIVIDUAL_FLAKES_PER_STEP = 50 |
| 35 FLAKY_RUNS_TEMPLATE = ( | 34 FLAKY_RUNS_TEMPLATE = ( |
| 36 'Detected %(new_flakes_count)d new flakes for test/step "%(name)s". To see ' | 35 'Detected %(new_flakes_count)d new flakes for test/step "%(name)s". To see ' |
| 37 'the actual flakes, please visit %(flakes_url)s. This message was posted ' | 36 'the actual flakes, please visit %(flakes_url)s. This message was posted ' |
| 38 'automatically by the chromium-try-flakes app.%(suffix)s') | 37 'automatically by the chromium-try-flakes app.%(suffix)s') |
| 39 RETURN_TO_QUEUE_SUFFIX = ( | 38 RETURN_TO_QUEUE_SUFFIX = ( |
| 40 'Since flakiness is ongoing, the issue was moved back into %s (unless ' | 39 'Since flakiness is ongoing, the issue was moved back into %s (unless ' |
| 41 'already there).') | 40 'already there).') |
| 42 SUMMARY_TEMPLATE = '"%(name)s" is flaky' | 41 SUMMARY_TEMPLATE = '"%(name)s" is flaky' |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 self.issue_updates.increment_by(1, {'operation': 'create'}) | 279 self.issue_updates.increment_by(1, {'operation': 'create'}) |
| 281 logging.info('Created a new issue %d for flake %s', flake.issue_id, | 280 logging.info('Created a new issue %d for flake %s', flake.issue_id, |
| 282 flake.name) | 281 flake.name) |
| 283 | 282 |
| 284 delay = (now - self._get_first_flake_occurrence_time(flake)).total_seconds() | 283 delay = (now - self._get_first_flake_occurrence_time(flake)).total_seconds() |
| 285 self.reporting_delay.set(delay) | 284 self.reporting_delay.set(delay) |
| 286 logging.info('Reported reporting_delay %d for flake %s', delay, flake.name) | 285 logging.info('Reported reporting_delay %d for flake %s', delay, flake.name) |
| 287 | 286 |
| 288 @ndb.transactional(xg=True) # pylint: disable=E1120 | 287 @ndb.transactional(xg=True) # pylint: disable=E1120 |
| 289 def post(self, urlsafe_key): | 288 def post(self, urlsafe_key): |
| 290 api = issue_tracker_api.IssueTrackerAPI( | 289 api = issue_tracker_api.IssueTrackerAPI('chromium') |
| 291 'chromium', use_monorail=USE_MONORAIL) | |
| 292 | 290 |
| 293 # Check if we should stop processing this issue because we've posted too | 291 # Check if we should stop processing this issue because we've posted too |
| 294 # many updates to issue tracker today already. | 292 # many updates to issue tracker today already. |
| 295 day_ago = datetime.datetime.utcnow() - datetime.timedelta(days=1) | 293 day_ago = datetime.datetime.utcnow() - datetime.timedelta(days=1) |
| 296 num_updates_last_day = FlakeUpdate.query( | 294 num_updates_last_day = FlakeUpdate.query( |
| 297 FlakeUpdate.time_updated > day_ago, | 295 FlakeUpdate.time_updated > day_ago, |
| 298 ancestor=self._get_flake_update_singleton_key()).count() | 296 ancestor=self._get_flake_update_singleton_key()).count() |
| 299 if num_updates_last_day >= MAX_UPDATED_ISSUES_PER_DAY: | 297 if num_updates_last_day >= MAX_UPDATED_ISSUES_PER_DAY: |
| 300 return | 298 return |
| 301 | 299 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 def post(self, issue_id): | 343 def post(self, issue_id): |
| 346 """Check if an issue is stale and report it back to appropriate queue. | 344 """Check if an issue is stale and report it back to appropriate queue. |
| 347 | 345 |
| 348 Check if the issue is stale, i.e. has not been updated by anyone else than | 346 Check if the issue is stale, i.e. has not been updated by anyone else than |
| 349 this app in the last DAYS_TILL_STALE days, and if this is the case, then | 347 this app in the last DAYS_TILL_STALE days, and if this is the case, then |
| 350 move it back to the appropriate queue. Also if the issue is stale for 7 | 348 move it back to the appropriate queue. Also if the issue is stale for 7 |
| 351 days, report it to stale-flakes-reports@google.com to investigate why it is | 349 days, report it to stale-flakes-reports@google.com to investigate why it is |
| 352 not being processed despite being in the appropriate queue. | 350 not being processed despite being in the appropriate queue. |
| 353 """ | 351 """ |
| 354 issue_id = int(issue_id) | 352 issue_id = int(issue_id) |
| 355 api = issue_tracker_api.IssueTrackerAPI( | 353 api = issue_tracker_api.IssueTrackerAPI('chromium') |
| 356 'chromium', use_monorail=USE_MONORAIL) | |
| 357 flake_issue = api.getIssue(issue_id) | 354 flake_issue = api.getIssue(issue_id) |
| 358 now = datetime.datetime.utcnow() | 355 now = datetime.datetime.utcnow() |
| 359 | 356 |
| 360 if not flake_issue.open: | 357 if not flake_issue.open: |
| 361 # Remove issue_id from all flakes unless it has recently been updated. We | 358 # Remove issue_id from all flakes unless it has recently been updated. We |
| 362 # should not remove issue_id too soon, otherwise issues will get reopened | 359 # should not remove issue_id too soon, otherwise issues will get reopened |
| 363 # before changes made will propogate and reduce flakiness. | 360 # before changes made will propogate and reduce flakiness. |
| 364 recent_cutoff = now - datetime.timedelta(days=DAYS_TO_REOPEN_ISSUE) | 361 recent_cutoff = now - datetime.timedelta(days=DAYS_TO_REOPEN_ISSUE) |
| 365 if flake_issue.updated < recent_cutoff: | 362 if flake_issue.updated < recent_cutoff: |
| 366 self._remove_issue_from_flakes(issue_id) | 363 self._remove_issue_from_flakes(issue_id) |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 return | 669 return |
| 673 | 670 |
| 674 key = self.request.get('key') | 671 key = self.request.get('key') |
| 675 flake = ndb.Key(urlsafe=key).get() | 672 flake = ndb.Key(urlsafe=key).get() |
| 676 flake.issue_id = issue_id | 673 flake.issue_id = issue_id |
| 677 flake.put() | 674 flake.put() |
| 678 | 675 |
| 679 logging.info('%s updated issue_id for flake %s to %d.', user_email, | 676 logging.info('%s updated issue_id for flake %s to %d.', user_email, |
| 680 flake.name, issue_id) | 677 flake.name, issue_id) |
| 681 self.redirect('/all_flake_occurrences?key=%s' % key) | 678 self.redirect('/all_flake_occurrences?key=%s' % key) |
| OLD | NEW |