| OLD | NEW |
| 1 # Copyright (c) 2010 Google Inc. All rights reserved. | 1 # Copyright (c) 2010 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 platform_options = factory.platform_options(use_globs=True) | 56 platform_options = factory.platform_options(use_globs=True) |
| 57 | 57 |
| 58 results_directory_option = optparse.make_option("--results-directory", help=
"Local results directory to use.") | 58 results_directory_option = optparse.make_option("--results-directory", help=
"Local results directory to use.") |
| 59 | 59 |
| 60 suffixes_option = optparse.make_option("--suffixes", default=','.join(BASELI
NE_SUFFIX_LIST), action="store", | 60 suffixes_option = optparse.make_option("--suffixes", default=','.join(BASELI
NE_SUFFIX_LIST), action="store", |
| 61 help="Comma-separated-list of file ty
pes to rebaseline.") | 61 help="Comma-separated-list of file ty
pes to rebaseline.") |
| 62 | 62 |
| 63 def __init__(self, options=None): | 63 def __init__(self, options=None): |
| 64 super(AbstractRebaseliningCommand, self).__init__(options=options) | 64 super(AbstractRebaseliningCommand, self).__init__(options=options) |
| 65 self._baseline_suffix_list = BASELINE_SUFFIX_LIST | 65 self._baseline_suffix_list = BASELINE_SUFFIX_LIST |
| 66 self._scm_changes = ChangeSet() | 66 self.expectation_line_changes = ChangeSet() |
| 67 self._tool = None | 67 self._tool = None |
| 68 | 68 |
| 69 def _print_scm_changes(self): | 69 def _print_expectation_line_changes(self): |
| 70 print(json.dumps(self._scm_changes.to_dict())) | 70 print(json.dumps(self.expectation_line_changes.to_dict())) |
| 71 | 71 |
| 72 | 72 |
| 73 class ChangeSet(object): | 73 class ChangeSet(object): |
| 74 """A record of added and deleted files and TestExpectation lines to remove. | 74 """A record of TestExpectation lines to remove. |
| 75 | 75 |
| 76 This class groups two kinds of changes together: | 76 TODO(qyearsley): Remove this class, track list of lines to remove directly |
| 77 (1) files that have been added or removed. | 77 in an attribute of AbstractRebaseliningCommand. |
| 78 (2) lines to remove from TestExpectations. | |
| 79 | |
| 80 The reason for keeping track of these changes together is that after rebasel
ining | |
| 81 many tests in parallel by subprocesses, we can update the git staged files l
ist | |
| 82 and the TestExpectations all at once at the end. | |
| 83 | |
| 84 Each subprocess can communicate some set of changes by outputting JSON lines
, | |
| 85 and another process can aggregate the changes. | |
| 86 | |
| 87 TODO(qyearsley): Refactor this so that lines to remove are only tracked in o
ne format. | |
| 88 """ | 78 """ |
| 89 def __init__(self, files_to_add=None, files_to_delete=None, lines_to_remove=
None): | 79 def __init__(self, lines_to_remove=None): |
| 90 self.files_to_add = files_to_add or [] | |
| 91 self.files_to_delete = files_to_delete or [] | |
| 92 self.lines_to_remove = lines_to_remove or {} | 80 self.lines_to_remove = lines_to_remove or {} |
| 93 | 81 |
| 94 def add_file(self, path): | |
| 95 self.files_to_add.append(path) | |
| 96 | |
| 97 def delete_file(self, path): | |
| 98 self.files_to_delete.append(path) | |
| 99 | |
| 100 def remove_line(self, test, builder): | 82 def remove_line(self, test, builder): |
| 101 if test not in self.lines_to_remove: | 83 if test not in self.lines_to_remove: |
| 102 self.lines_to_remove[test] = [] | 84 self.lines_to_remove[test] = [] |
| 103 self.lines_to_remove[test].append(builder) | 85 self.lines_to_remove[test].append(builder) |
| 104 | 86 |
| 105 def to_dict(self): | 87 def to_dict(self): |
| 106 remove_lines = [] | 88 remove_lines = [] |
| 107 for test in self.lines_to_remove: | 89 for test in self.lines_to_remove: |
| 108 for builder in self.lines_to_remove[test]: | 90 for builder in self.lines_to_remove[test]: |
| 109 remove_lines.append({'test': test, 'builder': builder}) | 91 remove_lines.append({'test': test, 'builder': builder}) |
| 110 return { | 92 return {'remove-lines': remove_lines} |
| 111 'add': list(self.files_to_add), | |
| 112 'delete': list(self.files_to_delete), | |
| 113 'remove-lines': remove_lines, | |
| 114 } | |
| 115 | 93 |
| 116 @staticmethod | 94 @staticmethod |
| 117 def from_dict(change_dict): | 95 def from_dict(change_dict): |
| 118 files_to_add = set() | |
| 119 files_to_delete = set() | |
| 120 lines_to_remove = {} | 96 lines_to_remove = {} |
| 121 if 'add' in change_dict: | |
| 122 files_to_add.update(change_dict['add']) | |
| 123 if 'delete' in change_dict: | |
| 124 files_to_delete.update(change_dict['delete']) | |
| 125 if 'remove-lines' in change_dict: | 97 if 'remove-lines' in change_dict: |
| 126 for line_to_remove in change_dict['remove-lines']: | 98 for line_to_remove in change_dict['remove-lines']: |
| 127 test = line_to_remove['test'] | 99 test = line_to_remove['test'] |
| 128 builder = line_to_remove['builder'] | 100 builder = line_to_remove['builder'] |
| 129 if test not in lines_to_remove: | 101 if test not in lines_to_remove: |
| 130 lines_to_remove[test] = [] | 102 lines_to_remove[test] = [] |
| 131 lines_to_remove[test].append(builder) | 103 lines_to_remove[test].append(builder) |
| 132 return ChangeSet( | 104 return ChangeSet(lines_to_remove=lines_to_remove) |
| 133 files_to_add=list(files_to_add), | |
| 134 files_to_delete=list(files_to_delete), | |
| 135 lines_to_remove=lines_to_remove) | |
| 136 | 105 |
| 137 def update(self, other): | 106 def update(self, other): |
| 138 assert isinstance(other, ChangeSet) | 107 assert isinstance(other, ChangeSet) |
| 139 assert type(other.lines_to_remove) is dict | 108 assert type(other.lines_to_remove) is dict |
| 140 self.files_to_add.extend(other.files_to_add) | |
| 141 self.files_to_delete.extend(other.files_to_delete) | |
| 142 for test in other.lines_to_remove: | 109 for test in other.lines_to_remove: |
| 143 if test not in self.lines_to_remove: | 110 if test not in self.lines_to_remove: |
| 144 self.lines_to_remove[test] = [] | 111 self.lines_to_remove[test] = [] |
| 145 self.lines_to_remove[test].extend(other.lines_to_remove[test]) | 112 self.lines_to_remove[test].extend(other.lines_to_remove[test]) |
| 146 | 113 |
| 147 | 114 |
| 148 class BaseInternalRebaselineCommand(AbstractRebaseliningCommand): | 115 class BaseInternalRebaselineCommand(AbstractRebaseliningCommand): |
| 149 """Base class for rebaseline-related commands that are intended to be used b
y other commands.""" | 116 """Base class for rebaseline-related commands that are intended to be used b
y other commands.""" |
| 150 # Not overriding execute() - pylint: disable=abstract-method | 117 # Not overriding execute() - pylint: disable=abstract-method |
| 151 | 118 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 old_baselines.append(old_baseline) | 198 old_baselines.append(old_baseline) |
| 232 new_baselines.append(new_baseline) | 199 new_baselines.append(new_baseline) |
| 233 | 200 |
| 234 for i in range(len(old_baselines)): | 201 for i in range(len(old_baselines)): |
| 235 old_baseline = old_baselines[i] | 202 old_baseline = old_baselines[i] |
| 236 new_baseline = new_baselines[i] | 203 new_baseline = new_baselines[i] |
| 237 | 204 |
| 238 _log.debug("Copying baseline from %s to %s.", old_baseline, new_base
line) | 205 _log.debug("Copying baseline from %s to %s.", old_baseline, new_base
line) |
| 239 self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dir
name(new_baseline)) | 206 self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dir
name(new_baseline)) |
| 240 self._tool.filesystem.copyfile(old_baseline, new_baseline) | 207 self._tool.filesystem.copyfile(old_baseline, new_baseline) |
| 241 if not self._tool.scm().exists(new_baseline): | |
| 242 self._scm_changes.add_file(new_baseline) | |
| 243 | 208 |
| 244 def execute(self, options, args, tool): | 209 def execute(self, options, args, tool): |
| 245 self._tool = tool | 210 self._tool = tool |
| 246 for suffix in options.suffixes.split(','): | 211 for suffix in options.suffixes.split(','): |
| 247 self._copy_existing_baseline(options.builder, options.test, suffix) | 212 self._copy_existing_baseline(options.builder, options.test, suffix) |
| 248 self._print_scm_changes() | |
| 249 | 213 |
| 250 | 214 |
| 251 class RebaselineTest(BaseInternalRebaselineCommand): | 215 class RebaselineTest(BaseInternalRebaselineCommand): |
| 252 name = "rebaseline-test-internal" | 216 name = "rebaseline-test-internal" |
| 253 help_text = "Rebaseline a single test from a buildbot. Only intended for use
by other webkit-patch commands." | 217 help_text = "Rebaseline a single test from a buildbot. Only intended for use
by other webkit-patch commands." |
| 254 | 218 |
| 255 def _save_baseline(self, data, target_baseline): | 219 def _save_baseline(self, data, target_baseline): |
| 256 if not data: | 220 if not data: |
| 257 _log.debug("No baseline data to save.") | 221 _log.debug("No baseline data to save.") |
| 258 return | 222 return |
| 259 | 223 |
| 260 filesystem = self._tool.filesystem | 224 filesystem = self._tool.filesystem |
| 261 filesystem.maybe_make_directory(filesystem.dirname(target_baseline)) | 225 filesystem.maybe_make_directory(filesystem.dirname(target_baseline)) |
| 262 filesystem.write_binary_file(target_baseline, data) | 226 filesystem.write_binary_file(target_baseline, data) |
| 263 if not self._tool.scm().exists(target_baseline): | |
| 264 self._scm_changes.add_file(target_baseline) | |
| 265 | 227 |
| 266 def _rebaseline_test(self, builder_name, test_name, suffix, results_url): | 228 def _rebaseline_test(self, builder_name, test_name, suffix, results_url): |
| 267 baseline_directory = self._baseline_directory(builder_name) | 229 baseline_directory = self._baseline_directory(builder_name) |
| 268 | 230 |
| 269 source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_res
ult(test_name, suffix)) | 231 source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_res
ult(test_name, suffix)) |
| 270 target_baseline = self._tool.filesystem.join(baseline_directory, self._f
ile_name_for_expected_result(test_name, suffix)) | 232 target_baseline = self._tool.filesystem.join(baseline_directory, self._f
ile_name_for_expected_result(test_name, suffix)) |
| 271 | 233 |
| 272 _log.debug("Retrieving source %s for target %s.", source_baseline, targe
t_baseline) | 234 _log.debug("Retrieving source %s for target %s.", source_baseline, targe
t_baseline) |
| 273 self._save_baseline(self._tool.web.get_binary(source_baseline, convert_4
04_to_None=True), | 235 self._save_baseline(self._tool.web.get_binary(source_baseline, convert_4
04_to_None=True), |
| 274 target_baseline) | 236 target_baseline) |
| 275 | 237 |
| 276 def _rebaseline_test_and_update_expectations(self, options): | 238 def _rebaseline_test_and_update_expectations(self, options): |
| 277 self._baseline_suffix_list = options.suffixes.split(',') | 239 self._baseline_suffix_list = options.suffixes.split(',') |
| 278 | 240 |
| 279 port = self._tool.port_factory.get_from_builder_name(options.builder) | 241 port = self._tool.port_factory.get_from_builder_name(options.builder) |
| 280 if port.reference_files(options.test): | 242 if port.reference_files(options.test): |
| 281 if 'png' in self._baseline_suffix_list: | 243 if 'png' in self._baseline_suffix_list: |
| 282 _log.warning("Cannot rebaseline image result for reftest: %s", o
ptions.test) | 244 _log.warning("Cannot rebaseline image result for reftest: %s", o
ptions.test) |
| 283 return | 245 return |
| 284 assert self._baseline_suffix_list == ['txt'] | 246 assert self._baseline_suffix_list == ['txt'] |
| 285 | 247 |
| 286 if options.results_directory: | 248 if options.results_directory: |
| 287 results_url = 'file://' + options.results_directory | 249 results_url = 'file://' + options.results_directory |
| 288 else: | 250 else: |
| 289 results_url = self._tool.buildbot.results_url(options.builder, build
_number=options.build_number) | 251 results_url = self._tool.buildbot.results_url(options.builder, build
_number=options.build_number) |
| 290 | 252 |
| 291 for suffix in self._baseline_suffix_list: | 253 for suffix in self._baseline_suffix_list: |
| 292 self._rebaseline_test(options.builder, options.test, suffix, results
_url) | 254 self._rebaseline_test(options.builder, options.test, suffix, results
_url) |
| 293 self._scm_changes.remove_line(test=options.test, builder=options.builder
) | 255 self.expectation_line_changes.remove_line(test=options.test, builder=opt
ions.builder) |
| 294 | 256 |
| 295 def execute(self, options, args, tool): | 257 def execute(self, options, args, tool): |
| 296 self._tool = tool | 258 self._tool = tool |
| 297 self._rebaseline_test_and_update_expectations(options) | 259 self._rebaseline_test_and_update_expectations(options) |
| 298 self._print_scm_changes() | 260 self._print_expectation_line_changes() |
| 299 | 261 |
| 300 | 262 |
| 301 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): | 263 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
| 302 """Base class for rebaseline commands that do some tasks in parallel.""" | 264 """Base class for rebaseline commands that do some tasks in parallel.""" |
| 303 # Not overriding execute() - pylint: disable=abstract-method | 265 # Not overriding execute() - pylint: disable=abstract-method |
| 304 | 266 |
| 305 def __init__(self, options=None): | 267 def __init__(self, options=None): |
| 306 super(AbstractParallelRebaselineCommand, self).__init__(options=options) | 268 super(AbstractParallelRebaselineCommand, self).__init__(options=options) |
| 307 | 269 |
| 308 def _release_builders(self): | 270 def _release_builders(self): |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 if build_number: | 360 if build_number: |
| 399 args.extend(['--build-number', str(build_number)]) | 361 args.extend(['--build-number', str(build_number)]) |
| 400 if options.results_directory: | 362 if options.results_directory: |
| 401 args.extend(['--results-directory', options.results_dire
ctory]) | 363 args.extend(['--results-directory', options.results_dire
ctory]) |
| 402 | 364 |
| 403 rebaseline_commands.append( | 365 rebaseline_commands.append( |
| 404 tuple([[self._tool.executable, path_to_webkit_patch, 're
baseline-test-internal'] + args, cwd])) | 366 tuple([[self._tool.executable, path_to_webkit_patch, 're
baseline-test-internal'] + args, cwd])) |
| 405 return copy_baseline_commands, rebaseline_commands, lines_to_remove | 367 return copy_baseline_commands, rebaseline_commands, lines_to_remove |
| 406 | 368 |
| 407 @staticmethod | 369 @staticmethod |
| 408 def _extract_scm_changes(command_results): | 370 def _extract_expectation_line_changes(command_results): |
| 409 """Parses the JSON lines from sub-command output and returns the result
as a ChangeSet.""" | 371 """Parses the JSON lines from sub-command output and returns the result
as a ChangeSet.""" |
| 410 change_set = ChangeSet() | 372 change_set = ChangeSet() |
| 411 for _, stdout, _ in command_results: | 373 for _, stdout, _ in command_results: |
| 412 updated = False | 374 updated = False |
| 413 for line in filter(None, stdout.splitlines()): | 375 for line in filter(None, stdout.splitlines()): |
| 414 try: | 376 try: |
| 415 parsed_line = json.loads(line) | 377 parsed_line = json.loads(line) |
| 416 change_set.update(ChangeSet.from_dict(parsed_line)) | 378 change_set.update(ChangeSet.from_dict(parsed_line)) |
| 417 updated = True | 379 updated = True |
| 418 except ValueError: | 380 except ValueError: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 430 for build in sorted(test_prefix_list[test]): | 392 for build in sorted(test_prefix_list[test]): |
| 431 if build.builder_name not in builders_to_fetch_from: | 393 if build.builder_name not in builders_to_fetch_from: |
| 432 break | 394 break |
| 433 all_suffixes.update(self._suffixes_for_actual_failures(test, bui
ld, test_prefix_list[test][build])) | 395 all_suffixes.update(self._suffixes_for_actual_failures(test, bui
ld, test_prefix_list[test][build])) |
| 434 | 396 |
| 435 # No need to optimize baselines for a test with no failures. | 397 # No need to optimize baselines for a test with no failures. |
| 436 if not all_suffixes: | 398 if not all_suffixes: |
| 437 continue | 399 continue |
| 438 | 400 |
| 439 # FIXME: We should propagate the platform options as well. | 401 # FIXME: We should propagate the platform options as well. |
| 440 cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes),
test] | 402 cmd_line = ['--suffixes', ','.join(all_suffixes), test] |
| 441 if verbose: | 403 if verbose: |
| 442 cmd_line.append('--verbose') | 404 cmd_line.append('--verbose') |
| 443 | 405 |
| 444 path_to_webkit_patch = self._tool.path() | 406 path_to_webkit_patch = self._tool.path() |
| 445 cwd = self._tool.scm().checkout_root | 407 cwd = self._tool.scm().checkout_root |
| 446 optimize_commands.append(tuple([[self._tool.executable, path_to_webk
it_patch, 'optimize-baselines'] + cmd_line, cwd])) | 408 optimize_commands.append(tuple([[self._tool.executable, path_to_webk
it_patch, 'optimize-baselines'] + cmd_line, cwd])) |
| 447 return optimize_commands | 409 return optimize_commands |
| 448 | 410 |
| 449 def _update_expectations_files(self, lines_to_remove): | 411 def _update_expectations_files(self, lines_to_remove): |
| 450 # FIXME: This routine is way too expensive. We're creating O(n ports) Te
stExpectations objects. | 412 # FIXME: This routine is way too expensive. We're creating O(n ports) Te
stExpectations objects. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 def _port_skips_test(port, test, generic_expectations, full_expectations): | 446 def _port_skips_test(port, test, generic_expectations, full_expectations): |
| 485 fs = port.host.filesystem | 447 fs = port.host.filesystem |
| 486 if port.default_smoke_test_only(): | 448 if port.default_smoke_test_only(): |
| 487 smoke_test_filename = fs.join(port.layout_tests_dir(), 'SmokeTests') | 449 smoke_test_filename = fs.join(port.layout_tests_dir(), 'SmokeTests') |
| 488 if fs.exists(smoke_test_filename) and test not in fs.read_text_file(
smoke_test_filename): | 450 if fs.exists(smoke_test_filename) and test not in fs.read_text_file(
smoke_test_filename): |
| 489 return True | 451 return True |
| 490 | 452 |
| 491 return (SKIP in full_expectations.get_expectations(test) and | 453 return (SKIP in full_expectations.get_expectations(test) and |
| 492 SKIP not in generic_expectations.get_expectations(test)) | 454 SKIP not in generic_expectations.get_expectations(test)) |
| 493 | 455 |
| 494 def _run_in_parallel(self, commands, update_scm=True): | 456 def _run_in_parallel(self, commands): |
| 495 if not commands: | 457 if not commands: |
| 496 return {} | 458 return {} |
| 497 | 459 |
| 498 command_results = self._tool.executive.run_in_parallel(commands) | 460 command_results = self._tool.executive.run_in_parallel(commands) |
| 499 for _, _, stderr in command_results: | 461 for _, _, stderr in command_results: |
| 500 if stderr: | 462 if stderr: |
| 501 _log.error(stderr) | 463 _log.error(stderr) |
| 502 | 464 |
| 503 change_set = self._extract_scm_changes(command_results) | 465 change_set = self._extract_expectation_line_changes(command_results) |
| 504 | |
| 505 # TODO(qyearsley): Instead of updating the SCM state here, aggregate cha
nges | |
| 506 # and update once in rebaseline. See http://crbug.com/639410. | |
| 507 if update_scm: | |
| 508 if change_set.files_to_delete: | |
| 509 self._tool.scm().delete_list(change_set.files_to_delete) | |
| 510 if change_set.files_to_add: | |
| 511 self._tool.scm().add_list(change_set.files_to_add) | |
| 512 | 466 |
| 513 return change_set.lines_to_remove | 467 return change_set.lines_to_remove |
| 514 | 468 |
| 515 def rebaseline(self, options, test_prefix_list, update_scm=True): | 469 def rebaseline(self, options, test_prefix_list): |
| 516 """Downloads new baselines in parallel, then updates expectations files | 470 """Downloads new baselines in parallel, then updates expectations files |
| 517 and optimizes baselines. | 471 and optimizes baselines. |
| 518 | 472 |
| 519 Args: | 473 Args: |
| 520 options: An object with the options passed to the current command. | 474 options: An object with the options passed to the current command. |
| 521 test_prefix_list: A map of test names to Build objects to file suffi
xes | 475 test_prefix_list: A map of test names to Build objects to file suffi
xes |
| 522 for new baselines. For example: | 476 for new baselines. For example: |
| 523 { | 477 { |
| 524 "some/test.html": {Build("builder-1", 412): ["txt"], Build("
builder-2", 100): ["txt"]}, | 478 "some/test.html": {Build("builder-1", 412): ["txt"], Build("
builder-2", 100): ["txt"]}, |
| 525 "some/other.html": {Build("builder-1", 412): ["txt"]} | 479 "some/other.html": {Build("builder-1", 412): ["txt"]} |
| 526 } | 480 } |
| 527 This would mean that new text baselines should be downloaded for | 481 This would mean that new text baselines should be downloaded for |
| 528 "some/test.html" on both builder-1 (build 412) and builder-2 | 482 "some/test.html" on both builder-1 (build 412) and builder-2 |
| 529 (build 100), and new text baselines should be downloaded for | 483 (build 100), and new text baselines should be downloaded for |
| 530 "some/other.html" but only from builder-1. | 484 "some/other.html" but only from builder-1. |
| 531 TODO(qyearsley): Replace test_prefix_list everywhere with some | 485 TODO(qyearsley): Replace test_prefix_list everywhere with some |
| 532 sort of class that contains the same data. | 486 sort of class that contains the same data. |
| 533 update_scm: If True, commands like `git add` and `git rm` will be ru
n. | |
| 534 """ | 487 """ |
| 488 if self._tool.scm().has_working_directory_changes(pathspec=self._layout_
tests_dir()): |
| 489 _log.error('There are uncommitted changes in the layout tests direct
ory; aborting.') |
| 490 return |
| 491 |
| 535 for test, builds_to_check in sorted(test_prefix_list.items()): | 492 for test, builds_to_check in sorted(test_prefix_list.items()): |
| 536 _log.info("Rebaselining %s", test) | 493 _log.info("Rebaselining %s", test) |
| 537 for build, suffixes in sorted(builds_to_check.items()): | 494 for build, suffixes in sorted(builds_to_check.items()): |
| 538 _log.debug(" %s: %s", build, ",".join(suffixes)) | 495 _log.debug(" %s: %s", build, ",".join(suffixes)) |
| 539 | 496 |
| 540 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel
f._rebaseline_commands( | 497 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel
f._rebaseline_commands( |
| 541 test_prefix_list, options) | 498 test_prefix_list, options) |
| 542 lines_to_remove = {} | 499 lines_to_remove = {} |
| 543 | 500 |
| 544 self._run_in_parallel(copy_baseline_commands, update_scm=update_scm) | 501 self._run_in_parallel(copy_baseline_commands) |
| 545 lines_to_remove = self._run_in_parallel(rebaseline_commands, update_scm=
update_scm) | 502 lines_to_remove = self._run_in_parallel(rebaseline_commands) |
| 546 | 503 |
| 547 for test in extra_lines_to_remove: | 504 for test in extra_lines_to_remove: |
| 548 if test in lines_to_remove: | 505 if test in lines_to_remove: |
| 549 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r
emove[test] | 506 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r
emove[test] |
| 550 else: | 507 else: |
| 551 lines_to_remove[test] = extra_lines_to_remove[test] | 508 lines_to_remove[test] = extra_lines_to_remove[test] |
| 552 | 509 |
| 553 if lines_to_remove: | 510 if lines_to_remove: |
| 554 self._update_expectations_files(lines_to_remove) | 511 self._update_expectations_files(lines_to_remove) |
| 555 | 512 |
| 556 if options.optimize: | 513 if options.optimize: |
| 557 # TODO(wkorman): Consider changing temporary branch to base off of H
EAD rather than | 514 # TODO(wkorman): Consider changing temporary branch to base off of H
EAD rather than |
| 558 # origin/master to ensure we run baseline optimization processes wit
h the same code as | 515 # origin/master to ensure we run baseline optimization processes wit
h the same code as |
| 559 # auto-rebaseline itself. | 516 # auto-rebaseline itself. |
| 560 self._run_in_parallel(self._optimize_baselines(test_prefix_list, opt
ions.verbose), update_scm=update_scm) | 517 self._run_in_parallel(self._optimize_baselines(test_prefix_list, opt
ions.verbose)) |
| 518 |
| 519 self._tool.scm().add_all(pathspec=self._layout_tests_dir()) |
| 520 |
| 521 def _layout_tests_dir(self): |
| 522 return self._tool.port_factory.get().layout_tests_dir() |
| 561 | 523 |
| 562 def _suffixes_for_actual_failures(self, test, build, existing_suffixes): | 524 def _suffixes_for_actual_failures(self, test, build, existing_suffixes): |
| 563 """Gets the baseline suffixes for actual mismatch failures in some resul
ts. | 525 """Gets the baseline suffixes for actual mismatch failures in some resul
ts. |
| 564 | 526 |
| 565 Args: | 527 Args: |
| 566 test: A full test path string. | 528 test: A full test path string. |
| 567 build: A Build object. | 529 build: A Build object. |
| 568 existing_suffixes: A collection of all suffixes to consider. | 530 existing_suffixes: A collection of all suffixes to consider. |
| 569 | 531 |
| 570 Returns: | 532 Returns: |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 for test in args: | 649 for test in args: |
| 688 if test not in test_prefix_list: | 650 if test not in test_prefix_list: |
| 689 test_prefix_list[test] = {} | 651 test_prefix_list[test] = {} |
| 690 build = Build(builder) | 652 build = Build(builder) |
| 691 test_prefix_list[test][build] = suffixes_to_update | 653 test_prefix_list[test][build] = suffixes_to_update |
| 692 | 654 |
| 693 if options.verbose: | 655 if options.verbose: |
| 694 _log.debug("rebaseline-json: " + str(test_prefix_list)) | 656 _log.debug("rebaseline-json: " + str(test_prefix_list)) |
| 695 | 657 |
| 696 self.rebaseline(options, test_prefix_list) | 658 self.rebaseline(options, test_prefix_list) |
| OLD | NEW |