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

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

Issue 2790863002: Add support for rebaselining for a port from a non-corresponding builder. (Closed)
Patch Set: Created 3 years, 8 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_unittest.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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 self._builder_names = set() 155 self._builder_names = set()
156 self._test_prefix_map = collections.defaultdict(list) 156 self._test_prefix_map = collections.defaultdict(list)
157 157
158 def __iter__(self): 158 def __iter__(self):
159 return iter(self._iter_combinations()) 159 return iter(self._iter_combinations())
160 160
161 def __bool__(self): 161 def __bool__(self):
162 return bool(self._test_prefix_map) 162 return bool(self._test_prefix_map)
163 163
164 def _iter_combinations(self): 164 def _iter_combinations(self):
165 """Iterates through (test, build) combinations.""" 165 """Iterates through (test, build, port) combinations."""
166 for test_prefix, builds in self._test_prefix_map.iteritems(): 166 for test_prefix, build_port_pairs in self._test_prefix_map.iteritems():
167 for test in self._port.tests([test_prefix]): 167 for test in self._port.tests([test_prefix]):
168 for build in builds: 168 for build, port_name in build_port_pairs:
169 yield (test, build) 169 yield (test, build, port_name)
170 170
171 def __str__(self): 171 def __str__(self):
172 if not self._test_prefix_map: 172 if not self._test_prefix_map:
173 return '<Empty TestBaselineSet>' 173 return '<Empty TestBaselineSet>'
174 return '<TestBaselineSet with:\n ' + '\n '.join('%s: %s' % pair for pa ir in self._iter_combinations()) + '>' 174 return ('<TestBaselineSet with:\n ' +
175 '\n '.join('%s: %s, %s' % triple for triple in self._iter_combi nations()) +
176 '>')
175 177
176 def add(self, test_prefix, build): 178 def add(self, test_prefix, build, port_name=None):
177 """Adds an entry for baselines to download for some set of tests. 179 """Adds an entry for baselines to download for some set of tests.
178 180
179 Args: 181 Args:
180 test_prefix: This can be a full test path, or directory of tests, or a path with globs. 182 test_prefix: This can be a full test path, or directory of tests, or a path with globs.
181 build: A Build object. This specifies where to fetch baselines from. 183 build: A Build object. This specifies where to fetch baselines from.
184 port_name: This specifies what platform the baseline is for.
182 """ 185 """
186 port_name = port_name or self._host.builders.port_name_for_builder_name( build.builder_name)
183 self._builder_names.add(build.builder_name) 187 self._builder_names.add(build.builder_name)
184 self._test_prefix_map[test_prefix].append(build) 188 self._test_prefix_map[test_prefix].append((build, port_name))
185 189
186 def all_builders(self): 190 def all_builders(self):
187 """Returns all builder names in in this collection.""" 191 """Returns all builder names in in this collection."""
188 return self._builder_names 192 return self._builder_names
189 193
190 194
191 class CopyExistingBaselinesInternal(AbstractRebaseliningCommand): 195 class CopyExistingBaselinesInternal(AbstractRebaseliningCommand):
192 name = 'copy-existing-baselines-internal' 196 name = 'copy-existing-baselines-internal'
193 help_text = ('Copy existing baselines down one level in the baseline order t o ensure ' 197 help_text = ('Copy existing baselines down one level in the baseline order t o ensure '
194 "new baselines don't break existing passing platforms.") 198 "new baselines don't break existing passing platforms.")
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 return set(builders_to_fallback_paths) 438 return set(builders_to_fallback_paths)
435 439
436 def _rebaseline_commands(self, test_baseline_set, options): 440 def _rebaseline_commands(self, test_baseline_set, options):
437 path_to_webkit_patch = self._tool.path() 441 path_to_webkit_patch = self._tool.path()
438 cwd = self._tool.git().checkout_root 442 cwd = self._tool.git().checkout_root
439 copy_baseline_commands = [] 443 copy_baseline_commands = []
440 rebaseline_commands = [] 444 rebaseline_commands = []
441 lines_to_remove = {} 445 lines_to_remove = {}
442 446
443 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set. all_builders()) 447 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set. all_builders())
444 for test, build in test_baseline_set: 448 for test, build, port_name in test_baseline_set:
445 if build.builder_name not in builders_to_fetch_from: 449 if build.builder_name not in builders_to_fetch_from:
446 continue 450 continue
447 451
448 port_name = self._tool.builders.port_name_for_builder_name(build.bui lder_name)
449
450 suffixes = self._suffixes_for_actual_failures(test, build) 452 suffixes = self._suffixes_for_actual_failures(test, build)
451 if not suffixes: 453 if not suffixes:
452 # If we're not going to rebaseline the test because it's passing on this 454 # If we're not going to rebaseline the test because it's passing on this
453 # builder, we still want to remove the line from TestExpectation s. 455 # builder, we still want to remove the line from TestExpectation s.
454 if test not in lines_to_remove: 456 if test not in lines_to_remove:
455 lines_to_remove[test] = [] 457 lines_to_remove[test] = []
456 lines_to_remove[test].append(port_name) 458 lines_to_remove[test].append(port_name)
457 continue 459 continue
458 460
459 args = [] 461 args = []
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 _log.debug('"%s" is not a JSON object, ignoring', line) 496 _log.debug('"%s" is not a JSON object, ignoring', line)
495 if not updated: 497 if not updated:
496 # TODO(qyearsley): This probably should be an error. See http:// crbug.com/649412. 498 # TODO(qyearsley): This probably should be an error. See http:// crbug.com/649412.
497 _log.debug('Could not add file based off output "%s"', stdout) 499 _log.debug('Could not add file based off output "%s"', stdout)
498 return change_set 500 return change_set
499 501
500 def _optimize_baselines(self, test_baseline_set, verbose=False): 502 def _optimize_baselines(self, test_baseline_set, verbose=False):
501 """Returns a list of commands to run in parallel to de-duplicate baselin es.""" 503 """Returns a list of commands to run in parallel to de-duplicate baselin es."""
502 tests_to_suffixes = collections.defaultdict(set) 504 tests_to_suffixes = collections.defaultdict(set)
503 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set. all_builders()) 505 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set. all_builders())
504 for test, build in test_baseline_set: 506 for test, build, _ in test_baseline_set:
505 if build.builder_name not in builders_to_fetch_from: 507 if build.builder_name not in builders_to_fetch_from:
506 continue 508 continue
507 tests_to_suffixes[test].update(self._suffixes_for_actual_failures(te st, build)) 509 tests_to_suffixes[test].update(self._suffixes_for_actual_failures(te st, build))
508 510
509 optimize_commands = [] 511 optimize_commands = []
510 for test, suffixes in tests_to_suffixes.iteritems(): 512 for test, suffixes in tests_to_suffixes.iteritems():
511 # No need to optimize baselines for a test with no failures. 513 # No need to optimize baselines for a test with no failures.
512 if not suffixes: 514 if not suffixes:
513 continue 515 continue
514 # FIXME: We should propagate the platform options as well. 516 # FIXME: We should propagate the platform options as well.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 577
576 Args: 578 Args:
577 options: An object with the command line options. 579 options: An object with the command line options.
578 test_baseline_set: A TestBaselineSet instance, which represents 580 test_baseline_set: A TestBaselineSet instance, which represents
579 a set of tests/platform combinations to rebaseline. 581 a set of tests/platform combinations to rebaseline.
580 """ 582 """
581 if self._tool.git().has_working_directory_changes(pathspec=self._layout_ tests_dir()): 583 if self._tool.git().has_working_directory_changes(pathspec=self._layout_ tests_dir()):
582 _log.error('There are uncommitted changes in the layout tests direct ory; aborting.') 584 _log.error('There are uncommitted changes in the layout tests direct ory; aborting.')
583 return 585 return
584 586
585 for test in sorted({t for t, _ in test_baseline_set}): 587 for test in sorted({t for t, _, _ in test_baseline_set}):
586 _log.info('Rebaselining %s', test) 588 _log.info('Rebaselining %s', test)
587 589
588 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands( 590 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands(
589 test_baseline_set, options) 591 test_baseline_set, options)
590 lines_to_remove = {} 592 lines_to_remove = {}
591 593
592 self._run_in_parallel(copy_baseline_commands) 594 self._run_in_parallel(copy_baseline_commands)
593 lines_to_remove = self._run_in_parallel(rebaseline_commands) 595 lines_to_remove = self._run_in_parallel(rebaseline_commands)
594 596
595 for test in extra_lines_to_remove: 597 for test in extra_lines_to_remove:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 """Returns file paths for all baselines for the given tests and builders . 640 """Returns file paths for all baselines for the given tests and builders .
639 641
640 Args: 642 Args:
641 test_baseline_set: A TestBaselineSet instance. 643 test_baseline_set: A TestBaselineSet instance.
642 644
643 Returns: 645 Returns:
644 A list of absolute paths where baselines could possibly exist. 646 A list of absolute paths where baselines could possibly exist.
645 """ 647 """
646 filesystem = self._tool.filesystem 648 filesystem = self._tool.filesystem
647 baseline_paths = set() 649 baseline_paths = set()
648 for test, build in test_baseline_set: 650 for test, build, _ in test_baseline_set:
wkorman 2017/04/03 20:41:52 Is this ok re: we won't start doing multiples of t
qyearsley 2017/04/04 18:56:45 Good idea to check this; right now it looks like i
649 filenames = [self._file_name_for_expected_result(test, suffix) for s uffix in BASELINE_SUFFIX_LIST] 651 filenames = [self._file_name_for_expected_result(test, suffix) for s uffix in BASELINE_SUFFIX_LIST]
650 port_baseline_dir = self._baseline_directory(build.builder_name) 652 port_baseline_dir = self._baseline_directory(build.builder_name)
651 baseline_paths.update({filesystem.join(port_baseline_dir, filename) for filename in filenames}) 653 baseline_paths.update({filesystem.join(port_baseline_dir, filename) for filename in filenames})
652 baseline_paths.update({filesystem.join(self._layout_tests_dir(), fil ename) for filename in filenames}) 654 baseline_paths.update({filesystem.join(self._layout_tests_dir(), fil ename) for filename in filenames})
653 return sorted(baseline_paths) 655 return sorted(baseline_paths)
654 656
655 def _layout_tests_dir(self): 657 def _layout_tests_dir(self):
656 return self._tool.port_factory.get().layout_tests_dir() 658 return self._tool.port_factory.get().layout_tests_dir()
657 659
658 def _suffixes_for_actual_failures(self, test, build): 660 def _suffixes_for_actual_failures(self, test, build):
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 760
759 test_baseline_set = TestBaselineSet(tool) 761 test_baseline_set = TestBaselineSet(tool)
760 762
761 for builder in builders_to_check: 763 for builder in builders_to_check:
762 for test_prefix in args: 764 for test_prefix in args:
763 test_baseline_set.add(test_prefix, Build(builder)) 765 test_baseline_set.add(test_prefix, Build(builder))
764 766
765 _log.debug('Rebaselining: %s', test_baseline_set) 767 _log.debug('Rebaselining: %s', test_baseline_set)
766 768
767 self.rebaseline(options, test_baseline_set) 769 self.rebaseline(options, test_baseline_set)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698