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

Unified Diff: Tools/Scripts/webkitpy/tool/commands/rebaseline.py

Issue 302003009: Make rebaselining not use gigabytes of memory. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: address review comments Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: Tools/Scripts/webkitpy/tool/commands/rebaseline.py
diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
index 852c136a6cd6c8cbc7e441271d8b85563a2a9d06..d6adf3b1b7e895e72c1e88b9a6a894bd6b66bfc5 100644
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -368,6 +368,7 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
cwd = self._tool.scm().checkout_root
copy_baseline_commands = []
rebaseline_commands = []
+ lines_to_remove = {}
port = self._tool.port_factory.get()
for test_prefix in test_prefix_list:
@@ -375,6 +376,11 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
for builder in self._builders_to_fetch_from(test_prefix_list[test_prefix]):
actual_failures_suffixes = self._suffixes_for_actual_failures(test, builder, test_prefix_list[test_prefix][builder])
if not actual_failures_suffixes:
+ # If we're not going to rebaseline the test because it's passing on this
+ # builder, we still want to remove the line from TestExpectations.
+ if test not in lines_to_remove:
+ lines_to_remove[test] = []
+ lines_to_remove[test].append(builder)
continue
suffixes = ','.join(actual_failures_suffixes)
@@ -385,7 +391,7 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
cmd_line.append('--verbose')
copy_baseline_commands.append(tuple([[path_to_webkit_patch, 'copy-existing-baselines-internal'] + cmd_line, cwd]))
rebaseline_commands.append(tuple([[path_to_webkit_patch, 'rebaseline-test-internal'] + cmd_line, cwd]))
- return copy_baseline_commands, rebaseline_commands
+ return copy_baseline_commands, rebaseline_commands, lines_to_remove
def _serial_commands(self, command_results):
files_to_add = set()
@@ -435,37 +441,45 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
return optimize_commands
def _update_expectations_files(self, lines_to_remove):
- # FIXME: This routine is way too expensive. We're creating N ports and N TestExpectations
- # objects and (re-)writing the actual expectations file N times, for each test we update.
- # We should be able to update everything in memory, once, and then write the file out a single time.
+ # FIXME: This routine is way too expensive. We're creating O(n ports) TestExpectations objects.
+ # This is slow and uses a lot of memory.
+ tests = lines_to_remove.keys()
+ to_remove = []
+
+ # This is so we remove lines for builders that skip this test, e.g. Android skips most
+ # tests and we don't want to leave stray [ Android ] lines in TestExpectations..
+ # FIXME: Is this necessary at all now that _rebaseline_commands includes the builders that
+ # used to be skipped because the result wasn't failing on tip of tree?
+ for port_name in self._tool.port_factory.all_port_names():
+ port = self._tool.port_factory.get(port_name)
+ generic_expectations = TestExpectations(port, tests=tests, include_overrides=False)
+ full_expectations = TestExpectations(port, tests=tests, include_overrides=True)
+ for test in tests:
+ if self._port_skips_test(port, test, generic_expectations, full_expectations):
+ for test_configuration in port.all_test_configurations():
+ if test_configuration.version == port.test_configuration().version:
+ to_remove.append((test, test_configuration))
+
for test in lines_to_remove:
for builder in lines_to_remove[test]:
port = self._tool.port_factory.get_from_builder_name(builder)
- path = port.path_to_generic_test_expectations_file()
- expectations = TestExpectations(port, include_overrides=False)
for test_configuration in port.all_test_configurations():
if test_configuration.version == port.test_configuration().version:
- expectationsString = expectations.remove_configuration_from_test(test, test_configuration)
- self._tool.filesystem.write_text_file(path, expectationsString)
+ to_remove.append((test, test_configuration))
- for port_name in self._tool.port_factory.all_port_names():
- port = self._tool.port_factory.get(port_name)
- generic_expectations = TestExpectations(port, tests=[test], include_overrides=False)
- if self._port_skips_test(port, test, generic_expectations):
- for test_configuration in port.all_test_configurations():
- if test_configuration.version == port.test_configuration().version:
- expectationsString = generic_expectations.remove_configuration_from_test(test, test_configuration)
- generic_path = port.path_to_generic_test_expectations_file()
- self._tool.filesystem.write_text_file(generic_path, expectationsString)
+ port = self._tool.port_factory.get()
+ expectations = TestExpectations(port, include_overrides=False)
+ expectationsString = expectations.remove_configurations(to_remove)
+ path = port.path_to_generic_test_expectations_file()
+ self._tool.filesystem.write_text_file(path, expectationsString)
- def _port_skips_test(self, port, test, generic_expectations):
+ def _port_skips_test(self, port, test, generic_expectations, full_expectations):
fs = port.host.filesystem
if port.default_smoke_test_only():
smoke_test_filename = fs.join(port.layout_tests_dir(), 'SmokeTests')
if fs.exists(smoke_test_filename) and test not in fs.read_text_file(smoke_test_filename):
return True
- full_expectations = TestExpectations(port, tests=[test], include_overrides=True)
return (SKIP in full_expectations.get_expectations(test) and
SKIP not in generic_expectations.get_expectations(test))
@@ -481,8 +495,7 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
self._tool.scm().delete_list(files_to_delete)
if files_to_add:
self._tool.scm().add_list(files_to_add)
- if lines_to_remove:
- self._update_expectations_files(lines_to_remove)
+ return lines_to_remove
def _rebaseline(self, options, test_prefix_list):
for test, builders_to_check in sorted(test_prefix_list.items()):
@@ -490,11 +503,23 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
for builder, suffixes in sorted(builders_to_check.items()):
_log.debug(" %s: %s" % (builder, ",".join(suffixes)))
- copy_baseline_commands, rebaseline_commands = self._rebaseline_commands(test_prefix_list, options)
+ copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = self._rebaseline_commands(test_prefix_list, options)
+ lines_to_remove = {}
+
if copy_baseline_commands:
self._run_in_parallel_and_update_scm(copy_baseline_commands)
if rebaseline_commands:
- self._run_in_parallel_and_update_scm(rebaseline_commands)
+ lines_to_remove = self._run_in_parallel_and_update_scm(rebaseline_commands)
+
+ for test in extra_lines_to_remove:
+ if test in lines_to_remove:
+ lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_remove[test]
+ else:
+ lines_to_remove[test] = extra_lines_to_remove[test]
+
+ if lines_to_remove:
+ self._update_expectations_files(lines_to_remove)
+
if options.optimize:
self._run_in_parallel_and_update_scm(self._optimize_baselines(test_prefix_list, options.verbose))
@@ -865,9 +890,6 @@ class AutoRebaseline(AbstractParallelRebaselineCommand):
# to rebaseline, but we'll still need to update TestExpectations.
if test_prefix_list:
self._rebaseline(options, test_prefix_list)
- # If a test is not failing on the bot, we don't try to rebaseline it, but we still
- # want to remove the NeedsRebaseline line.
- self._update_expectations_files(lines_to_remove)
tool.scm().commit_locally_with_message(self.commit_message(author, revision, bugs))

Powered by Google App Engine
This is Rietveld 408576698