Diff
Modified: trunk/Tools/ChangeLog (92492 => 92493)
--- trunk/Tools/ChangeLog 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/ChangeLog 2011-08-05 18:50:37 UTC (rev 92493)
@@ -1,3 +1,29 @@
+2011-08-05 Adam Barth <[email protected]>
+
+ Rebuild rebaseline-chromium-webkit-tests on top of modern infrastructure
+ https://bugs.webkit.org/show_bug.cgi?id=65759
+
+ Reviewed by Dimitri Glazkov.
+
+ rebaseline-chromium-webkit-tests doesn't really fit into webkitpy's
+ architecture, is poorly tested, and has a bunch of quirks. This patch
+ rebuilds the core functionality of rebaseline-chromium-webkit-tests on
+ top of more modern infrastructure. In the process, we get more code
+ re-use and better testing.
+
+ Once we're satisfied with this new implementation, we can delete the
+ old implementation.
+
+ * Scripts/webkitpy/common/checkout/baselineoptimizer.py:
+ * Scripts/webkitpy/common/net/web.py:
+ * Scripts/webkitpy/layout_tests/models/test_expectations.py:
+ * Scripts/webkitpy/layout_tests/port/builders.py:
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/factory.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/tool/commands/rebaseline.py:
+ * Scripts/webkitpy/tool/commands/rebaseline_unittest.py:
+
2011-08-05 Anders Carlsson <[email protected]>
Remove PluginHalter
Modified: trunk/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -145,6 +145,7 @@
if new_results_by_directory.get(directory) != result:
file_name = self._filesystem.join(self._scm.checkout_root, directory, baseline_name)
self._scm.delete(file_name)
+ # FIXME: Check for empty directories and remove them as well.
def optimize(self, baseline_name):
results_by_directory, new_results_by_directory = self._find_optimal_result_placement(baseline_name)
Modified: trunk/Tools/Scripts/webkitpy/common/net/web.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/common/net/web.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/common/net/web.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -32,5 +32,5 @@
class Web(object):
- def get_binary(self, url):
- return NetworkTransaction().run(lambda: urllib2.urlopen(url).read())
+ def get_binary(self, url, convert_404_to_None=False):
+ return NetworkTransaction(convert_404_to_None=convert_404_to_None).run(lambda: urllib2.urlopen(url).read())
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -776,7 +776,7 @@
return cls.EXPECTATIONS.get(string.lower())
def __init__(self, port, tests, expectations,
- test_config, is_lint_mode, overrides=None):
+ test_config, is_lint_mode=False, overrides=None):
"""Loads and parses the test expectations given in the string.
Args:
port: handle to object containing platform-specific functionality
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -29,61 +29,94 @@
import re
+from webkitpy.common.memoized import memoized
-def builder_path_from_name(builder_name):
- return re.sub(r'[\s().]', '_', builder_name)
+_exact_matches = {
+ # These builders are on build.chromium.org.
+ "Webkit Win": "chromium-win-xp",
+ "Webkit Vista": "chromium-win-vista",
+ "Webkit Win7": "chromium-win-win7",
+ "Webkit Win (dbg)(1)": "chromium-win-xp",
+ "Webkit Win (dbg)(2)": "chromium-win-xp",
+ "Webkit Linux": "chromium-linux-x86_64",
+ "Webkit Linux 32": "chromium-linux-x86",
+ "Webkit Linux (dbg)(1)": "chromium-linux-x86_64",
+ "Webkit Linux (dbg)(2)": "chromium-linux-x86_64",
+ "Webkit Mac10.5": "chromium-mac-leopard",
+ "Webkit Mac10.5 (dbg)(1)": "chromium-mac-leopard",
+ "Webkit Mac10.5 (dbg)(2)": "chromium-mac-leopard",
+ "Webkit Mac10.6": "chromium-mac-snowleopard",
+ "Webkit Mac10.6 (dbg)": "chromium-mac-snowleopard",
+ "Webkit Mac10.6 - GPU": "chromium-gpu-mac-snowleopard",
+ "Webkit Win - GPU": "chromium-gpu-win-xp",
+ "Webkit Win7 - GPU": "chromium-gpu-win-win7",
+ # FIXME: For some reason, these port names don't work correctly.
+ # "Webkit Linux - GPU": "chromium-gpu-linux-x86_64",
+ # "Webkit Linux 32 - GPU": "chromium-gpu-linux-x86",
+ "Webkit Mac10.5 - GPU": "chromium-gpu-mac-leopard",
+ "Webkit Mac10.6 - GPU": "chromium-gpu-mac-snowleopard",
-# Compiled manually from http://build.chromium.org/p/chromium/json/builders/help?as_text=1
-# Values of None mean there are no bots running at build.webkit.org or
-# build.chromium.org for that port.
-# FIXME Make the values in this map into lists.
-CHROMIUM_PORT_TO_BUILDER_NAME = {
- 'chromium-gpu-linux': builder_path_from_name('Webkit Linux - GPU'),
+ # These builders are on build.webkit.org.
+ "GTK Linux 32-bit Debug": "gtk",
+ "Leopard Intel Debug (Tests)": "mac-leopard",
+ "SnowLeopard Intel Release (Tests)": "mac-snowleopard",
+ "SnowLeopard Intel Release (WebKit2 Tests)": "mac-wk2",
+ "Qt Linux Release": "qt-linux",
+ "Windows XP Debug (Tests)": "win-xp",
+ "Windows 7 Release (WebKit2 Tests)": "win-wk2",
+}
- 'chromium-gpu-mac-snowleopard': builder_path_from_name('Webkit Mac10.6 - GPU'),
- 'chromium-gpu-mac-leopard': builder_path_from_name('Webkit Mac10.5 - GPU'),
- 'chromium-gpu-win-xp': builder_path_from_name('Webkit Win - GPU'),
- 'chromium-gpu-win-vista': builder_path_from_name('Webkit Vista - GPU'),
- 'chromium-gpu-win-win7': builder_path_from_name('Webkit Win7 - GPU'),
+_fuzzy_matches = {
+ # These builders are on build.webkit.org.
+ r"SnowLeopard": "mac-snowleopard",
+ r"Leopard": "mac-leopard",
+ r"Windows": "win",
+ r"GTK": "gtk",
+ r"Qt": "qt",
+ r"Chromium Mac": "chromium-mac",
+ r"Chromium Linux": "chromium-linux",
+ r"Chromium Win": "chromium-win",
+}
- 'chromium-linux-x86_64': builder_path_from_name('Linux Tests x64'),
- 'chromium-linux-x86': builder_path_from_name('Linux Tests (dbg)(1)'),
- 'chromium-mac-leopard': builder_path_from_name('Mac10.5 Tests (1)'),
- 'chromium-mac-snowleopard': builder_path_from_name('Mac 10.6 Tests (dbg)(1)'),
+_ports_without_builders = [
+ # FIXME: Including chromium-gpu-linux below is a workaroudn for
+ # chromium-gpu-linux-x86_64 and chromium-gpu-linux-x86 not working properly.
+ "chromium-gpu-linux",
+ "google-chrome-linux32",
+ "google-chrome-linux64",
+ "qt-mac",
+ "qt-win",
+ "qt-wk2",
+]
- 'chromium-win-xp': builder_path_from_name('XP Tests (dbg)(5)'),
- 'chromium-win-vista': builder_path_from_name('Vista Tests (dbg)(1)'),
- 'chromium-win-win7': None,
- 'google-chrome-linux32': None,
- 'google-chrome-linux64': None,
-}
+def builder_path_from_name(builder_name):
+ return re.sub(r'[\s().]', '_', builder_name)
-# Compiled manually from http://build.webkit.org/builders
-WEBKIT_PORT_TO_BUILDER_NAME = {
- 'gtk': 'GTK Linux 32-bit Debug',
- 'mac-leopard': 'Leopard Intel Debug (Tests)',
- 'mac-snowleopard': 'SnowLeopard Intel Release (Tests)',
- 'mac-wk2': 'SnowLeopard Intel Release (WebKit2 Tests)',
+@memoized
+def all_port_names():
+ return sorted(set(_exact_matches.values() + _ports_without_builders))
- 'qt-linux': 'Qt Linux Release',
- 'qt-mac': None,
- 'qt-win': None,
- 'qt-wk2': None,
- 'win-xp': 'Windows XP Debug (Tests)',
- 'win': None,
- 'win-wk2': 'Windows 7 Release (WebKit2 Tests)',
-}
+def port_name_for_builder_name(builder_name):
+ if builder_name in _exact_matches:
+ return _exact_matches[builder_name]
-PORT_TO_BUILDER_NAME = {}
-PORT_TO_BUILDER_NAME.update(CHROMIUM_PORT_TO_BUILDER_NAME)
-PORT_TO_BUILDER_NAME.update(WEBKIT_PORT_TO_BUILDER_NAME)
+ for regexp, port_name in _fuzzy_matches.items():
+ if re.match(regexp, builder_name):
+ return port_name
-def builder_name_for_platform(platform):
- return PORT_TO_BUILDER_NAME.get(platform)
+def builder_name_for_port_name(target_port_name):
+ for builder_name, port_name in _exact_matches.items():
+ if port_name == target_port_name:
+ return builder_name
+ return None
+
+
+def builder_path_for_port_name(port_name):
+ builder_path_from_name(builder_name_for_port_name(port_name))
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -226,7 +226,7 @@
'chromium', 'test_expectations.txt')
def _results_for_platform(self, platform):
- builder_name = builders.builder_name_for_platform(platform)
+ builder_name = builders.builder_path_for_port_name(platform)
if not builder_name:
raise Exception("Can't find builder for %s" % platform)
zip_url = urls.chromium_results_zip_url(builder_name)
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -42,7 +42,7 @@
by real ports. This does not include any "fake" names like "test"
or "mock-mac", and it does not include any directories that are not ."""
# FIXME: There's probably a better way to generate this list ...
- return builders.PORT_TO_BUILDER_NAME.keys()
+ return builders.all_port_names()
def get(port_name=None, options=None, **kwargs):
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -81,7 +81,7 @@
return self._filesystem.join(self._webkit_baseline_path(expectations_directory), 'test_expectations.txt')
def _results_for_platform(self, platform):
- builder_name = builders.builder_name_for_platform(platform)
+ builder_name = builders.builder_path_for_port_name(platform)
if not builder_name:
raise Exception("Can't find builder for %s" % platform)
builders_by_name = dict([(builder.name(), builder) for builder in BuildBot().builders()])
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -35,14 +35,27 @@
from webkitpy.common.checkout.baselineoptimizer import BaselineOptimizer
from webkitpy.common.net.buildbot import BuildBot
from webkitpy.common.net.layouttestresults import LayoutTestResults
+from webkitpy.common.system.executive import ScriptError
from webkitpy.common.system.user import User
from webkitpy.layout_tests.layout_package.test_result_writer import TestResultWriter
from webkitpy.layout_tests.models import test_failures
-from webkitpy.layout_tests.port import factory
+from webkitpy.layout_tests.models.test_expectations import TestExpectations
+from webkitpy.layout_tests.port import factory, builders
from webkitpy.tool.grammar import pluralize
from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
+_baseline_suffix_list = ['png', 'txt']
+
+
+def _port_for_builder(builder_name):
+ port_name = builders.port_name_for_builder_name(builder_name)
+ assert(port_name) # Need to update port_name_for_builder_name
+ port = factory.get(port_name, RebaseliningOptions(builder_name))
+ assert(port) # Need to update port_name_for_builder_name
+ return port
+
+
class RebaseliningOptions(object):
DEBUG_CONFIGURATION_REGEX = r"[d|D](ebu|b)g"
@@ -52,54 +65,11 @@
self.builder_name = builder_name
-# FIXME: This logic should be moved to builders.py.
-class BuilderToPort(object):
-
- _builder_name_to_port_name = {
- # These builders are on build.webkit.org.
- r"SnowLeopard": "mac-snowleopard",
- r"Leopard": "mac-leopard",
- r"Windows": "win",
- r"GTK": "gtk",
- r"Qt": "qt",
- r"Chromium Mac": "chromium-mac",
- r"Chromium Linux": "chromium-linux",
- r"Chromium Win": "chromium-win",
-
- # These builders are on build.chromium.org.
- r"Webkit Win$": "chromium-win-xp",
- r"Webkit Vista": "chromium-win-vista",
- r"Webkit Win7": "chromium-win-win7",
- r"Webkit Win \(dbg\)\(1\)": "chromium-win-xp",
- r"Webkit Win \(dbg\)\(2\)": "chromium-win-xp",
- r"Webkit Linux": "chromium-linux-x86_64",
- r"Webkit Linux 32": "chromium-linux-x86",
- r"Webkit Linux \(dbg\)\(1\)": "chromium-linux-x86_64",
- r"Webkit Linux \(dbg\)\(2\)": "chromium-linux-x86_64",
- r"Webkit Mac10\.5": "chromium-mac-leopard",
- r"Webkit Mac10\.5 \(dbg\)\(1\)": "chromium-mac-leopard",
- r"Webkit Mac10\.5 \(dbg\)\(2\)": "chromium-mac-leopard",
- r"Webkit Mac10\.6": "chromium-mac-snowleopard",
- r"Webkit Mac10\.6 \(dbg\)": "chromium-mac-snowleopard",
- }
-
- def _port_name_for_builder_name(self, builder_name):
- for regexp, port_name in self._builder_name_to_port_name.items():
- if re.match(regexp, builder_name):
- return port_name
-
- def port_for_builder(self, builder_name):
- port_name = self._port_name_for_builder_name(builder_name)
- assert(port_name) # Need to update _builder_name_to_port_name
- port = factory.get(port_name, RebaseliningOptions(builder_name))
- assert(port) # Need to update _builder_name_to_port_name
- return port
-
-
class RebaselineTest(AbstractDeclarativeCommand):
name = "rebaseline-test"
help_text = "Rebaseline a single test from a buildbot. (Currently works only with build.chromium.org buildbots.)"
- argument_names = "BUILDER_NAME TEST_NAME SUFFIX"
+ # FIXME: Remove SUFFIX argument.
+ argument_names = "BUILDER_NAME TEST_NAME [SUFFIX]"
def _results_url(self, builder_name):
# FIXME: Generalize this command to work with non-build.chromium.org builders.
@@ -107,10 +77,12 @@
return builder.accumulated_results_url()
def _baseline_directory(self, builder_name):
- port = BuilderToPort().port_for_builder(builder_name)
+ port = _port_for_builder(builder_name)
return port.baseline_path()
def _save_baseline(self, data, target_baseline):
+ if not data:
+ return
filesystem = self._tool.filesystem
filesystem.maybe_make_directory(filesystem.dirname(target_baseline))
filesystem.write_binary_file(target_baseline, data)
@@ -130,14 +102,15 @@
results_url = self._results_url(builder_name)
baseline_directory = self._baseline_directory(builder_name)
- source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_result(test_name, suffix))
+ source_baseline = "%s%s" % (results_url, self._file_name_for_actual_result(test_name, suffix))
target_baseline = os.path.join(baseline_directory, self._file_name_for_expected_result(test_name, suffix))
- print "Retrieving %s ..." % source_baseline
- self._save_baseline(self._tool.web.get_binary(source_baseline), target_baseline)
+ print "Retrieving %s." % source_baseline
+ self._save_baseline(self._tool.web.get_binary(source_baseline, convert_404_to_None=True), target_baseline)
def execute(self, options, args, tool):
- self._rebaseline_test(args[0], args[1], args[2])
+ for suffix in _baseline_suffix_list:
+ self._rebaseline_test(args[0], args[1], suffix)
class OptimizeBaselines(AbstractDeclarativeCommand):
@@ -147,18 +120,65 @@
# FIXME: Should TestResultWriter know how to compute this string?
def _baseline_name(self, test_name, suffix):
- return self._tool.filesystem.splitext(test_name)[0] + TestResultWriter.FILENAME_SUFFIX_EXPECTED + suffix
+ return self._tool.filesystem.splitext(test_name)[0] + TestResultWriter.FILENAME_SUFFIX_EXPECTED + "." + suffix
def execute(self, options, args, tool):
baseline_optimizer = BaselineOptimizer(tool.scm(), tool.filesystem)
test_name = args[0]
- for suffix in ['.png', '.txt']:
+ for suffix in _baseline_suffix_list:
baseline_name = self._baseline_name(test_name, suffix)
if not baseline_optimizer.optimize(baseline_name):
print "Hueristics failed to optimize %s" % baseline_name
+class RebaselineExpectations(AbstractDeclarativeCommand):
+ name = "rebaseline-expectations"
+ help_text = "Rebaselines the tests indicated in test_expectations.txt."
+
+ def _run_webkit_patch(self, args):
+ try:
+ self._tool.executive.run_command([self._tool.path()] + args, cwd=self._tool.scm().checkout_root)
+ except ScriptError, e:
+ pass
+
+ def _is_supported_port(self, port_name):
+ # FIXME: Support non-Chromium ports.
+ return port_name.startswith('chromium-')
+
+ def _update_expectations_file(self, port, expectations, tests_to_rebaseline):
+ new_expectations = expectations.remove_rebaselined_tests(tests_to_rebaseline)
+ path = port.path_to_test_expectations_file()
+ self._tool.filesystem.write_text_file(path, new_expectations)
+
+ # FIXME: We read and write the test_expectations.txt file once for each port. That seems excessive.
+ def _tests_to_rebaseline(self, port):
+ expectations = TestExpectations(port, None, port.test_expectations(), port.test_configuration())
+ tests_to_rebaseline = expectations.get_rebaselining_failures()
+ self._update_expectations_file(port, expectations, tests_to_rebaseline)
+ return tests_to_rebaseline
+
+ def _rebaseline_port(self, port_name):
+ if not self._is_supported_port(port_name):
+ return
+ builder_name = builders.builder_name_for_port_name(port_name)
+ if not builder_name:
+ return
+ print "Retrieving results for %s from %s." % (port_name, builder_name)
+ for test_name in self._tests_to_rebaseline(factory.get(port_name)):
+ self._touched_test_names.add(test_name)
+ print " %s" % test_name
+ self._run_webkit_patch(['rebaseline-test', builder_name, test_name])
+
+ def execute(self, options, args, tool):
+ self._touched_test_names = set([])
+ for port_name in factory.all_port_names():
+ self._rebaseline_port(port_name)
+ for test_name in self._touched_test_names:
+ print "Optimizing baselines for %s." % test_name
+ self._run_webkit_patch(['optimize-baselines', test_name])
+
+
class Rebaseline(AbstractDeclarativeCommand):
name = "rebaseline"
help_text = "Replaces local expected.txt files with new results from build bots"
@@ -191,7 +211,7 @@
def execute(self, options, args, tool):
builder, build_number = self._builder_to_pull_from()
build = builder.build(build_number)
- port = BuilderToPort().port_for_builder(builder.name())
+ port = builder_name_for_port_name.port_for_builder(builder.name())
for test in self._tests_to_update(build):
results_url = self._results_url_for_test(build, test)
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py (92492 => 92493)
--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py 2011-08-05 18:44:45 UTC (rev 92492)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py 2011-08-05 18:50:37 UTC (rev 92493)
@@ -31,33 +31,71 @@
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.thirdparty.mock import Mock
from webkitpy.tool.commands.rebaseline import *
-from webkitpy.tool.mocktool import MockTool
+from webkitpy.tool.mocktool import MockTool, MockExecutive
class TestRebaseline(unittest.TestCase):
- # This just makes sure the code runs without exceptions.
def test_tests_to_update(self):
command = Rebaseline()
command.bind_to_tool(MockTool())
build = Mock()
OutputCapture().assert_outputs(self, command._tests_to_update, [build])
-
-class TestRebaselineTest(unittest.TestCase):
- def test_tests_to_update(self):
+ def test_rebaseline_test(self):
command = RebaselineTest()
command.bind_to_tool(MockTool())
- build = Mock()
- expected_stdout = "Retrieving http://example.com/f/builders/Webkit Linux/results//userscripts/another-test-actual.txt ...\n"
+ expected_stdout = "Retrieving http://example.com/f/builders/Webkit Linux/results/userscripts/another-test-actual.txt.\n"
OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Linux", "userscripts/another-test.html", "txt"], expected_stdout=expected_stdout)
-
-class BuilderToPortTest(unittest.TestCase):
- def test_port_for_builder(self):
- converter = BuilderToPort()
- port = converter.port_for_builder("Leopard Intel Debug (Tests)")
- self.assertEqual(str(port.test_configuration()), "<leopard, x86, debug, cpu>")
- port = converter.port_for_builder("Leopard Intel Release (Tests)")
- self.assertEqual(str(port.test_configuration()), "<leopard, x86, release, cpu>")
- port = converter.port_for_builder("Webkit Win (dbg)(1)")
- self.assertEqual(str(port.test_configuration()), "<xp, x86, debug, cpu>")
+ def test_rebaseline_expectations(self):
+ command = RebaselineExpectations()
+ tool = MockTool()
+ tool.executive = MockExecutive(should_log=True)
+ command.bind_to_tool(tool)
+ expected_stdout = """Retrieving results for chromium-gpu-mac-leopard from Webkit Mac10.5 - GPU.
+Retrieving results for chromium-gpu-mac-snowleopard from Webkit Mac10.6 - GPU.
+Retrieving results for chromium-gpu-win-win7 from Webkit Win7 - GPU.
+Retrieving results for chromium-gpu-win-xp from Webkit Win - GPU.
+Retrieving results for chromium-linux-x86 from Webkit Linux 32.
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-linux-x86_64 from Webkit Linux (dbg)(2).
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-mac-leopard from Webkit Mac10.5 (dbg)(1).
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-mac-snowleopard from Webkit Mac10.6 (dbg).
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-win-vista from Webkit Vista.
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-win-win7 from Webkit Win7.
+ userscripts/another-test.html
+ userscripts/images.svg
+Retrieving results for chromium-win-xp from Webkit Win (dbg)(2).
+ userscripts/another-test.html
+ userscripts/images.svg
+Optimizing baselines for userscripts/another-test.html.
+Optimizing baselines for userscripts/images.svg.
+"""
+ expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Linux 32', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Linux 32', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Linux (dbg)(2)', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Linux (dbg)(2)', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Mac10.5 (dbg)(1)', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Mac10.5 (dbg)(1)', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Mac10.6 (dbg)', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Mac10.6 (dbg)', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Vista', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Vista', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win7', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win7', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win (dbg)(2)', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win (dbg)(2)', 'userscripts/images.svg'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'optimize-baselines', 'userscripts/another-test.html'], cwd=/mock-checkout
+MOCK run_command: ['echo', 'optimize-baselines', 'userscripts/images.svg'], cwd=/mock-checkout
+"""
+ command._tests_to_rebaseline = lambda port: [] if not port.name().find('-gpu-') == -1 else ['userscripts/another-test.html', 'userscripts/images.svg']
+ OutputCapture().assert_outputs(self, command.execute, [MockTool(), None, None], expected_stdout=expected_stdout, expected_stderr=expected_stderr)