| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 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 """A command to fetch new baselines from try jobs for a Rietveld issue. | 5 """A command to fetch new baselines from try jobs for a Rietveld issue. |
| 6 | 6 |
| 7 This command interacts with the Rietveld API to get information about try jobs | 7 This command interacts with the Rietveld API to get information about try jobs |
| 8 with layout test results. | 8 with layout test results. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import logging | 11 import logging |
| 12 import optparse | 12 import optparse |
| 13 | 13 |
| 14 from webkitpy.common.checkout.scm.git import Git | 14 from webkitpy.common.checkout.scm.git import Git |
| 15 from webkitpy.common.net.buildbot import Build | 15 from webkitpy.common.net.buildbot import Build |
| 16 from webkitpy.common.net.rietveld import Rietveld | 16 from webkitpy.common.net.rietveld import Rietveld |
| 17 from webkitpy.common.net.web import Web | 17 from webkitpy.common.net.web import Web |
| 18 from webkitpy.common.net.git_cl import GitCL |
| 18 from webkitpy.common.webkit_finder import WebKitFinder | 19 from webkitpy.common.webkit_finder import WebKitFinder |
| 19 from webkitpy.layout_tests.models.test_expectations import BASELINE_SUFFIX_LIST | 20 from webkitpy.layout_tests.models.test_expectations import BASELINE_SUFFIX_LIST |
| 20 from webkitpy.tool.commands.rebaseline import AbstractParallelRebaselineCommand | 21 from webkitpy.tool.commands.rebaseline import AbstractParallelRebaselineCommand |
| 21 | 22 |
| 22 | |
| 23 _log = logging.getLogger(__name__) | 23 _log = logging.getLogger(__name__) |
| 24 | 24 |
| 25 | 25 |
| 26 class RebaselineCL(AbstractParallelRebaselineCommand): | 26 class RebaselineCL(AbstractParallelRebaselineCommand): |
| 27 name = "rebaseline-cl" | 27 name = "rebaseline-cl" |
| 28 help_text = "Fetches new baselines for a CL from test runs on try bots." | 28 help_text = "Fetches new baselines for a CL from test runs on try bots." |
| 29 long_help = ("By default, this command will check the latest try results " | 29 long_help = ("By default, this command will check the latest try job results
" |
| 30 "and download new baselines for any tests that have been " | 30 "for all platforms, and start try jobs for platforms with no " |
| 31 "changed in the given CL that have failed and have new " | 31 "try jobs. Then, new baselines are downloaded for any tests " |
| 32 "baselines. After downloading, the baselines for different " | 32 "that are being rebaselined. After downloading, the baselines " |
| 33 "platforms should be optimized (conslidated).") | 33 "for different platforms will be optimized (consolidated).") |
| 34 show_in_main_help = True | 34 show_in_main_help = True |
| 35 | 35 |
| 36 def __init__(self): | 36 def __init__(self): |
| 37 super(RebaselineCL, self).__init__(options=[ | 37 super(RebaselineCL, self).__init__(options=[ |
| 38 optparse.make_option( | 38 optparse.make_option( |
| 39 '--issue', type='int', default=None, | 39 '--issue', type='int', default=None, |
| 40 help='Rietveld issue number; if none given, this will be obtaine
d via `git cl issue`.'), | 40 help='Rietveld issue number; if none given, this will be obtaine
d via `git cl issue`.'), |
| 41 optparse.make_option( | 41 optparse.make_option( |
| 42 '--dry-run', action='store_true', default=False, | 42 '--dry-run', action='store_true', default=False, |
| 43 help='Dry run mode; list actions that would be performed but do
not do anything.'), | 43 help='Dry run mode; list actions that would be performed but do
not do anything.'), |
| 44 optparse.make_option( | 44 optparse.make_option( |
| 45 '--only-changed-tests', action='store_true', default=False, | 45 '--only-changed-tests', action='store_true', default=False, |
| 46 help='Only download new baselines for tests that are changed in
the CL.'), | 46 help='Only download new baselines for tests that are changed in
the CL.'), |
| 47 optparse.make_option( |
| 48 '--no-trigger-jobs', dest='trigger_jobs', action='store_false',
default=True, |
| 49 help='Do not trigger any try jobs.'), |
| 47 self.no_optimize_option, | 50 self.no_optimize_option, |
| 48 self.results_directory_option, | 51 self.results_directory_option, |
| 49 ]) | 52 ]) |
| 50 self.rietveld = Rietveld(Web()) | 53 self.rietveld = Rietveld(Web()) |
| 51 | 54 |
| 52 def execute(self, options, args, tool): | 55 def execute(self, options, args, tool): |
| 53 issue_number = self._get_issue_number(options) | 56 issue_number = self._get_issue_number(options) |
| 54 if not issue_number: | 57 if not issue_number: |
| 55 return | 58 return |
| 59 |
| 60 builds = self.rietveld.latest_try_jobs(issue_number, self._try_bots()) |
| 61 if options.trigger_jobs: |
| 62 self.trigger_jobs_for_missing_builds(builds) |
| 63 |
| 56 if args: | 64 if args: |
| 57 test_prefix_list = {} | 65 test_prefix_list = {} |
| 58 try_jobs = self.rietveld.latest_try_jobs(issue_number, self._try_bot
s()) | |
| 59 builds = [Build(j.builder_name, j.build_number) for j in try_jobs] | |
| 60 for test in args: | 66 for test in args: |
| 61 test_prefix_list[test] = {b: BASELINE_SUFFIX_LIST for b in build
s} | 67 test_prefix_list[test] = {b: BASELINE_SUFFIX_LIST for b in build
s} |
| 62 else: | 68 else: |
| 63 test_prefix_list = self._test_prefix_list( | 69 test_prefix_list = self._test_prefix_list( |
| 64 issue_number, only_changed_tests=options.only_changed_tests) | 70 issue_number, only_changed_tests=options.only_changed_tests) |
| 65 self._log_test_prefix_list(test_prefix_list) | 71 self._log_test_prefix_list(test_prefix_list) |
| 66 | 72 |
| 67 if options.dry_run: | 73 if options.dry_run: |
| 68 return | 74 return |
| 69 self._rebaseline(options, test_prefix_list, update_scm=False) | 75 self._rebaseline(options, test_prefix_list, update_scm=False) |
| 70 | 76 |
| 71 def _get_issue_number(self, options): | 77 def _get_issue_number(self, options): |
| 72 """Gets the Rietveld CL number from either |options| or from the current
local branch.""" | 78 """Gets the Rietveld CL number from either |options| or from the current
local branch.""" |
| 73 if options.issue: | 79 if options.issue: |
| 74 return options.issue | 80 return options.issue |
| 75 issue_number = self.git().get_issue_number() | 81 issue_number = self.git().get_issue_number() |
| 76 _log.debug('Issue number for current branch: %s', issue_number) | 82 _log.debug('Issue number for current branch: %s', issue_number) |
| 77 if not issue_number.isdigit(): | 83 if not issue_number.isdigit(): |
| 78 _log.error('No issue number given and no issue for current branch.') | 84 _log.error('No issue number given and no issue for current branch.') |
| 79 return None | 85 return None |
| 80 return int(issue_number) | 86 return int(issue_number) |
| 81 | 87 |
| 82 def git(self): | 88 def git(self): |
| 83 """Returns a Git instance; can be overridden for tests.""" | 89 """Returns a Git instance; can be overridden for tests.""" |
| 84 # Pass in a current working directory inside of the repo so | 90 # Pass in a current working directory inside of the repo so |
| 85 # that this command can be called from outside of the repo. | 91 # that this command can be called from outside of the repo. |
| 86 return Git(cwd=self._tool.filesystem.dirname(self._tool.path())) | 92 return Git(cwd=self._tool.filesystem.dirname(self._tool.path())) |
| 87 | 93 |
| 94 def trigger_jobs_for_missing_builds(self, builds): |
| 95 builders_with_builds = {b.builder_name for b in builds} |
| 96 builders_without_builds = set(self._try_bots()) - builders_with_builds |
| 97 if not builders_without_builds: |
| 98 return |
| 99 _log.info('Triggering try jobs for: %s', ', '.join(sorted(builders_witho
ut_builds))) |
| 100 git_cl = GitCL(self._tool.executive) |
| 101 command = ['try'] |
| 102 for builder in sorted(builders_without_builds): |
| 103 command += ['-b', builder] |
| 104 git_cl.run(command) |
| 105 |
| 88 def _test_prefix_list(self, issue_number, only_changed_tests): | 106 def _test_prefix_list(self, issue_number, only_changed_tests): |
| 89 """Returns a collection of test, builder and file extensions to get new
baselines for. | 107 """Returns a collection of test, builder and file extensions to get new
baselines for. |
| 90 | 108 |
| 91 Args: | 109 Args: |
| 92 issue_number: The CL number of the change which needs new baselines. | 110 issue_number: The CL number of the change which needs new baselines. |
| 93 only_changed_tests: Whether to only include baselines for tests that | 111 only_changed_tests: Whether to only include baselines for tests that |
| 94 are changed in this CL. If False, all new baselines for failing | 112 are changed in this CL. If False, all new baselines for failing |
| 95 tests will be downloaded, even for tests that were not modified. | 113 tests will be downloaded, even for tests that were not modified. |
| 96 | 114 |
| 97 Returns: | 115 Returns: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 @staticmethod | 160 @staticmethod |
| 143 def _log_test_prefix_list(test_prefix_list): | 161 def _log_test_prefix_list(test_prefix_list): |
| 144 """Logs the tests to download new baselines for.""" | 162 """Logs the tests to download new baselines for.""" |
| 145 if not test_prefix_list: | 163 if not test_prefix_list: |
| 146 _log.info('No tests to rebaseline.') | 164 _log.info('No tests to rebaseline.') |
| 147 return | 165 return |
| 148 _log.info('Tests to rebaseline:') | 166 _log.info('Tests to rebaseline:') |
| 149 for test, builds in test_prefix_list.iteritems(): | 167 for test, builds in test_prefix_list.iteritems(): |
| 150 builds_str = ', '.join(sorted('%s (%s)' % (b.builder_name, b.build_n
umber) for b in builds)) | 168 builds_str = ', '.join(sorted('%s (%s)' % (b.builder_name, b.build_n
umber) for b in builds)) |
| 151 _log.info(' %s: %s', test, builds_str) | 169 _log.info(' %s: %s', test, builds_str) |
| OLD | NEW |