Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py

Issue 2760463004: Simplification: Remove support for specifying suffix lists when rebaselining. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 cwd = self._tool.git().checkout_root 358 cwd = self._tool.git().checkout_root
359 copy_baseline_commands = [] 359 copy_baseline_commands = []
360 rebaseline_commands = [] 360 rebaseline_commands = []
361 lines_to_remove = {} 361 lines_to_remove = {}
362 port = self._tool.port_factory.get() 362 port = self._tool.port_factory.get()
363 363
364 for test_prefix in test_prefix_list: 364 for test_prefix in test_prefix_list:
365 for test in port.tests([test_prefix]): 365 for test in port.tests([test_prefix]):
366 builders_to_fetch_from = self._builders_to_fetch_from(self._buil der_names(test_prefix_list[test_prefix])) 366 builders_to_fetch_from = self._builders_to_fetch_from(self._buil der_names(test_prefix_list[test_prefix]))
367 for build in sorted(test_prefix_list[test_prefix]): 367 for build in sorted(test_prefix_list[test_prefix]):
368
Xianzhu 2017/03/18 00:07:36 Nit: The blank line just looks weird. Feel free to
368 builder, build_number = build.builder_name, build.build_numb er 369 builder, build_number = build.builder_name, build.build_numb er
370
369 if builder not in builders_to_fetch_from: 371 if builder not in builders_to_fetch_from:
370 break 372 break
371 else: 373
372 actual_failures_suffixes = self._suffixes_for_actual_fai lures( 374 suffixes = self._suffixes_for_actual_failures(test, build)
373 test, build, test_prefix_list[test_prefix][build]) 375 if not suffixes:
374 if not actual_failures_suffixes:
375 # If we're not going to rebaseline the test because it's passing on this 376 # If we're not going to rebaseline the test because it's passing on this
376 # builder, we still want to remove the line from TestExp ectations. 377 # builder, we still want to remove the line from TestExp ectations.
377 if test not in lines_to_remove: 378 if test not in lines_to_remove:
378 lines_to_remove[test] = [] 379 lines_to_remove[test] = []
379 lines_to_remove[test].append(builder) 380 lines_to_remove[test].append(builder)
380 continue 381 continue
381 382
382 suffixes = ','.join(actual_failures_suffixes) 383 args = ['--suffixes', ','.join(suffixes), '--builder', build er, '--test', test]
383 args = ['--suffixes', suffixes, '--builder', builder, '--tes t', test]
384 384
385 if options.verbose: 385 if options.verbose:
386 args.append('--verbose') 386 args.append('--verbose')
387 387
388 copy_baseline_commands.append( 388 copy_baseline_commands.append(
389 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + args, cwd])) 389 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + args, cwd]))
390 390
391 if build_number: 391 if build_number:
392 args.extend(['--build-number', str(build_number)]) 392 args.extend(['--build-number', str(build_number)])
393 if options.results_directory: 393 if options.results_directory:
(...skipping 22 matching lines...) Expand all
416 return change_set 416 return change_set
417 417
418 def _optimize_baselines(self, test_prefix_list, verbose=False): 418 def _optimize_baselines(self, test_prefix_list, verbose=False):
419 optimize_commands = [] 419 optimize_commands = []
420 for test in test_prefix_list: 420 for test in test_prefix_list:
421 all_suffixes = set() 421 all_suffixes = set()
422 builders_to_fetch_from = self._builders_to_fetch_from(self._builder_ names(test_prefix_list[test])) 422 builders_to_fetch_from = self._builders_to_fetch_from(self._builder_ names(test_prefix_list[test]))
423 for build in sorted(test_prefix_list[test]): 423 for build in sorted(test_prefix_list[test]):
424 if build.builder_name not in builders_to_fetch_from: 424 if build.builder_name not in builders_to_fetch_from:
425 break 425 break
426 all_suffixes.update(self._suffixes_for_actual_failures(test, bui ld, test_prefix_list[test][build])) 426 all_suffixes.update(self._suffixes_for_actual_failures(test, bui ld))
427 427
428 # No need to optimize baselines for a test with no failures. 428 # No need to optimize baselines for a test with no failures.
429 if not all_suffixes: 429 if not all_suffixes:
430 continue 430 continue
431 431
432 # FIXME: We should propagate the platform options as well. 432 # FIXME: We should propagate the platform options as well.
433 cmd_line = ['--suffixes', ','.join(all_suffixes), test] 433 cmd_line = ['--suffixes', ','.join(all_suffixes), test]
434 if verbose: 434 if verbose:
435 cmd_line.append('--verbose') 435 cmd_line.append('--verbose')
436 436
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 command_results = self._tool.executive.run_in_parallel(commands) 480 command_results = self._tool.executive.run_in_parallel(commands)
481 for _, _, stderr in command_results: 481 for _, _, stderr in command_results:
482 if stderr: 482 if stderr:
483 _log.error(stderr) 483 _log.error(stderr)
484 484
485 change_set = self._extract_expectation_line_changes(command_results) 485 change_set = self._extract_expectation_line_changes(command_results)
486 486
487 return change_set.lines_to_remove 487 return change_set.lines_to_remove
488 488
489 def rebaseline(self, options, test_prefix_list): 489 def rebaseline(self, options, test_prefix_list):
490 """Downloads new baselines in parallel, then updates expectations files 490 """Fetches new baselines and removes related test expectation lines.
491 and optimizes baselines.
492 491
493 Args: 492 Args:
494 options: An object with the options passed to the current command. 493 options: An object with the command line options.
495 test_prefix_list: A map of test names to Build objects to file suffi xes 494 test_prefix_list: A dict of test names to Build objects for new
496 for new baselines. For example: 495 baselines. For example:
497 { 496 {
498 "some/test.html": {Build("builder-1", 412): ["txt"], Build(" builder-2", 100): ["txt"]}, 497 "some/test.html": [Build("builder-1", 412),
499 "some/other.html": {Build("builder-1", 412): ["txt"]} 498 Build("builder-2", 100)]},
499 "some/other.html": [Build("builder-1", 412)}
500 } 500 }
501 This would mean that new text baselines should be downloaded for 501 This would mean that new text baselines should be
502 "some/test.html" on both builder-1 (build 412) and builder-2 502 downloaded for "some/test.html" on both builder-1
503 (build 100), and new text baselines should be downloaded for 503 (build 412) and builder-2 (build 100), and new text
504 "some/other.html" but only from builder-1. 504 baselines should be downloaded for "some/other.html"
505 TODO(qyearsley): Replace test_prefix_list everywhere with some 505 but only from builder-1.
506 sort of class that contains the same data. 506 TODO(qyearsley): Replace test_prefix_list everywhere
507 with some sort of class that contains the same data.
507 """ 508 """
508 if self._tool.git().has_working_directory_changes(pathspec=self._layout_ tests_dir()): 509 if self._tool.git().has_working_directory_changes(pathspec=self._layout_ tests_dir()):
509 _log.error('There are uncommitted changes in the layout tests direct ory; aborting.') 510 _log.error('There are uncommitted changes in the layout tests direct ory; aborting.')
510 return 511 return
511 512
512 for test, builds_to_check in sorted(test_prefix_list.items()): 513 for test, builds_to_check in sorted(test_prefix_list.items()):
513 _log.info('Rebaselining %s', test) 514 _log.info('Rebaselining %s', test)
514 for build, suffixes in sorted(builds_to_check.items()): 515 for build in sorted(builds_to_check):
515 _log.debug(' %s: %s', build, ','.join(suffixes)) 516 _log.debug(' %s', build)
516 517
517 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands( 518 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands(
518 test_prefix_list, options) 519 test_prefix_list, options)
519 lines_to_remove = {} 520 lines_to_remove = {}
520 521
521 self._run_in_parallel(copy_baseline_commands) 522 self._run_in_parallel(copy_baseline_commands)
522 lines_to_remove = self._run_in_parallel(rebaseline_commands) 523 lines_to_remove = self._run_in_parallel(rebaseline_commands)
523 524
524 for test in extra_lines_to_remove: 525 for test in extra_lines_to_remove:
525 if test in lines_to_remove: 526 if test in lines_to_remove:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 for path in baseline_paths: 559 for path in baseline_paths:
559 if not (filesystem.exists(path) and 560 if not (filesystem.exists(path) and
560 filesystem.splitext(path)[1] == '.txt'): 561 filesystem.splitext(path)[1] == '.txt'):
561 continue 562 continue
562 contents = filesystem.read_text_file(path) 563 contents = filesystem.read_text_file(path)
563 if is_all_pass_testharness_result(contents): 564 if is_all_pass_testharness_result(contents):
564 _log.info('Removing all-PASS testharness baseline: %s', path) 565 _log.info('Removing all-PASS testharness baseline: %s', path)
565 filesystem.remove(path) 566 filesystem.remove(path)
566 567
567 def _all_baseline_paths(self, test_prefix_list): 568 def _all_baseline_paths(self, test_prefix_list):
568 """Return file paths for all baselines for the given tests and builders. 569 """Returns file paths for all baselines for the given tests and builders .
569 570
570 Args: 571 Args:
571 test_prefix_list: A dict mapping test prefixes, which could be 572 test_prefix_list: A dict mapping test prefixes, which could be
572 directories or full test paths, to builds to baseline suffixes. 573 directories or full test paths, to Builds.
573 TODO(qyearsley): If a class is added to replace test_prefix_list , 574 TODO(qyearsley): If a class is added to replace
574 then this can be made a method on that class. 575 test_prefix_list, then this can be made a method on
576 that class.
575 577
576 Returns: 578 Returns:
577 A list of absolute paths to possible baseline files, 579 A list of absolute paths to possible baseline files,
578 which may or may not exist on the local filesystem. 580 which may or may not exist on the local filesystem.
579 """ 581 """
580 filesystem = self._tool.filesystem 582 filesystem = self._tool.filesystem
581 baseline_paths = [] 583 baseline_paths = []
582 port = self._tool.port_factory.get() 584 port = self._tool.port_factory.get()
583 585
584 for test_prefix in test_prefix_list: 586 for test_prefix in test_prefix_list:
585 tests = port.tests([test_prefix]) 587 tests = port.tests([test_prefix])
586 all_suffixes = set()
587 588
588 for build, suffixes in test_prefix_list[test_prefix].iteritems(): 589 for build in test_prefix_list[test_prefix]:
589 all_suffixes.update(suffixes)
590 port_baseline_dir = self._baseline_directory(build.builder_name) 590 port_baseline_dir = self._baseline_directory(build.builder_name)
591 baseline_paths.extend([ 591 baseline_paths.extend([
592 filesystem.join(port_baseline_dir, self._file_name_for_expec ted_result(test, suffix)) 592 filesystem.join(port_baseline_dir, self._file_name_for_expec ted_result(test, suffix))
593 for test in tests for suffix in suffixes 593 for test in tests for suffix in BASELINE_SUFFIX_LIST
594 ]) 594 ])
595 595
596 baseline_paths.extend([ 596 baseline_paths.extend([
597 filesystem.join(self._layout_tests_dir(), self._file_name_for_ex pected_result(test, suffix)) 597 filesystem.join(self._layout_tests_dir(), self._file_name_for_ex pected_result(test, suffix))
598 for test in tests for suffix in all_suffixes 598 for test in tests for suffix in BASELINE_SUFFIX_LIST
599 ]) 599 ])
600 600
601 return sorted(baseline_paths) 601 return sorted(baseline_paths)
602 602
603 def _layout_tests_dir(self): 603 def _layout_tests_dir(self):
604 return self._tool.port_factory.get().layout_tests_dir() 604 return self._tool.port_factory.get().layout_tests_dir()
605 605
606 def _suffixes_for_actual_failures(self, test, build, existing_suffixes): 606 def _suffixes_for_actual_failures(self, test, build):
607 """Gets the baseline suffixes for actual mismatch failures in some resul ts. 607 """Gets the baseline suffixes for actual mismatch failures in some resul ts.
608 608
609 Args: 609 Args:
610 test: A full test path string. 610 test: A full test path string.
611 build: A Build object. 611 build: A Build object.
612 existing_suffixes: A collection of all suffixes to consider.
613 612
614 Returns: 613 Returns:
615 A set of file suffix strings. 614 A set of file suffix strings.
616 """ 615 """
617 results = self._tool.buildbot.fetch_results(build) 616 results = self._tool.buildbot.fetch_results(build)
618 if not results: 617 if not results:
619 _log.debug('No results found for build %s', build) 618 _log.debug('No results found for build %s', build)
620 return set() 619 return set()
621 test_result = results.result_for_test(test) 620 test_result = results.result_for_test(test)
622 if not test_result: 621 if not test_result:
623 _log.debug('No test result for test %s in build %s', test, build) 622 _log.debug('No test result for test %s in build %s', test, build)
624 return set() 623 return set()
625 return set(existing_suffixes) & TestExpectations.suffixes_for_test_resul t(test_result) 624 return TestExpectations.suffixes_for_test_result(test_result)
626 625
627 626
628 class RebaselineJson(AbstractParallelRebaselineCommand): 627 class RebaselineJson(AbstractParallelRebaselineCommand):
629 name = 'rebaseline-json' 628 name = 'rebaseline-json'
630 help_text = 'Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts.' 629 help_text = 'Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts.'
631 630
632 def __init__(self,): 631 def __init__(self,):
633 super(RebaselineJson, self).__init__(options=[ 632 super(RebaselineJson, self).__init__(options=[
634 self.no_optimize_option, 633 self.no_optimize_option,
635 self.results_directory_option, 634 self.results_directory_option,
(...skipping 10 matching lines...) Expand all
646 show_in_main_help = True 645 show_in_main_help = True
647 646
648 def __init__(self): 647 def __init__(self):
649 super(RebaselineExpectations, self).__init__(options=[ 648 super(RebaselineExpectations, self).__init__(options=[
650 self.no_optimize_option, 649 self.no_optimize_option,
651 ] + self.platform_options) 650 ] + self.platform_options)
652 self._test_prefix_list = None 651 self._test_prefix_list = None
653 652
654 @staticmethod 653 @staticmethod
655 def _tests_to_rebaseline(port): 654 def _tests_to_rebaseline(port):
656 tests_to_rebaseline = {} 655 tests_to_rebaseline = []
657 for path, value in port.expectations_dict().items(): 656 for path, value in port.expectations_dict().items():
658 expectations = TestExpectations(port, include_overrides=False, expec tations_dict={path: value}) 657 expectations = TestExpectations(port, include_overrides=False, expec tations_dict={path: value})
659 for test in expectations.get_rebaselining_failures(): 658 for test in expectations.get_rebaselining_failures():
660 suffixes = TestExpectations.suffixes_for_expectations(expectatio ns.get_expectations(test)) 659 tests_to_rebaseline.append(test)
661 tests_to_rebaseline[test] = suffixes or BASELINE_SUFFIX_LIST
662 return tests_to_rebaseline 660 return tests_to_rebaseline
663 661
664 def _add_tests_to_rebaseline(self, port_name): 662 def _add_tests_to_rebaseline(self, port_name):
665 builder_name = self._tool.builders.builder_name_for_port_name(port_name) 663 builder_name = self._tool.builders.builder_name_for_port_name(port_name)
666 if not builder_name: 664 if not builder_name:
667 return 665 return
668 tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name) ).items() 666 tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name) )
669 667
670 if tests: 668 if tests:
671 _log.info('Retrieving results for %s from %s.', port_name, builder_n ame) 669 _log.info('Retrieving results for %s from %s.', port_name, builder_n ame)
672 670
673 for test_name, suffixes in tests: 671 for test_name in tests:
674 _log.info(' %s (%s)', test_name, ','.join(suffixes)) 672 _log.info(' %s', test_name)
675 if test_name not in self._test_prefix_list: 673 if test_name not in self._test_prefix_list:
676 self._test_prefix_list[test_name] = {} 674 self._test_prefix_list[test_name] = []
677 self._test_prefix_list[test_name][Build(builder_name)] = suffixes 675 self._test_prefix_list[test_name].append(Build(builder_name))
678 676
679 def execute(self, options, args, tool): 677 def execute(self, options, args, tool):
680 self._tool = tool 678 self._tool = tool
681 options.results_directory = None 679 options.results_directory = None
682 self._test_prefix_list = {} 680 self._test_prefix_list = {}
683 port_names = tool.port_factory.all_port_names(options.platform) 681 port_names = tool.port_factory.all_port_names(options.platform)
684 for port_name in port_names: 682 for port_name in port_names:
685 self._add_tests_to_rebaseline(port_name) 683 self._add_tests_to_rebaseline(port_name)
686 if not self._test_prefix_list: 684 if not self._test_prefix_list:
687 _log.warning('Did not find any tests marked Rebaseline.') 685 _log.warning('Did not find any tests marked Rebaseline.')
688 return 686 return
689 687
690 self.rebaseline(options, self._test_prefix_list) 688 self.rebaseline(options, self._test_prefix_list)
691 689
692 690
693 class Rebaseline(AbstractParallelRebaselineCommand): 691 class Rebaseline(AbstractParallelRebaselineCommand):
694 name = 'rebaseline' 692 name = 'rebaseline'
695 help_text = 'Rebaseline tests with results from the build bots.' 693 help_text = 'Rebaseline tests with results from the build bots.'
696 show_in_main_help = True 694 show_in_main_help = True
697 argument_names = '[TEST_NAMES]' 695 argument_names = '[TEST_NAMES]'
698 696
699 def __init__(self): 697 def __init__(self):
700 super(Rebaseline, self).__init__(options=[ 698 super(Rebaseline, self).__init__(options=[
701 self.no_optimize_option, 699 self.no_optimize_option,
702 # FIXME: should we support the platform options in addition to (or i nstead of) --builders? 700 # FIXME: should we support the platform options in addition to (or i nstead of) --builders?
703 self.suffixes_option,
704 self.results_directory_option, 701 self.results_directory_option,
705 optparse.make_option('--builders', default=None, action='append', 702 optparse.make_option('--builders', default=None, action='append',
706 help=('Comma-separated-list of builders to pull new baselines from ' 703 help=('Comma-separated-list of builders to pull new baselines from '
707 '(can also be provided multiple times).') ), 704 '(can also be provided multiple times).') ),
708 ]) 705 ])
709 706
710 def _builders_to_pull_from(self): 707 def _builders_to_pull_from(self):
711 return self._tool.user.prompt_with_list( 708 return self._tool.user.prompt_with_list(
712 'Which builder to pull results from:', self._release_builders(), can _choose_multiple=True) 709 'Which builder to pull results from:', self._release_builders(), can _choose_multiple=True)
713 710
714 def execute(self, options, args, tool): 711 def execute(self, options, args, tool):
715 self._tool = tool 712 self._tool = tool
716 if not args: 713 if not args:
717 _log.error('Must list tests to rebaseline.') 714 _log.error('Must list tests to rebaseline.')
718 return 715 return
719 716
720 if options.builders: 717 if options.builders:
721 builders_to_check = [] 718 builders_to_check = []
722 for builder_names in options.builders: 719 for builder_names in options.builders:
723 builders_to_check += builder_names.split(',') 720 builders_to_check += builder_names.split(',')
724 else: 721 else:
725 builders_to_check = self._builders_to_pull_from() 722 builders_to_check = self._builders_to_pull_from()
726 723
727 test_prefix_list = {} 724 test_prefix_list = {}
728 suffixes_to_update = options.suffixes.split(',')
729 725
730 for builder in builders_to_check: 726 for builder in builders_to_check:
731 for test in args: 727 for test in args:
732 if test not in test_prefix_list: 728 if test not in test_prefix_list:
733 test_prefix_list[test] = {} 729 test_prefix_list[test] = []
734 build = Build(builder) 730 test_prefix_list[test].append(Build(builder))
735 test_prefix_list[test][build] = suffixes_to_update
736 731
737 if options.verbose: 732 if options.verbose:
738 _log.debug('rebaseline-json: ' + str(test_prefix_list)) 733 _log.debug('rebaseline-json: ' + str(test_prefix_list))
739 734
740 self.rebaseline(options, test_prefix_list) 735 self.rebaseline(options, test_prefix_list)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698