| 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 download new baselines for NeedsRebaseline tests. | 5 """A command to download new baselines for NeedsRebaseline tests. |
| 6 | 6 |
| 7 This command checks the list of tests with NeedsRebaseline expectations, | 7 This command checks the list of tests with NeedsRebaseline expectations, |
| 8 and downloads the latest baselines for those tests from the results archived | 8 and downloads the latest baselines for those tests from the results archived |
| 9 by the continuous builders. | 9 by the continuous builders. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 import logging | 12 import logging |
| 13 import optparse | 13 import optparse |
| 14 import re | 14 import re |
| 15 import sys | 15 import sys |
| 16 import time | 16 import time |
| 17 import traceback | 17 import traceback |
| 18 import urllib2 | 18 import urllib2 |
| 19 | 19 |
| 20 from webkitpy.common.net.buildbot import Build, current_build_link | 20 from webkitpy.common.net.buildbot import Build, current_build_link |
| 21 from webkitpy.layout_tests.models.test_expectations import TestExpectations, BAS
ELINE_SUFFIX_LIST | 21 from webkitpy.layout_tests.models.test_expectations import TestExpectations, BAS
ELINE_SUFFIX_LIST |
| 22 from webkitpy.tool.commands.rebaseline import AbstractParallelRebaselineCommand | 22 from webkitpy.tool.commands.rebaseline import AbstractParallelRebaselineCommand,
TestBaselineSet |
| 23 | 23 |
| 24 | 24 |
| 25 _log = logging.getLogger(__name__) | 25 _log = logging.getLogger(__name__) |
| 26 | 26 |
| 27 | 27 |
| 28 class AutoRebaseline(AbstractParallelRebaselineCommand): | 28 class AutoRebaseline(AbstractParallelRebaselineCommand): |
| 29 name = 'auto-rebaseline' | 29 name = 'auto-rebaseline' |
| 30 help_text = 'Rebaselines any NeedsRebaseline lines in TestExpectations that
have cycled through all the bots.' | 30 help_text = 'Rebaselines any NeedsRebaseline lines in TestExpectations that
have cycled through all the bots.' |
| 31 AUTO_REBASELINE_BRANCH_NAME = 'auto-rebaseline-temporary-branch' | 31 AUTO_REBASELINE_BRANCH_NAME = 'auto-rebaseline-temporary-branch' |
| 32 AUTO_REBASELINE_ALT_BRANCH_NAME = 'auto-rebaseline-alt-temporary-branch' | 32 AUTO_REBASELINE_ALT_BRANCH_NAME = 'auto-rebaseline-alt-temporary-branch' |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 message += '%s\n\n' % self.link_to_patch(commit) | 143 message += '%s\n\n' % self.link_to_patch(commit) |
| 144 if bugs: | 144 if bugs: |
| 145 message += 'BUG=%s\n' % ','.join(bugs) | 145 message += 'BUG=%s\n' % ','.join(bugs) |
| 146 message += 'TBR=%s\n' % author | 146 message += 'TBR=%s\n' % author |
| 147 return message | 147 return message |
| 148 | 148 |
| 149 @staticmethod | 149 @staticmethod |
| 150 def link_to_patch(commit): | 150 def link_to_patch(commit): |
| 151 return 'https://chromium.googlesource.com/chromium/src/+/' + commit | 151 return 'https://chromium.googlesource.com/chromium/src/+/' + commit |
| 152 | 152 |
| 153 def get_test_prefix_list(self, tests): | 153 def _make_test_baseline_set(self, tests): |
| 154 test_prefix_list = {} | 154 test_baseline_set = TestBaselineSet(self._tool) |
| 155 lines_to_remove = {} | |
| 156 | |
| 157 for builder_name in self._release_builders(): | 155 for builder_name in self._release_builders(): |
| 158 port_name = self._tool.builders.port_name_for_builder_name(builder_n
ame) | 156 port_name = self._tool.builders.port_name_for_builder_name(builder_n
ame) |
| 159 port = self._tool.port_factory.get(port_name) | 157 port = self._tool.port_factory.get(port_name) |
| 160 expectations = TestExpectations(port, include_overrides=True) | 158 expectations = TestExpectations(port, include_overrides=True) |
| 161 for test in expectations.get_needs_rebaseline_failures(): | 159 for test in expectations.get_needs_rebaseline_failures(): |
| 162 if test not in tests: | 160 if test not in tests: |
| 163 continue | 161 continue |
| 164 | 162 test_baseline_set.add(test, Build(builder_name)) |
| 165 if test not in test_prefix_list: | 163 return test_baseline_set |
| 166 lines_to_remove[test] = [] | |
| 167 test_prefix_list[test] = {} | |
| 168 lines_to_remove[test].append(builder_name) | |
| 169 test_prefix_list[test][Build(builder_name)] = BASELINE_SUFFIX_LI
ST | |
| 170 | |
| 171 return test_prefix_list, lines_to_remove | |
| 172 | 164 |
| 173 def _run_git_cl_command(self, options, command): | 165 def _run_git_cl_command(self, options, command): |
| 174 subprocess_command = ['git', 'cl'] + command | 166 subprocess_command = ['git', 'cl'] + command |
| 175 if options.verbose: | 167 if options.verbose: |
| 176 subprocess_command.append('--verbose') | 168 subprocess_command.append('--verbose') |
| 177 if options.auth_refresh_token_json: | 169 if options.auth_refresh_token_json: |
| 178 subprocess_command.append('--auth-refresh-token-json') | 170 subprocess_command.append('--auth-refresh-token-json') |
| 179 subprocess_command.append(options.auth_refresh_token_json) | 171 subprocess_command.append(options.auth_refresh_token_json) |
| 180 | 172 |
| 181 process = self._tool.executive.popen(subprocess_command, stdout=self._to
ol.executive.PIPE, | 173 process = self._tool.executive.popen(subprocess_command, stdout=self._to
ol.executive.PIPE, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 if not tests: | 226 if not tests: |
| 235 _log.debug('No tests to rebaseline.') | 227 _log.debug('No tests to rebaseline.') |
| 236 return | 228 return |
| 237 | 229 |
| 238 if self.tree_status() == 'closed': | 230 if self.tree_status() == 'closed': |
| 239 _log.info('Cannot proceed. Tree is closed.') | 231 _log.info('Cannot proceed. Tree is closed.') |
| 240 return | 232 return |
| 241 | 233 |
| 242 _log.info('Rebaselining %s for r%s by %s.', list(tests), revision, autho
r) | 234 _log.info('Rebaselining %s for r%s by %s.', list(tests), revision, autho
r) |
| 243 | 235 |
| 244 test_prefix_list, _ = self.get_test_prefix_list(tests) | 236 test_baseline_set = self._make_test_baseline_set(tests) |
| 245 | 237 |
| 246 did_switch_branches = False | 238 did_switch_branches = False |
| 247 did_finish = False | 239 did_finish = False |
| 248 old_branch_name_or_ref = '' | 240 old_branch_name_or_ref = '' |
| 249 rebaseline_branch_name = self.AUTO_REBASELINE_BRANCH_NAME | 241 rebaseline_branch_name = self.AUTO_REBASELINE_BRANCH_NAME |
| 250 try: | 242 try: |
| 251 # Save the current branch name and check out a clean branch for the
patch. | 243 # Save the current branch name and check out a clean branch for the
patch. |
| 252 old_branch_name_or_ref = tool.git().current_branch_or_ref() | 244 old_branch_name_or_ref = tool.git().current_branch_or_ref() |
| 253 if old_branch_name_or_ref == self.AUTO_REBASELINE_BRANCH_NAME: | 245 if old_branch_name_or_ref == self.AUTO_REBASELINE_BRANCH_NAME: |
| 254 rebaseline_branch_name = self.AUTO_REBASELINE_ALT_BRANCH_NAME | 246 rebaseline_branch_name = self.AUTO_REBASELINE_ALT_BRANCH_NAME |
| 255 if not options.dry_run: | 247 if not options.dry_run: |
| 256 tool.git().delete_branch(rebaseline_branch_name) | 248 tool.git().delete_branch(rebaseline_branch_name) |
| 257 tool.git().create_clean_branch(rebaseline_branch_name) | 249 tool.git().create_clean_branch(rebaseline_branch_name) |
| 258 did_switch_branches = True | 250 did_switch_branches = True |
| 259 | 251 |
| 260 if test_prefix_list: | 252 if test_baseline_set: |
| 261 self.rebaseline(options, test_prefix_list) | 253 self.rebaseline(options, test_baseline_set) |
| 262 | 254 |
| 263 if options.dry_run: | 255 if options.dry_run: |
| 264 return | 256 return |
| 265 | 257 |
| 266 tool.git().commit_locally_with_message( | 258 tool.git().commit_locally_with_message( |
| 267 self.commit_message(author, revision, commit, bugs)) | 259 self.commit_message(author, revision, commit, bugs)) |
| 268 | 260 |
| 269 # FIXME: It would be nice if we could dcommit the patch without uplo
ading, but still | 261 # FIXME: It would be nice if we could dcommit the patch without uplo
ading, but still |
| 270 # go through all the precommit hooks. For rebaselines with lots of f
iles, uploading | 262 # go through all the precommit hooks. For rebaselines with lots of f
iles, uploading |
| 271 # takes a long time and sometimes fails, but we don't want to commit
if, e.g. the | 263 # takes a long time and sometimes fails, but we don't want to commit
if, e.g. the |
| (...skipping 16 matching lines...) Expand all Loading... |
| 288 issue_already_closed = tool.executive.run_command( | 280 issue_already_closed = tool.executive.run_command( |
| 289 ['git', 'config', 'branch.%s.rietveldissue' % rebaseline
_branch_name], | 281 ['git', 'config', 'branch.%s.rietveldissue' % rebaseline
_branch_name], |
| 290 return_exit_code=True) | 282 return_exit_code=True) |
| 291 if not issue_already_closed: | 283 if not issue_already_closed: |
| 292 self._run_git_cl_command(options, ['set_close']) | 284 self._run_git_cl_command(options, ['set_close']) |
| 293 | 285 |
| 294 tool.git().ensure_cleanly_tracking_remote_master() | 286 tool.git().ensure_cleanly_tracking_remote_master() |
| 295 if old_branch_name_or_ref: | 287 if old_branch_name_or_ref: |
| 296 tool.git().checkout_branch(old_branch_name_or_ref) | 288 tool.git().checkout_branch(old_branch_name_or_ref) |
| 297 tool.git().delete_branch(rebaseline_branch_name) | 289 tool.git().delete_branch(rebaseline_branch_name) |
| OLD | NEW |