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 456a32b32e73b478728fe5feadb2eb6a846505d5..852c136a6cd6c8cbc7e441271d8b85563a2a9d06 100644 |
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py |
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py |
@@ -72,6 +72,13 @@ class AbstractRebaseliningCommand(AbstractDeclarativeCommand): |
def __init__(self, options=None): |
super(AbstractRebaseliningCommand, self).__init__(options=options) |
self._baseline_suffix_list = BASELINE_SUFFIX_LIST |
+ self._scm_changes = {'add': [], 'delete': [], 'remove-lines': []} |
+ |
+ def _add_to_scm_later(self, path): |
+ self._scm_changes['add'].append(path) |
+ |
+ def _delete_from_scm_later(self, path): |
+ self._scm_changes['delete'].append(path) |
class BaseInternalRebaselineCommand(AbstractRebaseliningCommand): |
@@ -82,10 +89,6 @@ class BaseInternalRebaselineCommand(AbstractRebaseliningCommand): |
optparse.make_option("--builder", help="Builder to pull new baselines from"), |
optparse.make_option("--test", help="Test to rebaseline"), |
]) |
- self._scm_changes = {'add': [], 'remove-lines': []} |
- |
- def _add_to_scm(self, path): |
- self._scm_changes['add'].append(path) |
def _baseline_directory(self, builder_name): |
port = self._tool.port_factory.get_from_builder_name(builder_name) |
@@ -168,7 +171,7 @@ class CopyExistingBaselinesInternal(BaseInternalRebaselineCommand): |
self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dirname(new_baseline)) |
self._tool.filesystem.copyfile(old_baseline, new_baseline) |
if not self._tool.scm().exists(new_baseline): |
- self._add_to_scm(new_baseline) |
+ self._add_to_scm_later(new_baseline) |
def execute(self, options, args, tool): |
for suffix in options.suffixes.split(','): |
@@ -192,7 +195,7 @@ class RebaselineTest(BaseInternalRebaselineCommand): |
filesystem.maybe_make_directory(filesystem.dirname(target_baseline)) |
filesystem.write_binary_file(target_baseline, data) |
if not self._tool.scm().exists(target_baseline): |
- self._add_to_scm(target_baseline) |
+ self._add_to_scm_later(target_baseline) |
def _rebaseline_test(self, builder_name, test_name, suffix, results_url): |
baseline_directory = self._baseline_directory(builder_name) |
@@ -231,13 +234,18 @@ class OptimizeBaselines(AbstractRebaseliningCommand): |
argument_names = "TEST_NAMES" |
def __init__(self): |
- super(OptimizeBaselines, self).__init__(options=[self.suffixes_option] + self.platform_options) |
+ super(OptimizeBaselines, self).__init__(options=[ |
+ self.suffixes_option, |
+ optparse.make_option('--no-modify-scm', action='store_true', default=False, help='Dump SCM commands as JSON instead of '), |
+ ] + self.platform_options) |
def _optimize_baseline(self, optimizer, test_name): |
for suffix in self._baseline_suffix_list: |
baseline_name = _baseline_name(self._tool.filesystem, test_name, suffix) |
- if not optimizer.optimize(baseline_name): |
+ succeeded, files_to_delete, files_to_add = optimizer.optimize(baseline_name) |
+ if not succeeded: |
print "Heuristics failed to optimize %s" % baseline_name |
+ return files_to_delete, files_to_add |
def execute(self, options, args, tool): |
self._baseline_suffix_list = options.suffixes.split(',') |
@@ -246,11 +254,17 @@ class OptimizeBaselines(AbstractRebaseliningCommand): |
print "No port names match '%s'" % options.platform |
return |
- optimizer = BaselineOptimizer(tool, port_names) |
+ optimizer = BaselineOptimizer(tool, port_names, skip_scm_commands=options.no_modify_scm) |
port = tool.port_factory.get(port_names[0]) |
for test_name in port.tests(args): |
_log.info("Optimizing %s" % test_name) |
- self._optimize_baseline(optimizer, test_name) |
+ files_to_delete, files_to_add = self._optimize_baseline(optimizer, test_name) |
+ for path in files_to_delete: |
+ self._delete_from_scm_later(path) |
+ for path in files_to_add: |
+ self._add_to_scm_later(path) |
+ |
+ print json.dumps(self._scm_changes) |
class AnalyzeBaselines(AbstractRebaseliningCommand): |
@@ -288,7 +302,7 @@ class AnalyzeBaselines(AbstractRebaseliningCommand): |
print "No port names match '%s'" % options.platform |
return |
- self._baseline_optimizer = self._optimizer_class(tool, port_names) |
+ self._baseline_optimizer = self._optimizer_class(tool, port_names, skip_scm_commands=False) |
self._port = tool.port_factory.get(port_names[0]) |
for test_name in self._port.tests(args): |
self._analyze_baseline(options, test_name) |
@@ -373,8 +387,9 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
rebaseline_commands.append(tuple([[path_to_webkit_patch, 'rebaseline-test-internal'] + cmd_line, cwd])) |
return copy_baseline_commands, rebaseline_commands |
- def _files_to_add(self, command_results): |
+ def _serial_commands(self, command_results): |
files_to_add = set() |
+ files_to_delete = set() |
lines_to_remove = {} |
for output in [result[1].split('\n') for result in command_results]: |
file_added = False |
@@ -384,6 +399,8 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
parsed_line = json.loads(line) |
if 'add' in parsed_line: |
files_to_add.update(parsed_line['add']) |
+ if 'delete' in parsed_line: |
+ files_to_delete.update(parsed_line['delete']) |
if 'remove-lines' in parsed_line: |
for line_to_remove in parsed_line['remove-lines']: |
test = line_to_remove['test'] |
@@ -398,16 +415,24 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
if not file_added: |
_log.debug('Could not add file based off output "%s"' % output) |
- return list(files_to_add), lines_to_remove |
+ return list(files_to_add), list(files_to_delete), lines_to_remove |
def _optimize_baselines(self, test_prefix_list, verbose=False): |
- # We don't run this in parallel because modifying the SCM in parallel is unreliable. |
+ optimize_commands = [] |
for test in test_prefix_list: |
all_suffixes = set() |
for builder in self._builders_to_fetch_from(test_prefix_list[test]): |
all_suffixes.update(self._suffixes_for_actual_failures(test, builder, test_prefix_list[test][builder])) |
+ |
# FIXME: We should propagate the platform options as well. |
- self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(all_suffixes), test], verbose) |
+ cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes), test] |
+ if verbose: |
+ cmd_line.append('--verbose') |
+ |
+ path_to_webkit_patch = self._tool.path() |
+ cwd = self._tool.scm().checkout_root |
+ optimize_commands.append(tuple([[path_to_webkit_patch, 'optimize-baselines'] + cmd_line, cwd])) |
+ 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 |
@@ -451,9 +476,11 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
if line: |
print >> sys.stderr, line # FIXME: Figure out how to log properly. |
- files_to_add, lines_to_remove = self._files_to_add(command_results) |
+ files_to_add, files_to_delete, lines_to_remove = self._serial_commands(command_results) |
+ if files_to_delete: |
+ self._tool.scm().delete_list(files_to_delete) |
if files_to_add: |
- self._tool.scm().add_list(list(files_to_add)) |
+ self._tool.scm().add_list(files_to_add) |
if lines_to_remove: |
self._update_expectations_files(lines_to_remove) |
@@ -468,9 +495,8 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
self._run_in_parallel_and_update_scm(copy_baseline_commands) |
if rebaseline_commands: |
self._run_in_parallel_and_update_scm(rebaseline_commands) |
- |
if options.optimize: |
- self._optimize_baselines(test_prefix_list, options.verbose) |
+ self._run_in_parallel_and_update_scm(self._optimize_baselines(test_prefix_list, options.verbose)) |
def _suffixes_for_actual_failures(self, test, builder_name, existing_suffixes): |
actual_results = self.builder_data()[builder_name].actual_results(test) |