| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 class TestBaselineSet(object): | 138 class TestBaselineSet(object): |
| 139 """Represents a collection of tests and platforms that can be rebaselined. | 139 """Represents a collection of tests and platforms that can be rebaselined. |
| 140 | 140 |
| 141 A TestBaselineSet specifies tests to rebaseline along with information | 141 A TestBaselineSet specifies tests to rebaseline along with information |
| 142 about where to fetch the baselines from. | 142 about where to fetch the baselines from. |
| 143 """ | 143 """ |
| 144 | 144 |
| 145 def __init__(self, host): | 145 def __init__(self, host): |
| 146 self._host = host | 146 self._host = host |
| 147 self._port = self._host.port_factory.get() |
| 148 self._builder_names = set() |
| 147 self._test_prefix_map = collections.defaultdict(list) | 149 self._test_prefix_map = collections.defaultdict(list) |
| 148 | 150 |
| 149 def __iter__(self): | 151 def __iter__(self): |
| 150 return iter(self._iter_combinations()) | 152 return iter(self._iter_combinations()) |
| 151 | 153 |
| 152 def __bool__(self): | 154 def __bool__(self): |
| 153 return bool(self._test_prefix_map) | 155 return bool(self._test_prefix_map) |
| 154 | 156 |
| 155 def _iter_combinations(self): | 157 def _iter_combinations(self): |
| 156 """Iterates through (test, build) combinations.""" | 158 """Iterates through (test, build) combinations.""" |
| 157 port = self._host.port_factory.get() | |
| 158 for test_prefix, builds in self._test_prefix_map.iteritems(): | 159 for test_prefix, builds in self._test_prefix_map.iteritems(): |
| 159 for build in builds: | 160 for test in self._port.tests([test_prefix]): |
| 160 for test in port.tests([test_prefix]): | 161 for build in builds: |
| 161 yield (test, build) | 162 yield (test, build) |
| 162 | 163 |
| 163 def __str__(self): | 164 def __str__(self): |
| 164 if not self._test_prefix_map: | 165 if not self._test_prefix_map: |
| 165 return '<Empty TestBaselineSet>' | 166 return '<Empty TestBaselineSet>' |
| 166 return '<TestBaselineSet with:\n ' + '\n '.join('%s: %s' % pair for pa
ir in self._iter_combinations()) + '>' | 167 return '<TestBaselineSet with:\n ' + '\n '.join('%s: %s' % pair for pa
ir in self._iter_combinations()) + '>' |
| 167 | 168 |
| 168 def add(self, test_prefix, build): | 169 def add(self, test_prefix, build): |
| 169 """Adds an entry for baselines to download for some set of tests. | 170 """Adds an entry for baselines to download for some set of tests. |
| 170 | 171 |
| 171 Args: | 172 Args: |
| 172 test_prefix: This can be a full test path, or directory of tests, or
a path with globs. | 173 test_prefix: This can be a full test path, or directory of tests, or
a path with globs. |
| 173 build: A Build object. This specifies where to fetch baselines from. | 174 build: A Build object. This specifies where to fetch baselines from. |
| 174 """ | 175 """ |
| 176 self._builder_names.add(build.builder_name) |
| 175 self._test_prefix_map[test_prefix].append(build) | 177 self._test_prefix_map[test_prefix].append(build) |
| 176 | 178 |
| 177 def all_builders(self): | 179 def all_builders(self): |
| 178 """Returns all builder names in in this collection.""" | 180 """Returns all builder names in in this collection.""" |
| 179 return sorted({b.builder_name for _, b in self._iter_combinations()}) | 181 return self._builder_names |
| 180 | 182 |
| 181 | 183 |
| 182 class CopyExistingBaselinesInternal(AbstractRebaseliningCommand): | 184 class CopyExistingBaselinesInternal(AbstractRebaseliningCommand): |
| 183 name = 'copy-existing-baselines-internal' | 185 name = 'copy-existing-baselines-internal' |
| 184 help_text = ('Copy existing baselines down one level in the baseline order t
o ensure ' | 186 help_text = ('Copy existing baselines down one level in the baseline order t
o ensure ' |
| 185 "new baselines don't break existing passing platforms.") | 187 "new baselines don't break existing passing platforms.") |
| 186 | 188 |
| 187 def __init__(self): | 189 def __init__(self): |
| 188 super(CopyExistingBaselinesInternal, self).__init__(options=[ | 190 super(CopyExistingBaselinesInternal, self).__init__(options=[ |
| 189 self.results_directory_option, | 191 self.results_directory_option, |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 402 |
| 401 return set(builders_to_fallback_paths) | 403 return set(builders_to_fallback_paths) |
| 402 | 404 |
| 403 def _rebaseline_commands(self, test_baseline_set, options): | 405 def _rebaseline_commands(self, test_baseline_set, options): |
| 404 path_to_webkit_patch = self._tool.path() | 406 path_to_webkit_patch = self._tool.path() |
| 405 cwd = self._tool.git().checkout_root | 407 cwd = self._tool.git().checkout_root |
| 406 copy_baseline_commands = [] | 408 copy_baseline_commands = [] |
| 407 rebaseline_commands = [] | 409 rebaseline_commands = [] |
| 408 lines_to_remove = {} | 410 lines_to_remove = {} |
| 409 | 411 |
| 412 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set.
all_builders()) |
| 410 for test, build in test_baseline_set: | 413 for test, build in test_baseline_set: |
| 411 if build.builder_name not in self._builders_to_fetch_from(test_basel
ine_set.all_builders()): | 414 if build.builder_name not in builders_to_fetch_from: |
| 412 continue | 415 continue |
| 413 | 416 |
| 414 suffixes = self._suffixes_for_actual_failures(test, build) | 417 suffixes = self._suffixes_for_actual_failures(test, build) |
| 415 if not suffixes: | 418 if not suffixes: |
| 416 # If we're not going to rebaseline the test because it's passing
on this | 419 # If we're not going to rebaseline the test because it's passing
on this |
| 417 # builder, we still want to remove the line from TestExpectation
s. | 420 # builder, we still want to remove the line from TestExpectation
s. |
| 418 if test not in lines_to_remove: | 421 if test not in lines_to_remove: |
| 419 lines_to_remove[test] = [] | 422 lines_to_remove[test] = [] |
| 420 lines_to_remove[test].append(build.builder_name) | 423 lines_to_remove[test].append(build.builder_name) |
| 421 continue | 424 continue |
| (...skipping 29 matching lines...) Expand all Loading... |
| 451 except ValueError: | 454 except ValueError: |
| 452 _log.debug('"%s" is not a JSON object, ignoring', line) | 455 _log.debug('"%s" is not a JSON object, ignoring', line) |
| 453 if not updated: | 456 if not updated: |
| 454 # TODO(qyearsley): This probably should be an error. See http://
crbug.com/649412. | 457 # TODO(qyearsley): This probably should be an error. See http://
crbug.com/649412. |
| 455 _log.debug('Could not add file based off output "%s"', stdout) | 458 _log.debug('Could not add file based off output "%s"', stdout) |
| 456 return change_set | 459 return change_set |
| 457 | 460 |
| 458 def _optimize_baselines(self, test_baseline_set, verbose=False): | 461 def _optimize_baselines(self, test_baseline_set, verbose=False): |
| 459 """Returns a list of commands to run in parallel to de-duplicate baselin
es.""" | 462 """Returns a list of commands to run in parallel to de-duplicate baselin
es.""" |
| 460 tests_to_suffixes = collections.defaultdict(set) | 463 tests_to_suffixes = collections.defaultdict(set) |
| 464 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_set.
all_builders()) |
| 461 for test, build in test_baseline_set: | 465 for test, build in test_baseline_set: |
| 462 builders_to_fetch_from = self._builders_to_fetch_from(test_baseline_
set.all_builders()) | |
| 463 if build.builder_name not in builders_to_fetch_from: | 466 if build.builder_name not in builders_to_fetch_from: |
| 464 continue | 467 continue |
| 465 tests_to_suffixes[test].update(self._suffixes_for_actual_failures(te
st, build)) | 468 tests_to_suffixes[test].update(self._suffixes_for_actual_failures(te
st, build)) |
| 466 | 469 |
| 467 optimize_commands = [] | 470 optimize_commands = [] |
| 468 for test, suffixes in tests_to_suffixes.iteritems(): | 471 for test, suffixes in tests_to_suffixes.iteritems(): |
| 469 # No need to optimize baselines for a test with no failures. | 472 # No need to optimize baselines for a test with no failures. |
| 470 if not suffixes: | 473 if not suffixes: |
| 471 continue | 474 continue |
| 472 # FIXME: We should propagate the platform options as well. | 475 # FIXME: We should propagate the platform options as well. |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 | 718 |
| 716 test_baseline_set = TestBaselineSet(tool) | 719 test_baseline_set = TestBaselineSet(tool) |
| 717 | 720 |
| 718 for builder in builders_to_check: | 721 for builder in builders_to_check: |
| 719 for test_prefix in args: | 722 for test_prefix in args: |
| 720 test_baseline_set.add(test_prefix, Build(builder)) | 723 test_baseline_set.add(test_prefix, Build(builder)) |
| 721 | 724 |
| 722 _log.debug('Rebaselining: %s', test_baseline_set) | 725 _log.debug('Rebaselining: %s', test_baseline_set) |
| 723 | 726 |
| 724 self.rebaseline(options, test_baseline_set) | 727 self.rebaseline(options, test_baseline_set) |
| OLD | NEW |