Title: [90770] trunk/Tools
Revision
90770
Author
aba...@webkit.org
Date
2011-07-11 11:51:13 -0700 (Mon, 11 Jul 2011)

Log Message

Add a webkit-patch command for rebaselining an individual test
https://bugs.webkit.org/show_bug.cgi?id=64246

Reviewed by Eric Seidel.

This patch introduces a command that's able to rebaseline a single
test.  Currently, the command works only with the build.chromium.org
buildbots, but extending it to work with the build.webkit.org bots
shouldn't be that hard.

A complete rebaseling tool should also include an "optimize baselines"
command (which moves/deletes baselines in order to reduce the number of
expected results files), but that will come in a future patch.

Really BuilderToPort should be merged into builders.py, but I'm going
to save that for a future patch as well.  (We need to stop shaving yaks
at some point.)

* Scripts/webkitpy/tool/commands/rebaseline.py:

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (90769 => 90770)


--- trunk/Tools/ChangeLog	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/ChangeLog	2011-07-11 18:51:13 UTC (rev 90770)
@@ -1,5 +1,27 @@
 2011-07-11  Adam Barth  <aba...@webkit.org>
 
+        Add a webkit-patch command for rebaselining an individual test
+        https://bugs.webkit.org/show_bug.cgi?id=64246
+
+        Reviewed by Eric Seidel.
+
+        This patch introduces a command that's able to rebaseline a single
+        test.  Currently, the command works only with the build.chromium.org
+        buildbots, but extending it to work with the build.webkit.org bots
+        shouldn't be that hard.
+
+        A complete rebaseling tool should also include an "optimize baselines"
+        command (which moves/deletes baselines in order to reduce the number of
+        expected results files), but that will come in a future patch.
+
+        Really BuilderToPort should be merged into builders.py, but I'm going
+        to save that for a future patch as well.  (We need to stop shaving yaks
+        at some point.)
+
+        * Scripts/webkitpy/tool/commands/rebaseline.py:
+
+2011-07-11  Adam Barth  <aba...@webkit.org>
+
         garden-o-matic should be able to roll out patches
         https://bugs.webkit.org/show_bug.cgi?id=64185
 

Modified: trunk/Tools/Scripts/webkitpy/common/host.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/common/host.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/common/host.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -31,7 +31,7 @@
 from webkitpy.common.checkout import Checkout
 from webkitpy.common.checkout.scm import default_scm
 from webkitpy.common.config.ports import WebKitPort
-from webkitpy.common.net import bugzilla, buildbot, statusserver
+from webkitpy.common.net import bugzilla, buildbot, statusserver, web
 from webkitpy.common.net.irc import ircproxy
 from webkitpy.common.system import executive, filesystem, platforminfo, user, workspace
 from webkitpy.layout_tests import port
@@ -42,6 +42,7 @@
         self.bugs = bugzilla.Bugzilla()
         self.buildbot = buildbot.BuildBot()
         self.executive = executive.Executive()
+        self.web = web.Web()
         self._irc = None
         self.filesystem = filesystem.FileSystem()
         self.workspace = workspace.Workspace(self.filesystem, self.executive)

Modified: trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -69,6 +69,11 @@
     def results_url(self):
         return "%s/results/%s" % (self._buildbot.buildbot_url, self.url_encoded_name())
 
+    # In addition to per-build results, the build.chromium.org builders also
+    # keep a directory that accumulates test results over many runs.
+    def accumulated_results_url(self):
+        return None
+
     def url_encoded_name(self):
         return urllib.quote(self._name)
 
@@ -280,8 +285,11 @@
 
 
 class BuildBot(object):
-    def __init__(self, url=""
-        self.buildbot_url = url
+    _builder_factory = Builder
+    _default_url = config_urls.buildbot_url
+
+    def __init__(self, url=""
+        self.buildbot_url = url if url else self._default_url
         self._builder_by_name = {}
 
         # If any core builder is red we should not be landing patches.  Other
@@ -440,7 +448,7 @@
     def builder_with_name(self, name):
         builder = self._builder_by_name.get(name)
         if not builder:
-            builder = Builder(name, self)
+            builder = self._builder_factory(name, self)
             self._builder_by_name[name] = builder
         return builder
 

Added: trunk/Tools/Scripts/webkitpy/common/net/buildbot/chromiumbuildbot.py (0 => 90770)


--- trunk/Tools/Scripts/webkitpy/common/net/buildbot/chromiumbuildbot.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/net/buildbot/chromiumbuildbot.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -0,0 +1,47 @@
+# Copyright (c) 2011, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import webkitpy.common.config.urls as config_urls
+from webkitpy.common.net.buildbot.buildbot import Builder, BuildBot
+# FIXME: builders should probably be in webkitpy.common.config.
+from webkitpy.layout_tests.port.builders import builder_path_from_name
+
+
+class ChromiumBuilder(Builder):
+    # The build.chromium.org builders store their results in a different
+    # location than the build.webkit.org builders.
+    def results_url(self):
+        return "http://build.chromium.org/f/chromium/layout_test_results/%s" % builder_path_from_name(self._name)
+
+    def accumulated_results_url(self):
+        return self.results_url() + "/results/layout-test-results"
+
+
+class ChromiumBuildBot(BuildBot):
+    _builder_factory = ChromiumBuilder
+    _default_url = config_urls.chromium_buildbot_url

Added: trunk/Tools/Scripts/webkitpy/common/net/web.py (0 => 90770)


--- trunk/Tools/Scripts/webkitpy/common/net/web.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/net/web.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -0,0 +1,36 @@
+# Copyright (C) 2011 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import urllib2
+
+from webkitpy.common.net.networktransaction import NetworkTransaction
+
+
+class Web(object):
+    def get_binary(self, url):
+        return NetworkTransaction().run(lambda: urllib2.urlopen(url).read())

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/builders.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -30,31 +30,32 @@
 import re
 
 
-def _path_from_name(name):
-    return re.sub(r'[\s().]', '_', name)
+def builder_path_from_name(builder_name):
+    return re.sub(r'[\s().]', '_', builder_name)
 
+
 # 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': _path_from_name('Webkit Linux - GPU'),
+    'chromium-gpu-linux': builder_path_from_name('Webkit Linux - GPU'),
 
-    'chromium-gpu-mac-snowleopard': _path_from_name('Webkit Mac10.6 - GPU'),
-    'chromium-gpu-mac-leopard': _path_from_name('Webkit Mac10.5 - GPU'),
+    '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': _path_from_name('Webkit Win - GPU'),
-    'chromium-gpu-win-vista': _path_from_name('Webkit Vista - GPU'),
-    'chromium-gpu-win-win7': _path_from_name('Webkit Win7 - 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'),
 
-    'chromium-linux-x86_64': _path_from_name('Linux Tests x64'),
-    'chromium-linux-x86': _path_from_name('Linux Tests (dbg)(1)'),
+    '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': _path_from_name('Mac10.5 Tests (1)'),
-    'chromium-mac-snowleopard': _path_from_name('Mac 10.6 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)'),
 
-    'chromium-win-xp': _path_from_name('XP Tests (dbg)(5)'),
-    'chromium-win-vista': _path_from_name('Vista Tests (dbg)(1)'),
+    '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,

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/builders_unittest.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/builders_unittest.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/builders_unittest.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -38,7 +38,7 @@
             '(.) ': '____',
         }
         for name, expected in tests.items():
-            self.assertEquals(expected, builders._path_from_name(name))
+            self.assertEquals(expected, builders.builder_path_from_name(name))
 
 if __name__ == '__main__':
     unittest.main()

Modified: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -31,7 +31,9 @@
 import shutil
 import urllib
 
+import webkitpy.common.config.urls as config_urls
 from webkitpy.common.net.buildbot import BuildBot
+from webkitpy.common.net.buildbot.chromiumbuildbot import ChromiumBuildBot
 from webkitpy.common.net.layouttestresults import LayoutTestResults
 from webkitpy.common.system.user import User
 from webkitpy.layout_tests.models import test_failures
@@ -40,10 +42,10 @@
 from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
 
 
-# FIXME: I'm not sure where this logic should go in the end.
-# For now it's here, until we have a second need for it.
+# 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",
@@ -52,6 +54,22 @@
         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-win7",  # FIXME: Is this correct?
+        r"Webkit Win (dbg)(2)": "chromium-win-win7",  # FIXME: Is this correct?
+        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):
@@ -67,6 +85,49 @@
         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"
+
+    def _results_url(self, builder_name):
+        # FIXME: Generalize this command to work with non-build.chromium.org builders.
+        # FIXME: We should really get the buildbot from the tool!
+        builder = ChromiumBuildBot().builder_with_name(builder_name)
+        return builder.accumulated_results_url()
+
+    def _baseline_directory(self, builder_name):
+        port = BuilderToPort().port_for_builder(builder_name)
+        return port.baseline_path()
+
+    def _save_baseline(self, data, target_baseline):
+        self._tool.filesystem.write_binary_file(target_baseline, data)
+        if not self._tool.scm().exists(target_baseline):
+            self._tool.scm().add(target_baseline)
+
+    def _test_root(self, test_name):
+        return os.path.splitext(test_name)[0]
+
+    def _file_name_for_actual_result(self, test_name, suffix):
+        return "%s-actual.%s" % (self._test_root(test_name), suffix)
+
+    def _file_name_for_expected_result(self, test_name, suffix):
+        return "%s-expected.%s" % (self._test_root(test_name), suffix)
+
+    def _rebaseline_test(self, builder_name, test_name, suffix):
+        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))
+        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)
+
+    def execute(self, options, args, tool):
+        self._rebaseline_test(args[0], args[1], args[2])
+
+
 class Rebaseline(AbstractDeclarativeCommand):
     name = "rebaseline"
     help_text = "Replaces local expected.txt files with new results from build bots"

Modified: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -30,11 +30,11 @@
 
 from webkitpy.common.system.outputcapture import OutputCapture
 from webkitpy.thirdparty.mock import Mock
-from webkitpy.tool.commands.rebaseline import BuilderToPort, Rebaseline
+from webkitpy.tool.commands.rebaseline import *
 from webkitpy.tool.mocktool import MockTool
 
 
-class RebaselineTest(unittest.TestCase):
+class TestRebaseline(unittest.TestCase):
     # This just makes sure the code runs without exceptions.
     def test_tests_to_update(self):
         command = Rebaseline()
@@ -43,6 +43,15 @@
         OutputCapture().assert_outputs(self, command._tests_to_update, [build])
 
 
+class TestRebaselineTest(unittest.TestCase):
+    def test_tests_to_update(self):
+        command = RebaselineTest()
+        command.bind_to_tool(MockTool())
+        build = Mock()
+        expected_stdout = "Retrieving http://build.chromium.org/f/chromium/layout_test_results/Webkit_Linux/results/layout-test-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()

Modified: trunk/Tools/Scripts/webkitpy/tool/mocktool.py (90769 => 90770)


--- trunk/Tools/Scripts/webkitpy/tool/mocktool.py	2011-07-11 18:48:34 UTC (rev 90769)
+++ trunk/Tools/Scripts/webkitpy/tool/mocktool.py	2011-07-11 18:51:13 UTC (rev 90770)
@@ -747,6 +747,11 @@
         return object()  # Something that is not None
 
 
+class MockWeb(object):
+    def get_binary(self, url):
+        return "MOCK Web result"
+
+
 class MockTool(object):
 
     def __init__(self, log_executive=False):
@@ -754,6 +759,7 @@
         self.bugs = MockBugzilla()
         self.buildbot = MockBuildBot()
         self.executive = MockExecutive(should_log=log_executive)
+        self.web = MockWeb()
         self.filesystem = MockFileSystem()
         self.workspace = MockWorkspace()
         self._irc = None
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to