[webkit-patch] Add new chrome-channels command to track down current chrome release...
authorgavinp@chromium.org <gavinp@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 May 2012 13:37:25 +0000 (13:37 +0000)
committergavinp@chromium.org <gavinp@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 May 2012 13:37:25 +0000 (13:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85368

Reviewed by Eric Seidel.

* Scripts/webkitpy/common/config/urls.py:
* Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py:
(MockBugzillaQueries.fetch_bugs_matching_quicksearch):
* Scripts/webkitpy/common/net/omahaproxy.py: Added.
(OmahaProxy):
(OmahaProxy.__init__):
(OmahaProxy.set_url):
(OmahaProxy._json_url):
(OmahaProxy._get_json):
(OmahaProxy.get_revisions):
* Scripts/webkitpy/common/net/omahaproxy_unittest.py: Added.
(MockOmahaProxy):
(MockOmahaProxy.__init__):
(OmahaProxyTest):
(OmahaProxyTest.test_get_revisions):
* Scripts/webkitpy/tool/commands/__init__.py:
* Scripts/webkitpy/tool/commands/bugsearch.py:
(BugSearch):
* Scripts/webkitpy/tool/commands/chromechannels.py: Added.
(ChromeChannels):
(__init__):
(execute):
* Scripts/webkitpy/tool/commands/chromechannels_unittest.py: Added.
(MockOmahaProxy):
(MockOmahaProxy.get_revisions):
(TestableChromeChannels):
(TestableChromeChannels.__init__):
(ChromeChannelsTest):
(ChromeChannelsTest.test_single_bug):
(ChromeChannelsTest.test_with_query):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@116414 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/webkitpy/common/config/urls.py
Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py
Tools/Scripts/webkitpy/common/net/omahaproxy.py [new file with mode: 0644]
Tools/Scripts/webkitpy/common/net/omahaproxy_unittest.py [new file with mode: 0644]
Tools/Scripts/webkitpy/tool/commands/__init__.py
Tools/Scripts/webkitpy/tool/commands/bugsearch.py
Tools/Scripts/webkitpy/tool/commands/chromechannels.py [new file with mode: 0644]
Tools/Scripts/webkitpy/tool/commands/chromechannels_unittest.py [new file with mode: 0644]

index 02dabd4..effe653 100644 (file)
@@ -1,3 +1,41 @@
+2012-05-08  Gavin Peters  <gavinp@chromium.org>
+
+        [webkit-patch] Add new chrome-channels command to track down current chrome release channels for a committed bug.
+        https://bugs.webkit.org/show_bug.cgi?id=85368
+
+        Reviewed by Eric Seidel.
+
+        * Scripts/webkitpy/common/config/urls.py:
+        * Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py:
+        (MockBugzillaQueries.fetch_bugs_matching_quicksearch):
+        * Scripts/webkitpy/common/net/omahaproxy.py: Added.
+        (OmahaProxy):
+        (OmahaProxy.__init__):
+        (OmahaProxy.set_url):
+        (OmahaProxy._json_url):
+        (OmahaProxy._get_json):
+        (OmahaProxy.get_revisions):
+        * Scripts/webkitpy/common/net/omahaproxy_unittest.py: Added.
+        (MockOmahaProxy):
+        (MockOmahaProxy.__init__):
+        (OmahaProxyTest):
+        (OmahaProxyTest.test_get_revisions):
+        * Scripts/webkitpy/tool/commands/__init__.py:
+        * Scripts/webkitpy/tool/commands/bugsearch.py:
+        (BugSearch):
+        * Scripts/webkitpy/tool/commands/chromechannels.py: Added.
+        (ChromeChannels):
+        (__init__):
+        (execute):
+        * Scripts/webkitpy/tool/commands/chromechannels_unittest.py: Added.
+        (MockOmahaProxy):
+        (MockOmahaProxy.get_revisions):
+        (TestableChromeChannels):
+        (TestableChromeChannels.__init__):
+        (ChromeChannelsTest):
+        (ChromeChannelsTest.test_single_bug):
+        (ChromeChannelsTest.test_with_query):
+
 2012-05-08  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Unreviewed. Fix GTK+ unit tests.
index b547045..48830c5 100644 (file)
@@ -56,6 +56,7 @@ direct_attachment_url = r"https?://bug-(?P<bug_id>\d+)-attachments.%s/attachment
 buildbot_url = "http://build.webkit.org"
 chromium_buildbot_url = "http://build.chromium.org/p/chromium.webkit"
 
+omahaproxy_url = "http://omahaproxy.appspot.com/"
 
 def parse_bug_id(string):
     if not string:
index 47f867e..3de75fa 100644 (file)
@@ -169,9 +169,9 @@ _bug2 = {
     "bug_status": "ASSIGNED",
     "comments": [{"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
                   "comment_email": "bar@foo.com",
-                  "text": "Message1.",
-        },
-    ],
+                  "text": "Message1.\nCommitted r35: <http://trac.webkit.org/changeset/35>",
+                  },
+                 ],
 }
 
 
@@ -183,7 +183,15 @@ _bug3 = {
     "cc_emails": [],
     "attachments": [_patch7],
     "bug_status": "NEW",
-    "comments": [],
+    "comments":  [{"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
+                   "comment_email": "bar@foo.com",
+                   "text": "Committed r30: <http://trac.webkit.org/changeset/30>",
+                   },
+                  {"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
+                   "comment_email": "bar@foo.com",
+                   "text": "Committed r31: <http://trac.webkit.org/changeset/31>",
+                   },
+                  ],
 }
 
 
@@ -195,7 +203,15 @@ _bug4 = {
     "cc_emails": [],
     "attachments": [_patch4, _patch5, _patch6],
     "bug_status": "REOPENED",
-    "comments": [],
+    "comments": [{"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
+                  "comment_email": "bar@foo.com",
+                  "text": "Committed r25: <http://trac.webkit.org/changeset/30>",
+                  },
+                 {"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
+                  "comment_email": "bar@foo.com",
+                  "text": "Rolled out in <http://trac.webkit.org/changeset/26",
+                  },
+                 ],
 }
 
 
@@ -208,7 +224,12 @@ _bug5 = {
     "attachments": [],
     "bug_status": "RESOLVED",
     "dup_id": 50002,
-    "comments": [],
+    "comments": [{"comment_date":  datetime.datetime(2011, 6, 11, 9, 4, 3),
+                  "comment_email": "bar@foo.com",
+                  "text": "Committed r15: <http://trac.webkit.org/changeset/15>",
+                  },
+                 ],
+
 }
 
 
@@ -251,6 +272,10 @@ class MockBugzillaQueries(object):
     def fetch_bugs_matching_search(self, search_string, author_email=None):
         return [self._bugzilla.fetch_bug(50004), self._bugzilla.fetch_bug(50003)]
 
+    def fetch_bugs_matching_quicksearch(self, search_string):
+        return [self._bugzilla.fetch_bug(50001), self._bugzilla.fetch_bug(50002),
+                self._bugzilla.fetch_bug(50003), self._bugzilla.fetch_bug(50004)]
+
 
 _mock_reviewers = [Reviewer("Foo Bar", "foo@bar.com"),
                    Reviewer("Reviewer2", "reviewer2@webkit.org")]
diff --git a/Tools/Scripts/webkitpy/common/net/omahaproxy.py b/Tools/Scripts/webkitpy/common/net/omahaproxy.py
new file mode 100644 (file)
index 0000000..796923a
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright (C) 2012 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.
+#
+# This is the client to query http://omahaproxy.appspot.com/ to retrieve
+# chrome versions associated with WebKit commits.
+
+from webkitpy.common.net.networktransaction import NetworkTransaction
+from webkitpy.common.config import urls
+
+import json
+import urllib2
+
+
+class OmahaProxy(object):
+    default_url = urls.omahaproxy_url
+
+    chrome_platforms = {"linux": "Linux",
+                        "win": "Windows",
+                        "mac": "Mac",
+                        "cros": "Chrome OS",
+                        "cf": "Chrome Frame"}
+    chrome_channels = ["canary", "dev", "beta", "stable"]
+
+    def __init__(self, url=default_url, browser=None):
+        self._chrome_channels = set(self.chrome_channels)
+        self.set_url(url)
+        from webkitpy.thirdparty.autoinstalled.mechanize import Browser
+        self._browser = browser or Browser()
+
+    def set_url(self, url):
+        self.url = url
+
+    def _json_url(self):
+        return "%s/all.json" % self.url
+
+    def _get_json(self):
+        return NetworkTransaction().run(lambda: urllib2.urlopen(self._json_url()).read())
+
+    def get_revisions(self):
+        revisions_json = json.loads(self._get_json())
+        revisions = []
+        for platform in revisions_json:
+            for version in platform["versions"]:
+                try:
+                    row = {
+                        "commit": int(version["base_webkit_revision"]),
+                        "channel": version["channel"],
+                        "platform": self.chrome_platforms[platform["os"]],
+                        "date": version["date"],
+                    }
+                    assert(version["channel"] in self._chrome_channels)
+                    revisions.append(row)
+                except ValueError:
+                    next
+        return revisions
diff --git a/Tools/Scripts/webkitpy/common/net/omahaproxy_unittest.py b/Tools/Scripts/webkitpy/common/net/omahaproxy_unittest.py
new file mode 100644 (file)
index 0000000..42735c1
--- /dev/null
@@ -0,0 +1,125 @@
+# Copyright (C) 2012 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.
+#
+
+# Unit test for omahaproxy.py
+
+import unittest
+
+from webkitpy.common.net.omahaproxy import OmahaProxy
+
+
+class MockOmahaProxy(OmahaProxy):
+    def __init__(self, json):
+        self._get_json = lambda: json
+        OmahaProxy.__init__(self)
+
+
+class OmahaProxyTest(unittest.TestCase):
+    example_omahaproxy_json = """[
+        {"os": "win",
+         "versions": [
+                {"base_webkit_revision": "116185",
+                 "v8_ver": "3.10.8.1",
+                 "wk_ver": "536.11",
+                 "base_trunk_revision": 135598,
+                 "prev_version": "20.0.1128.0",
+                 "version": "20.0.1129.0",
+                 "date": "05\/07\/12",
+                 "prev_date": "05\/06\/12",
+                 "true_branch": "trunk",
+                 "channel": "canary",
+                 "branch_revision": "NA"},
+                {"base_webkit_revision": "115687",
+                 "v8_ver": "3.10.6.0",
+                 "wk_ver": "536.10",
+                 "base_trunk_revision": 134666,
+                 "prev_version": "20.0.1123.1",
+                 "version": "20.0.1123.4",
+                 "date": "05\/04\/12",
+                 "prev_date": "05\/02\/12",
+                 "true_branch": "1123",
+                 "channel": "dev",
+                 "branch_revision": 135092}]},
+        {"os": "linux",
+         "versions": [
+                {"base_webkit_revision": "115688",
+                 "v8_ver": "3.10.6.0",
+                 "wk_ver": "536.10",
+                 "base_trunk_revision": 134666,
+                 "prev_version": "20.0.1123.2",
+                 "version": "20.0.1123.4",
+                 "date": "05\/04\/12",
+                 "prev_date": "05\/02\/12",
+                 "true_branch": "1123",
+                 "channel": "dev",
+                 "branch_revision": 135092},
+                {"base_webkit_revision": "112327",
+                 "v8_ver": "3.9.24.17",
+                 "wk_ver": "536.5",
+                 "base_trunk_revision": 129376,
+                 "prev_version": "19.0.1084.36",
+                 "version": "19.0.1084.41",
+                 "date": "05\/03\/12",
+                 "prev_date": "04\/25\/12",
+                 "true_branch": "1084",
+                 "channel": "beta",
+                 "branch_revision": 134854},
+                {"base_webkit_revision": "*",
+                 "v8_ver": "3.9.24.17",
+                 "wk_ver": "536.5",
+                 "base_trunk_revision": 129376,
+                 "prev_version": "19.0.1084.36",
+                 "version": "19.0.1084.41",
+                 "date": "05\/03\/12",
+                 "prev_date": "04\/25\/12",
+                 "true_branch": "1084",
+                 "channel": "release",
+                 "branch_revision": 134854}]}]"""
+
+    expected_revisions = [
+        {"commit": 116185, "channel": "canary", "platform": "Windows", "date": "05/07/12"},
+        {"commit": 115687, "channel": "dev", "platform": "Windows", "date": "05/04/12"},
+        {"commit": 115688, "channel": "dev", "platform": "Linux", "date": "05/04/12"},
+        {"commit": 112327, "channel": "beta", "platform": "Linux", "date": "05/03/12"},
+    ]
+
+    def test_get_revisions(self):
+        omahaproxy = MockOmahaProxy(self.example_omahaproxy_json)
+        revisions = omahaproxy.get_revisions()
+        self.assertEqual(len(revisions), 4)
+        for revision in revisions:
+            self.assertTrue("commit" in revision)
+            self.assertTrue("channel" in revision)
+            self.assertTrue("platform" in revision)
+            self.assertTrue("date" in revision)
+            self.assertEqual(len(revision.keys()), 4)
+        self.assertEqual(revisions, self.expected_revisions)
+
+if __name__ == '__main__':
+    unittest.main()
index ef05b5a..e0d885f 100644 (file)
@@ -5,6 +5,7 @@ from webkitpy.tool.commands.analyzechangelog import AnalyzeChangeLog
 from webkitpy.tool.commands.applywatchlistlocal import ApplyWatchListLocal
 from webkitpy.tool.commands.bugfortest import BugForTest
 from webkitpy.tool.commands.bugsearch import BugSearch
+from webkitpy.tool.commands.chromechannels import ChromeChannels
 from webkitpy.tool.commands.download import *
 from webkitpy.tool.commands.earlywarningsystem import *
 from webkitpy.tool.commands.expectations import OptimizeExpectations
index 5cbc1a0..a1d74c5 100644 (file)
@@ -32,6 +32,13 @@ from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
 class BugSearch(AbstractDeclarativeCommand):
     name = "bug-search"
     help_text = "List bugs matching a query"
+    argument_names = "QUERY"
+    long_help = \
+"""Runs the bugzilla quicksearch QUERY on bugs.webkit.org, and lists all bugs
+returned. QUERY can be as simple as a bug number or a comma delimited list of
+bug numbers.
+See https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html for full
+documentation on the query format."""
 
     def execute(self, options, args, tool):
         search_string = args[0]
diff --git a/Tools/Scripts/webkitpy/tool/commands/chromechannels.py b/Tools/Scripts/webkitpy/tool/commands/chromechannels.py
new file mode 100644 (file)
index 0000000..da093b4
--- /dev/null
@@ -0,0 +1,104 @@
+# Copyright (c) 2012 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.
+
+from optparse import make_option
+
+from webkitpy.common.net.omahaproxy import OmahaProxy
+from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
+
+import re
+
+
+class ChromeChannels(AbstractDeclarativeCommand):
+    name = "chrome-channels"
+    help_text = "List which chrome channels include the patches in bugs returned by QUERY."
+    argument_names = "QUERY"
+    long_help = """Retrieves the current list of Chrome releases from omahaproxy.appspot.com,
+and then runs the bugzilla quicksearch QUERY on bugs.bugzilla.org. For each bug
+returned by query, a single svn commit is deduced, and a short summary is
+printed of each bug listing which Chrome channels contain each bugs associated
+commit.
+
+The QUERY can be as simple as a bug number, or a comma delimited list of bug
+numbers. See https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html for full
+documentation on the query format."""
+
+    chrome_channels = OmahaProxy.chrome_channels
+    commited_pattern = "Committed r([0-9]+): <http://trac.webkit.org/changeset/\\1>"
+    rollout_pattern = "Rolled out in http://trac.webkit.org/changeset/[0-9]+"
+
+    def __init__(self):
+        AbstractDeclarativeCommand.__init__(self)
+        self._re_committed = re.compile(self.commited_pattern)
+        self._re_rollout = re.compile(self.rollout_pattern)
+        self._omahaproxy = OmahaProxy()
+
+    def _channels_for_bug(self, revisions, bug):
+        comments = bug.comments()
+        commit = None
+
+        # Scan the comments, looking for a sane list of commits and rollbacks.
+        for comment in comments:
+            commit_match = self._re_committed.search(comment['text'])
+            if commit_match:
+                if commit:
+                    return "%5s %s\n... has too confusing a commit history to parse, skipping\n" % (bug.id(), bug.title())
+                commit = int(commit_match.group(1))
+            if self._re_rollout.search(comment['text']):
+                commit = None
+        if not commit:
+            return "%5s %s\n... does not appear to have an associated commit.\n" % (bug.id(), bug.title())
+
+        # We now know that we have a commit, so gather up the list of platforms
+        # by channel, then print.
+        by_channel = {}
+        for revision in revisions:
+            channel = revision['channel']
+            if revision['commit'] < commit:
+                continue
+            if not channel in by_channel:
+                by_channel[revision['channel']] = " %6s:" % channel
+            by_channel[channel] += " %s," % revision['platform']
+        if not by_channel:
+            return "%5s %s (r%d)\n... not yet released in any Chrome channels.\n" % (bug.id(), bug.title(), commit)
+        retval = "%5s %s (r%d)\n" % (bug.id(), bug.title(), commit)
+        for channel in self.chrome_channels:
+            if channel in by_channel:
+                retval += by_channel[channel][:-1]
+                retval += "\n"
+        return retval
+
+    def execute(self, options, args, tool):
+        search_string = args[0]
+        revisions = self._omahaproxy.get_revisions()
+        bugs = tool.bugs.queries.fetch_bugs_matching_quicksearch(search_string)
+        if not bugs:
+            print "No bugs found matching '%s'" % search_string
+            return
+        for bug in bugs:
+            print self._channels_for_bug(revisions, bug),
diff --git a/Tools/Scripts/webkitpy/tool/commands/chromechannels_unittest.py b/Tools/Scripts/webkitpy/tool/commands/chromechannels_unittest.py
new file mode 100644 (file)
index 0000000..037aebb
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright (c) 2012 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.
+
+from webkitpy.tool.commands.chromechannels import ChromeChannels
+from webkitpy.tool.commands.commandtest import CommandsTest
+from webkitpy.tool.mocktool import MockTool
+from webkitpy.common.net.omahaproxy import OmahaProxy
+
+
+class MockOmahaProxy(OmahaProxy):
+    revisions = [{"commit": 20, "channel": "canary", "platform": "Mac", "date": "07/04/76"},
+                 {"commit": 20, "channel": "canary", "platform": "Windows", "date": "07/04/76"},
+                 {"commit": 25, "channel": "dev", "platform": "Mac", "date": "07/01/76"},
+                 {"commit": 30, "channel": "dev", "platform": "Windows", "date": "03/29/82"},
+                 {"commit": 30, "channel": "dev", "platform": "Linux", "date": "03/29/82"},
+                 {"commit": 15, "channel": "beta", "platform": "Windows", "date": "07/04/67"},
+                 {"commit": 15, "channel": "beta", "platform": "Linux", "date": "07/04/67"},
+                 {"commit": 10, "channel": "stable", "platform": "Windows", "date": "07/01/67"},
+                 {"commit": 20, "channel": "stable", "platform": "Linux", "date": "09/16/10"},
+                 ]
+
+    def get_revisions(self):
+        return self.revisions
+
+
+class TestableChromeChannels(ChromeChannels):
+    def __init__(self):
+        ChromeChannels.__init__(self)
+        self._omahaproxy = MockOmahaProxy()
+
+
+class ChromeChannelsTest(CommandsTest):
+
+    single_bug_expectations = {
+        50001: """50001 Bug with a patch needing review. (r35)
+... not yet released in any Chrome channels.
+""",
+        50002: """50002 The third bug
+... has too confusing a commit history to parse, skipping
+""",
+        50003: """50003 The fourth bug
+... does not appear to have an associated commit.
+""",
+        50004: """50004 The fifth bug (r15)
+ canary: Mac, Windows
+    dev: Mac, Windows, Linux
+   beta: Windows, Linux
+ stable: Linux
+"""}
+
+    def test_single_bug(self):
+        testable_chrome_channels = TestableChromeChannels()
+        tool = MockTool()
+        testable_chrome_channels.bind_to_tool(tool)
+        revisions = testable_chrome_channels._omahaproxy.get_revisions()
+        for bug_id, expectation in self.single_bug_expectations.items():
+            self.assertEqual(testable_chrome_channels._channels_for_bug(revisions, testable_chrome_channels._tool.bugs.fetch_bug(bug_id)),
+                             expectation)
+
+    def test_with_query(self):
+        expected_stdout = \
+"""50001 Bug with a patch needing review. (r35)
+... not yet released in any Chrome channels.
+50002 The third bug
+... has too confusing a commit history to parse, skipping
+50003 The fourth bug
+... does not appear to have an associated commit.
+50004 The fifth bug (r15)
+ canary: Mac, Windows
+    dev: Mac, Windows, Linux
+   beta: Windows, Linux
+ stable: Linux
+"""
+        self.assert_execute_outputs(TestableChromeChannels(), ["foo"], expected_stdout=expected_stdout)