Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 from webkitpy.common.system.executive import ScriptError | 42 from webkitpy.common.system.executive import ScriptError |
| 43 from webkitpy.layout_tests.controllers.test_result_writer import baseline_name | 43 from webkitpy.layout_tests.controllers.test_result_writer import baseline_name |
| 44 from webkitpy.layout_tests.models.test_expectations import TestExpectations, BAS ELINE_SUFFIX_LIST, SKIP | 44 from webkitpy.layout_tests.models.test_expectations import TestExpectations, BAS ELINE_SUFFIX_LIST, SKIP |
| 45 from webkitpy.layout_tests.port import factory | 45 from webkitpy.layout_tests.port import factory |
| 46 from webkitpy.tool.commands.command import Command | 46 from webkitpy.tool.commands.command import Command |
| 47 | 47 |
| 48 | 48 |
| 49 _log = logging.getLogger(__name__) | 49 _log = logging.getLogger(__name__) |
| 50 | 50 |
| 51 | 51 |
| 52 class Build(object): | |
| 53 """Represents a combination of builder and build number. | |
| 54 | |
| 55 If build number is None, this represents the latest build | |
| 56 for a given builder. | |
| 57 | |
| 58 TODO(qyearsley): Move this somewhere else; note it's very similar to TryJob, | |
|
wkorman
2016/07/15 00:12:14
There is also already a Build class:
https://cs.c
qyearsley
2016/07/15 16:28:47
Yesterday after looking at the buildbot module, I
| |
| 59 and it seems like it might belong in the buildbot module. | |
| 60 """ | |
| 61 def __init__(self, builder_name, build_number=None): | |
| 62 self.builder_name = builder_name | |
| 63 self.build_number = build_number | |
| 64 | |
| 65 # Having __hash__ and __eq__ allow instances of this class to be used | |
| 66 # as keys in dictionaries. | |
| 67 def __hash__(self): | |
| 68 return hash((self.builder_name, self.build_number)) | |
| 69 | |
| 70 def __eq__(self, other): | |
| 71 return (self.builder_name, self.build_number) == (other.builder_name, ot her.build_number) | |
| 72 | |
| 73 | |
| 52 class AbstractRebaseliningCommand(Command): | 74 class AbstractRebaseliningCommand(Command): |
| 53 """Base class for rebaseline-related commands.""" | 75 """Base class for rebaseline-related commands.""" |
| 54 # Not overriding execute() - pylint: disable=abstract-method | 76 # Not overriding execute() - pylint: disable=abstract-method |
| 55 | 77 |
| 56 no_optimize_option = optparse.make_option('--no-optimize', dest='optimize', action='store_false', default=True, | 78 no_optimize_option = optparse.make_option('--no-optimize', dest='optimize', action='store_false', default=True, |
| 57 help=('Do not optimize/de-dup the expectations after rebaselining (default is to de-dup automatically). ' | 79 help=('Do not optimize/de-dup the expectations after rebaselining (default is to de-dup automatically). ' |
| 58 'You can use "webkit-patch o ptimize-baselines" to optimize separately.')) | 80 'You can use "webkit-patch o ptimize-baselines" to optimize separately.')) |
| 59 | 81 |
| 60 platform_options = factory.platform_options(use_globs=True) | 82 platform_options = factory.platform_options(use_globs=True) |
| 61 | 83 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 | 302 |
| 281 | 303 |
| 282 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): | 304 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
| 283 """Base class for rebaseline commands that do some tasks in parallel.""" | 305 """Base class for rebaseline commands that do some tasks in parallel.""" |
| 284 # Not overriding execute() - pylint: disable=abstract-method | 306 # Not overriding execute() - pylint: disable=abstract-method |
| 285 | 307 |
| 286 def __init__(self, options=None): | 308 def __init__(self, options=None): |
| 287 super(AbstractParallelRebaselineCommand, self).__init__(options=options) | 309 super(AbstractParallelRebaselineCommand, self).__init__(options=options) |
| 288 | 310 |
| 289 @memoized | 311 @memoized |
| 290 def builder_data(self): | 312 def build_data(self): |
| 291 builder_to_results = {} | 313 """Returns a map of Build objects to LayoutTestResult objects. |
| 314 | |
| 315 The Build objects are the latest builds for the release builders, | |
| 316 and LayoutTestResult objects for results fetched from archived layout | |
| 317 test results. | |
| 318 """ | |
| 319 build_to_results = {} | |
| 292 for builder_name in self._release_builders(): | 320 for builder_name in self._release_builders(): |
| 293 builder = self._tool.buildbot.builder_with_name(builder_name) | 321 builder = self._tool.buildbot.builder_with_name(builder_name) |
| 294 builder_results = builder.latest_layout_test_results() | 322 builder_results = builder.latest_layout_test_results() |
| 295 if builder_results: | 323 if builder_results: |
| 296 builder_to_results[builder_name] = builder_results | 324 build_to_results[Build(builder_name)] = builder_results |
| 297 else: | 325 else: |
| 298 raise Exception("No result for builder %s." % builder_name) | 326 raise Exception("No result for builder %s." % builder_name) |
| 299 return builder_to_results | 327 return build_to_results |
| 300 | 328 |
| 301 # The release builders cycle much faster than the debug ones and cover all t he platforms. | 329 # The release builders cycle much faster than the debug ones and cover all t he platforms. |
| 302 def _release_builders(self): | 330 def _release_builders(self): |
| 303 release_builders = [] | 331 release_builders = [] |
| 304 for builder_name in self._tool.builders.all_continuous_builder_names(): | 332 for builder_name in self._tool.builders.all_continuous_builder_names(): |
| 305 if 'ASAN' in builder_name: | 333 if 'ASAN' in builder_name: |
| 306 continue | 334 continue |
| 307 port = self._tool.port_factory.get_from_builder_name(builder_name) | 335 port = self._tool.port_factory.get_from_builder_name(builder_name) |
| 308 if port.test_configuration().build_type == 'release': | 336 if port.test_configuration().build_type == 'release': |
| 309 release_builders.append(builder_name) | 337 release_builders.append(builder_name) |
| 310 return release_builders | 338 return release_builders |
| 311 | 339 |
| 312 def _run_webkit_patch(self, args, verbose): | 340 def _run_webkit_patch(self, args, verbose): |
| 313 try: | 341 try: |
| 314 verbose_args = ['--verbose'] if verbose else [] | 342 verbose_args = ['--verbose'] if verbose else [] |
| 315 stderr = self._tool.executive.run_command([self._tool.path()] + verb ose_args + | 343 stderr = self._tool.executive.run_command([self._tool.path()] + verb ose_args + |
| 316 args, cwd=self._tool.scm() .checkout_root, return_stderr=True) | 344 args, cwd=self._tool.scm() .checkout_root, return_stderr=True) |
| 317 for line in stderr.splitlines(): | 345 for line in stderr.splitlines(): |
| 318 _log.warning(line) | 346 _log.warning(line) |
| 319 except ScriptError: | 347 except ScriptError: |
| 320 traceback.print_exc(file=sys.stderr) | 348 traceback.print_exc(file=sys.stderr) |
| 321 | 349 |
| 322 def _builders_to_fetch_from(self, builders_to_check): | 350 def _builders_to_fetch_from(self, builders_to_check): |
| 323 """Returns the subset of builders that will cover all of the baseline se arch paths | 351 """Returns the subset of builders that will cover all of the baseline |
| 324 used in the input list. | 352 search paths used in the input list. |
| 325 | 353 |
| 326 In particular, if the input list contains both Release and Debug | 354 In particular, if the input list contains both Release and Debug |
| 327 versions of a configuration, we *only* return the Release version | 355 versions of a configuration, we *only* return the Release version |
| 328 (since we don't save debug versions of baselines). | 356 (since we don't save debug versions of baselines). |
| 329 | 357 |
| 330 Args: | 358 Args: |
| 331 builders_to_check: List of builder names. | 359 builders_to_check: List of builder names. |
| 332 """ | 360 """ |
| 333 release_builders = set() | 361 release_builders = set() |
| 334 debug_builders = set() | 362 debug_builders = set() |
| 335 builders_to_fallback_paths = {} | 363 builders_to_fallback_paths = {} |
| 336 for builder in builders_to_check: | 364 for builder in builders_to_check: |
| 337 port = self._tool.port_factory.get_from_builder_name(builder) | 365 port = self._tool.port_factory.get_from_builder_name(builder) |
| 338 if port.test_configuration().build_type == 'release': | 366 if port.test_configuration().build_type == 'release': |
| 339 release_builders.add(builder) | 367 release_builders.add(builder) |
| 340 else: | 368 else: |
| 341 debug_builders.add(builder) | 369 debug_builders.add(builder) |
| 342 for builder in list(release_builders) + list(debug_builders): | 370 for builder in list(release_builders) + list(debug_builders): |
| 343 port = self._tool.port_factory.get_from_builder_name(builder) | 371 port = self._tool.port_factory.get_from_builder_name(builder) |
| 344 fallback_path = port.baseline_search_path() | 372 fallback_path = port.baseline_search_path() |
| 345 if fallback_path not in builders_to_fallback_paths.values(): | 373 if fallback_path not in builders_to_fallback_paths.values(): |
| 346 builders_to_fallback_paths[builder] = fallback_path | 374 builders_to_fallback_paths[builder] = fallback_path |
| 347 return builders_to_fallback_paths.keys() | 375 return builders_to_fallback_paths.keys() |
| 348 | 376 |
| 349 def _rebaseline_commands(self, test_prefix_list, options, skip_checking_actu al_results=False): | 377 def _rebaseline_commands(self, test_prefix_list, options, skip_checking_actu al_results=False): |
| 350 path_to_webkit_patch = self._tool.path() | 378 path_to_webkit_patch = self._tool.path() |
| 351 cwd = self._tool.scm().checkout_root | 379 cwd = self._tool.scm().checkout_root |
| 352 copy_baseline_commands = [] | 380 copy_baseline_commands = [] |
| 353 rebaseline_commands = [] | 381 rebaseline_commands = [] |
| 354 lines_to_remove = {} | 382 lines_to_remove = {} |
| 355 port = self._tool.port_factory.get() | 383 port = self._tool.port_factory.get() |
| 356 | 384 |
| 357 for test_prefix in test_prefix_list: | 385 for test_prefix in test_prefix_list: |
| 358 for test in port.tests([test_prefix]): | 386 for test in port.tests([test_prefix]): |
| 359 for builder in self._builders_to_fetch_from(test_prefix_list[tes t_prefix]): | 387 builders_to_fetch_from = self._builders_to_fetch_from([b.builder _name for b in test_prefix_list[test_prefix]]) |
| 388 for build in test_prefix_list[test_prefix]: | |
| 360 # TODO(qyearsley): Remove the parameter skip_checking_actual _results | 389 # TODO(qyearsley): Remove the parameter skip_checking_actual _results |
| 361 # and instead refactor the existing code so that this is not necessary. | 390 # and instead refactor the existing code so that this is not necessary. |
| 391 builder, build_number = build.builder_name, build.build_numb er | |
| 392 | |
| 393 if builder not in builders_to_fetch_from: | |
| 394 break | |
| 362 if skip_checking_actual_results: | 395 if skip_checking_actual_results: |
| 363 actual_failures_suffixes = test_prefix_list[test_prefix] [builder] | 396 actual_failures_suffixes = test_prefix_list[test_prefix] [build] |
| 364 else: | 397 else: |
| 365 actual_failures_suffixes = self._suffixes_for_actual_fai lures( | 398 actual_failures_suffixes = self._suffixes_for_actual_fai lures( |
| 366 test, builder, test_prefix_list[test_prefix][builder ]) | 399 test, build, test_prefix_list[test_prefix][build]) |
| 367 if not actual_failures_suffixes: | 400 if not actual_failures_suffixes: |
| 368 # If we're not going to rebaseline the test because it's passing on this | 401 # If we're not going to rebaseline the test because it's passing on this |
| 369 # builder, we still want to remove the line from TestExp ectations. | 402 # builder, we still want to remove the line from TestExp ectations. |
| 370 if test not in lines_to_remove: | 403 if test not in lines_to_remove: |
| 371 lines_to_remove[test] = [] | 404 lines_to_remove[test] = [] |
| 372 lines_to_remove[test].append(builder) | 405 lines_to_remove[test].append(builder) |
| 373 continue | 406 continue |
| 374 | 407 |
| 375 suffixes = ','.join(actual_failures_suffixes) | 408 suffixes = ','.join(actual_failures_suffixes) |
| 376 cmd_line = ['--suffixes', suffixes, '--builder', builder, '- -test', test] | 409 cmd_line = ['--suffixes', suffixes, '--builder', builder, '- -test', test] |
| 410 if build_number: | |
| 411 cmd_line.extend(['--build-number', build_number]) | |
| 377 if options.results_directory: | 412 if options.results_directory: |
| 378 cmd_line.extend(['--results-directory', options.results_ directory]) | 413 cmd_line.extend(['--results-directory', options.results_ directory]) |
| 379 if options.verbose: | 414 if options.verbose: |
| 380 cmd_line.append('--verbose') | 415 cmd_line.append('--verbose') |
| 381 copy_baseline_commands.append( | 416 copy_baseline_commands.append( |
| 382 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + cmd_line, cwd])) | 417 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + cmd_line, cwd])) |
| 383 rebaseline_commands.append( | 418 rebaseline_commands.append( |
| 384 tuple([[self._tool.executable, path_to_webkit_patch, 're baseline-test-internal'] + cmd_line, cwd])) | 419 tuple([[self._tool.executable, path_to_webkit_patch, 're baseline-test-internal'] + cmd_line, cwd])) |
| 385 return copy_baseline_commands, rebaseline_commands, lines_to_remove | 420 return copy_baseline_commands, rebaseline_commands, lines_to_remove |
| 386 | 421 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 411 | 446 |
| 412 if not file_added: | 447 if not file_added: |
| 413 _log.debug('Could not add file based off output "%s"' % output) | 448 _log.debug('Could not add file based off output "%s"' % output) |
| 414 | 449 |
| 415 return list(files_to_add), list(files_to_delete), lines_to_remove | 450 return list(files_to_add), list(files_to_delete), lines_to_remove |
| 416 | 451 |
| 417 def _optimize_baselines(self, test_prefix_list, verbose=False): | 452 def _optimize_baselines(self, test_prefix_list, verbose=False): |
| 418 optimize_commands = [] | 453 optimize_commands = [] |
| 419 for test in test_prefix_list: | 454 for test in test_prefix_list: |
| 420 all_suffixes = set() | 455 all_suffixes = set() |
| 421 for builder in self._builders_to_fetch_from(test_prefix_list[test]): | 456 builders_to_fetch_from = self._builders_to_fetch_from([b.builder_nam e for b in test_prefix_list[test]]) |
|
wkorman
2016/07/15 00:12:14
Could be worth a helper method for the list compre
qyearsley
2016/07/15 16:28:47
Extracted a little helper method -- but now, after
| |
| 422 all_suffixes.update(self._suffixes_for_actual_failures(test, bui lder, test_prefix_list[test][builder])) | 457 for build in test_prefix_list[test]: |
| 458 if build.builder_name not in builders_to_fetch_from: | |
| 459 break | |
| 460 all_suffixes.update(self._suffixes_for_actual_failures(test, bui ld, test_prefix_list[test][build])) | |
| 423 | 461 |
| 424 # No need to optimize baselines for a test with no failures. | 462 # No need to optimize baselines for a test with no failures. |
| 425 if not all_suffixes: | 463 if not all_suffixes: |
| 426 continue | 464 continue |
| 427 | 465 |
| 428 # FIXME: We should propagate the platform options as well. | 466 # FIXME: We should propagate the platform options as well. |
| 429 cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes), test] | 467 cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes), test] |
| 430 if verbose: | 468 if verbose: |
| 431 cmd_line.append('--verbose') | 469 cmd_line.append('--verbose') |
| 432 | 470 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 if files_to_add: | 533 if files_to_add: |
| 496 self._tool.scm().add_list(files_to_add) | 534 self._tool.scm().add_list(files_to_add) |
| 497 return lines_to_remove | 535 return lines_to_remove |
| 498 | 536 |
| 499 def _rebaseline(self, options, test_prefix_list, skip_checking_actual_result s=False): | 537 def _rebaseline(self, options, test_prefix_list, skip_checking_actual_result s=False): |
| 500 """Downloads new baselines in parallel, then updates expectations files | 538 """Downloads new baselines in parallel, then updates expectations files |
| 501 and optimizes baselines. | 539 and optimizes baselines. |
| 502 | 540 |
| 503 Args: | 541 Args: |
| 504 options: An object with the options passed to the current command. | 542 options: An object with the options passed to the current command. |
| 505 test_prefix_list: A map of test names to builder names to baseline | 543 test_prefix_list: A map of test names to Build objects to file suffi xes |
| 506 suffixes to rebaseline. For example: | 544 for new baseilnes. For example: |
| 507 { | 545 { |
| 508 "some/test.html": {"builder-1": ["txt"], "builder-2": ["txt" ]}, | 546 "some/test.html": {Build("builder-1", 412): ["txt"], Build(" builder-2", 100): ["txt"]}, |
| 509 "some/other.html": {"builder-1": ["txt"]} | 547 "some/other.html": {Build("builder-1", 412): ["txt"]} |
| 510 } | 548 } |
| 511 This would mean that new text baselines should be downloaded for | 549 This would mean that new text baselines should be downloaded for |
| 512 "some/test.html" on both builder-1 and builder-2, and new text | 550 "some/test.html" on both builder-1 (build 412) and builder-2 |
| 513 baselines should be downloaded for "some/other.html" but only | 551 (build 100), and new text baselines should be downloaded for |
| 514 from builder-1. | 552 "some/other.html" but only from builder-1. |
| 515 skip_checking_actual_results: If True, then the lists of suffixes | 553 skip_checking_actual_results: If True, then the lists of suffixes |
| 516 to rebaseline from |test_prefix_list| will be used directly; | 554 to rebaseline from |test_prefix_list| will be used directly; |
| 517 if False, then the list of suffixes will filtered to include | 555 if False, then the list of suffixes will filtered to include |
| 518 suffixes with mismatches in actual results. | 556 suffixes with mismatches in actual results. |
| 519 """ | 557 """ |
| 520 for test, builders_to_check in sorted(test_prefix_list.items()): | 558 for test, builds_to_check in sorted(test_prefix_list.items()): |
| 521 _log.info("Rebaselining %s" % test) | 559 _log.info("Rebaselining %s" % test) |
| 522 for builder, suffixes in sorted(builders_to_check.items()): | 560 for build, suffixes in sorted(builds_to_check.items()): |
| 523 _log.debug(" %s: %s" % (builder, ",".join(suffixes))) | 561 _log.debug(" %s: %s" % (build, ",".join(suffixes))) |
| 524 | 562 |
| 525 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands( | 563 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands( |
| 526 test_prefix_list, options, skip_checking_actual_results) | 564 test_prefix_list, options, skip_checking_actual_results) |
| 527 lines_to_remove = {} | 565 lines_to_remove = {} |
| 528 | 566 |
| 529 self._run_in_parallel_and_update_scm(copy_baseline_commands) | 567 self._run_in_parallel_and_update_scm(copy_baseline_commands) |
| 530 lines_to_remove = self._run_in_parallel_and_update_scm(rebaseline_comman ds) | 568 lines_to_remove = self._run_in_parallel_and_update_scm(rebaseline_comman ds) |
| 531 | 569 |
| 532 for test in extra_lines_to_remove: | 570 for test in extra_lines_to_remove: |
| 533 if test in lines_to_remove: | 571 if test in lines_to_remove: |
| 534 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r emove[test] | 572 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r emove[test] |
| 535 else: | 573 else: |
| 536 lines_to_remove[test] = extra_lines_to_remove[test] | 574 lines_to_remove[test] = extra_lines_to_remove[test] |
| 537 | 575 |
| 538 if lines_to_remove: | 576 if lines_to_remove: |
| 539 self._update_expectations_files(lines_to_remove) | 577 self._update_expectations_files(lines_to_remove) |
| 540 | 578 |
| 541 if options.optimize: | 579 if options.optimize: |
| 542 # TODO(wkorman): Consider changing temporary branch to base off of H EAD rather than | 580 # TODO(wkorman): Consider changing temporary branch to base off of H EAD rather than |
| 543 # origin/master to ensure we run baseline optimization processes wit h the same code as | 581 # origin/master to ensure we run baseline optimization processes wit h the same code as |
| 544 # auto-rebaseline itself. | 582 # auto-rebaseline itself. |
| 545 self._run_in_parallel_and_update_scm(self._optimize_baselines(test_p refix_list, options.verbose)) | 583 self._run_in_parallel_and_update_scm(self._optimize_baselines(test_p refix_list, options.verbose)) |
| 546 | 584 |
| 547 def _suffixes_for_actual_failures(self, test, builder_name, existing_suffixe s): | 585 def _suffixes_for_actual_failures(self, test, build, existing_suffixes): |
| 548 if builder_name not in self.builder_data(): | 586 """Gets the baseline suffixes for actual mismatch failures in some resul ts. |
| 587 | |
| 588 Args: | |
| 589 test: A full test path string. | |
| 590 build: A pair (builder_name, build_number). | |
|
wkorman
2016/07/15 00:12:14
Is the description here up to date re: Build class
qyearsley
2016/07/15 16:28:47
It was not; now updated.
| |
| 591 existing_suffixes: A collection of all suffixes to consider. | |
| 592 | |
| 593 Returns: | |
| 594 A set of file suffix strings. | |
| 595 """ | |
| 596 if build not in self.build_data(): | |
| 549 return set() | 597 return set() |
| 550 test_result = self.builder_data()[builder_name].result_for_test(test) | 598 test_result = self.build_data()[build].result_for_test(test) |
| 551 if not test_result: | 599 if not test_result: |
| 552 return set() | 600 return set() |
| 553 return set(existing_suffixes) & TestExpectations.suffixes_for_test_resul t(test_result) | 601 return set(existing_suffixes) & TestExpectations.suffixes_for_test_resul t(test_result) |
| 554 | 602 |
| 555 | 603 |
| 556 class RebaselineJson(AbstractParallelRebaselineCommand): | 604 class RebaselineJson(AbstractParallelRebaselineCommand): |
| 557 name = "rebaseline-json" | 605 name = "rebaseline-json" |
| 558 help_text = "Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts." | 606 help_text = "Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts." |
| 559 | 607 |
| 560 def __init__(self,): | 608 def __init__(self,): |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 return | 641 return |
| 594 tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name) ).items() | 642 tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name) ).items() |
| 595 | 643 |
| 596 if tests: | 644 if tests: |
| 597 _log.info("Retrieving results for %s from %s." % (port_name, builder _name)) | 645 _log.info("Retrieving results for %s from %s." % (port_name, builder _name)) |
| 598 | 646 |
| 599 for test_name, suffixes in tests: | 647 for test_name, suffixes in tests: |
| 600 _log.info(" %s (%s)" % (test_name, ','.join(suffixes))) | 648 _log.info(" %s (%s)" % (test_name, ','.join(suffixes))) |
| 601 if test_name not in self._test_prefix_list: | 649 if test_name not in self._test_prefix_list: |
| 602 self._test_prefix_list[test_name] = {} | 650 self._test_prefix_list[test_name] = {} |
| 603 self._test_prefix_list[test_name][builder_name] = suffixes | 651 self._test_prefix_list[test_name][Build(builder_name)] = suffixes |
| 604 | 652 |
| 605 def execute(self, options, args, tool): | 653 def execute(self, options, args, tool): |
| 606 options.results_directory = None | 654 options.results_directory = None |
| 607 self._test_prefix_list = {} | 655 self._test_prefix_list = {} |
| 608 port_names = tool.port_factory.all_port_names(options.platform) | 656 port_names = tool.port_factory.all_port_names(options.platform) |
| 609 for port_name in port_names: | 657 for port_name in port_names: |
| 610 self._add_tests_to_rebaseline_for_port(port_name) | 658 self._add_tests_to_rebaseline_for_port(port_name) |
| 611 if not self._test_prefix_list: | 659 if not self._test_prefix_list: |
| 612 _log.warning("Did not find any tests marked Rebaseline.") | 660 _log.warning("Did not find any tests marked Rebaseline.") |
| 613 return | 661 return |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 else: | 699 else: |
| 652 builders_to_check = self._builders_to_pull_from() | 700 builders_to_check = self._builders_to_pull_from() |
| 653 | 701 |
| 654 test_prefix_list = {} | 702 test_prefix_list = {} |
| 655 suffixes_to_update = options.suffixes.split(",") | 703 suffixes_to_update = options.suffixes.split(",") |
| 656 | 704 |
| 657 for builder in builders_to_check: | 705 for builder in builders_to_check: |
| 658 for test in args: | 706 for test in args: |
| 659 if test not in test_prefix_list: | 707 if test not in test_prefix_list: |
| 660 test_prefix_list[test] = {} | 708 test_prefix_list[test] = {} |
| 661 test_prefix_list[test][builder.name()] = suffixes_to_update | 709 build = Build(builder.name()) |
| 710 test_prefix_list[test][build] = suffixes_to_update | |
| 662 | 711 |
| 663 if options.verbose: | 712 if options.verbose: |
| 664 _log.debug("rebaseline-json: " + str(test_prefix_list)) | 713 _log.debug("rebaseline-json: " + str(test_prefix_list)) |
| 665 | 714 |
| 666 self._rebaseline(options, test_prefix_list) | 715 self._rebaseline(options, test_prefix_list) |
| 667 | 716 |
| 668 | 717 |
| 669 class AutoRebaseline(AbstractParallelRebaselineCommand): | 718 class AutoRebaseline(AbstractParallelRebaselineCommand): |
| 670 name = "auto-rebaseline" | 719 name = "auto-rebaseline" |
| 671 help_text = "Rebaselines any NeedsRebaseline lines in TestExpectations that have cycled through all the bots." | 720 help_text = "Rebaselines any NeedsRebaseline lines in TestExpectations that have cycled through all the bots." |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 698 @ | 747 @ |
| 699 [^@>]+ # Domain terminated by @ or >, some lines have an ad ditional @ fragment after the email. | 748 [^@>]+ # Domain terminated by @ or >, some lines have an ad ditional @ fragment after the email. |
| 700 ) | 749 ) |
| 701 .*?([^ ]*) # Test file name | 750 .*?([^ ]*) # Test file name |
| 702 \ \[ # Single space followed by opening [ for expectation specifier | 751 \ \[ # Single space followed by opening [ for expectation specifier |
| 703 [^[]*$ # Prevents matching previous [ for version specifier s instead of expectation specifiers | 752 [^[]*$ # Prevents matching previous [ for version specifier s instead of expectation specifiers |
| 704 """, re.VERBOSE) | 753 """, re.VERBOSE) |
| 705 | 754 |
| 706 def bot_revision_data(self, scm): | 755 def bot_revision_data(self, scm): |
| 707 revisions = [] | 756 revisions = [] |
| 708 for result in self.builder_data().values(): | 757 for result in self.build_data().values(): |
| 709 if result.run_was_interrupted(): | 758 if result.run_was_interrupted(): |
| 710 _log.error("Can't rebaseline because the latest run on %s exited early." % result.builder_name()) | 759 _log.error("Can't rebaseline because the latest run on %s exited early." % result.builder_name()) |
| 711 return [] | 760 return [] |
| 712 revisions.append({ | 761 revisions.append({ |
| 713 "builder": result.builder_name(), | 762 "builder": result.builder_name(), |
| 714 "revision": result.chromium_revision(scm), | 763 "revision": result.chromium_revision(scm), |
| 715 }) | 764 }) |
| 716 return revisions | 765 return revisions |
| 717 | 766 |
| 718 def _strip_comments(self, line): | 767 def _strip_comments(self, line): |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 798 port = self._tool.port_factory.get(port_name) | 847 port = self._tool.port_factory.get(port_name) |
| 799 expectations = TestExpectations(port, include_overrides=True) | 848 expectations = TestExpectations(port, include_overrides=True) |
| 800 for test in expectations.get_needs_rebaseline_failures(): | 849 for test in expectations.get_needs_rebaseline_failures(): |
| 801 if test not in tests: | 850 if test not in tests: |
| 802 continue | 851 continue |
| 803 | 852 |
| 804 if test not in test_prefix_list: | 853 if test not in test_prefix_list: |
| 805 lines_to_remove[test] = [] | 854 lines_to_remove[test] = [] |
| 806 test_prefix_list[test] = {} | 855 test_prefix_list[test] = {} |
| 807 lines_to_remove[test].append(builder_name) | 856 lines_to_remove[test].append(builder_name) |
| 808 test_prefix_list[test][builder_name] = BASELINE_SUFFIX_LIST | 857 test_prefix_list[test][Build(builder_name)] = BASELINE_SUFFIX_LI ST |
| 809 | 858 |
| 810 return test_prefix_list, lines_to_remove | 859 return test_prefix_list, lines_to_remove |
| 811 | 860 |
| 812 def _run_git_cl_command(self, options, command): | 861 def _run_git_cl_command(self, options, command): |
| 813 subprocess_command = ['git', 'cl'] + command | 862 subprocess_command = ['git', 'cl'] + command |
| 814 if options.verbose: | 863 if options.verbose: |
| 815 subprocess_command.append('--verbose') | 864 subprocess_command.append('--verbose') |
| 816 if options.auth_refresh_token_json: | 865 if options.auth_refresh_token_json: |
| 817 subprocess_command.append('--auth-refresh-token-json') | 866 subprocess_command.append('--auth-refresh-token-json') |
| 818 subprocess_command.append(options.auth_refresh_token_json) | 867 subprocess_command.append(options.auth_refresh_token_json) |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 issue_already_closed = tool.executive.run_command( | 974 issue_already_closed = tool.executive.run_command( |
| 926 ['git', 'config', 'branch.%s.rietveldissue' % rebaseline _branch_name], | 975 ['git', 'config', 'branch.%s.rietveldissue' % rebaseline _branch_name], |
| 927 return_exit_code=True) | 976 return_exit_code=True) |
| 928 if not issue_already_closed: | 977 if not issue_already_closed: |
| 929 self._run_git_cl_command(options, ['set_close']) | 978 self._run_git_cl_command(options, ['set_close']) |
| 930 | 979 |
| 931 tool.scm().ensure_cleanly_tracking_remote_master() | 980 tool.scm().ensure_cleanly_tracking_remote_master() |
| 932 if old_branch_name_or_ref: | 981 if old_branch_name_or_ref: |
| 933 tool.scm().checkout_branch(old_branch_name_or_ref) | 982 tool.scm().checkout_branch(old_branch_name_or_ref) |
| 934 tool.scm().delete_branch(rebaseline_branch_name) | 983 tool.scm().delete_branch(rebaseline_branch_name) |
| OLD | NEW |