[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da
eric at webkit.org
eric at webkit.org
Wed Dec 22 18:21:44 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit f1eeac35f30cad732a4a5a0da713ce566da0c13b
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Dec 10 06:45:42 2010 +0000
2010-12-09 Eric Seidel <eric at webkit.org>
Reviewed by Adam Barth.
Teach webkit-patch how to search bugzilla
https://bugs.webkit.org/show_bug.cgi?id=50500
This is a step towards teaching webkitpy how to file
new bugs for flaky tests and update them when new flakes occur.
* Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
* Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py:
* Scripts/webkitpy/tool/commands/__init__.py:
* Scripts/webkitpy/tool/commands/bugsearch.py: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73688 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index d56c62f..ba6df0f 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,18 @@
+2010-12-09 Eric Seidel <eric at webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Teach webkit-patch how to search bugzilla
+ https://bugs.webkit.org/show_bug.cgi?id=50500
+
+ This is a step towards teaching webkitpy how to file
+ new bugs for flaky tests and update them when new flakes occur.
+
+ * Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
+ * Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py:
+ * Scripts/webkitpy/tool/commands/__init__.py:
+ * Scripts/webkitpy/tool/commands/bugsearch.py: Added.
+
2010-12-09 Adam Barth <abarth at webkit.org>
Reviewed by Ojan Vafai.
diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
index 9fa7fe5..a0609c5 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
@@ -33,6 +33,7 @@
import os.path
import re
import StringIO
+import urllib
from datetime import datetime # used in timestamp()
@@ -72,15 +73,39 @@ class BugzillaQueries(object):
def __init__(self, bugzilla):
self._bugzilla = bugzilla
- # Note: _load_query and _fetch_bug are the only two methods which access
- # self._bugzilla.
+ def _is_xml_bugs_form(self, form):
+ # ClientForm.HTMLForm.find_control throws if the control is not found,
+ # so we do a manual search instead:
+ return "xml" in [control.id for control in form.controls]
+
+ # This is kinda a hack. There is probably a better way to get this information from bugzilla.
+ def _parse_result_count(self, results_page):
+ result_count_text = BeautifulSoup(results_page).find(attrs={'class': 'bz_result_count'}).string
+ result_count_parts = result_count_text.split(" ")
+ if result_count_parts[0] == "Zarro":
+ return 0
+ return int(result_count_parts[0])
+
+ # Note: _load_query, _fetch_bug and _fetch_bugs_from_advanced_query
+ # are the only methods which access self._bugzilla.
def _load_query(self, query):
self._bugzilla.authenticate()
-
full_url = "%s%s" % (self._bugzilla.bug_server_url, query)
return self._bugzilla.browser.open(full_url)
+ def _fetch_bugs_from_advanced_query(self, query):
+ results_page = self._load_query(query)
+ if not self._parse_result_count(results_page):
+ return []
+ # Bugzilla results pages have an "XML" submit button at the bottom
+ # which can be used to get an XML page containing all of the <bug> elements.
+ # This is slighty lame that this assumes that _load_query used
+ # self._bugzilla.browser and that it's in an acceptable state.
+ self._bugzilla.browser.select_form(predicate=self._is_xml_bugs_form)
+ bugs_xml = self._bugzilla.browser.submit()
+ return self._bugzilla._parse_bugs_from_xml(bugs_xml)
+
def _fetch_bug(self, bug_id):
return self._bugzilla.fetch_bug(bug_id)
@@ -114,6 +139,13 @@ class BugzillaQueries(object):
needs_commit_query_url = "buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=review%2B"
return self._fetch_bug_ids_advanced_query(needs_commit_query_url)
+ def fetch_bugs_matching_quicksearch(self, search_string):
+ # We may want to use a more explicit query than "quicksearch".
+ # If quicksearch changes we should probably change to use
+ # a normal buglist.cgi?query_format=advanced query.
+ quicksearch_url = "buglist.cgi?quicksearch=%s" % urllib.quote(search_string)
+ return self._fetch_bugs_from_advanced_query(quicksearch_url)
+
def fetch_patches_from_pending_commit_list(self):
return sum([self._fetch_bug(bug_id).reviewed_patches()
for bug_id in self.fetch_bug_ids_from_pending_commit_list()], [])
@@ -250,7 +282,13 @@ class Bugzilla(object):
element, 'commit-queue', attachment, 'committer_email')
return attachment
- def _parse_bug_page(self, page):
+ def _parse_bugs_from_xml(self, page):
+ soup = BeautifulSoup(page)
+ # Without the unicode() call, BeautifulSoup occasionally complains of being
+ # passed None for no apparent reason.
+ return [Bug(self._parse_bug_dictionary_from_xml(unicode(bug_xml)), self) for bug_xml in soup('bug')]
+
+ def _parse_bug_dictionary_from_xml(self, page):
soup = BeautifulSoup(page)
bug = {}
bug["id"] = int(soup.find("bug_id").string)
@@ -273,12 +311,12 @@ class Bugzilla(object):
def fetch_bug_dictionary(self, bug_id):
try:
- return self._parse_bug_page(self._fetch_bug_page(bug_id))
+ return self._parse_bug_dictionary_from_xml(self._fetch_bug_page(bug_id))
except KeyboardInterrupt:
raise
except:
self.authenticate()
- return self._parse_bug_page(self._fetch_bug_page(bug_id))
+ return self._parse_bug_dictionary_from_xml(self._fetch_bug_page(bug_id))
# FIXME: A BugzillaCache object should provide all these fetch_ methods.
diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py
index c476c81..9c03596 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py
@@ -99,14 +99,7 @@ class BugzillaTest(unittest.TestCase):
self.assertEquals(None, parse_bug_id("http://www.webkit.org/b/12345"))
self.assertEquals(None, parse_bug_id("http://bugs.webkit.org/show_bug.cgi?ctype=xml&id=12345"))
- _example_bug = """
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd">
-<bugzilla version="3.2.3"
- urlbase="https://bugs.webkit.org/"
- maintainer="admin at webkit.org"
- exporter="eric at webkit.org"
->
+ _bug_xml = """
<bug>
<bug_id>32585</bug_id>
<creation_ts>2009-12-15 15:17 PST</creation_ts>
@@ -149,13 +142,13 @@ Ignore this bug. Just for testing failure modes of webkit-patch and the commit-
<type>text/plain</type>
<size>10882</size>
<attacher>mjs at apple.com</attacher>
-
+
<token>1261988248-dc51409e9c421a4358f365fa8bec8357</token>
<data encoding="base64">SW5kZXg6IFdlYktpdC9tYWMvQ2hhbmdlTG9nCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
removed-because-it-was-really-long
ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
</data>
-
+
<flag name="review"
id="27602"
status="?"
@@ -163,8 +156,20 @@ ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
/>
</attachment>
</bug>
-</bugzilla>
"""
+
+ _single_bug_xml = """
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd">
+<bugzilla version="3.2.3"
+ urlbase="https://bugs.webkit.org/"
+ maintainer="admin at webkit.org"
+ exporter="eric at webkit.org"
+>
+%s
+</bugzilla>
+""" % _bug_xml
+
_expected_example_bug_parsing = {
"id" : 32585,
"title" : u"bug to test webkit-patch and commit-queue failures",
@@ -194,10 +199,25 @@ ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
for key, expected_value in expected.items():
self.assertEquals(actual[key], expected_value, ("Failure for key: %s: Actual='%s' Expected='%s'" % (key, actual[key], expected_value)))
- def test_bug_parsing(self):
- bug = Bugzilla()._parse_bug_page(self._example_bug)
+ def test_parse_bug_dictionary_from_xml(self):
+ bug = Bugzilla()._parse_bug_dictionary_from_xml(self._single_bug_xml)
self._assert_dictionaries_equal(bug, self._expected_example_bug_parsing)
+ _sample_multi_bug_xml = """
+<bugzilla version="3.2.3" urlbase="https://bugs.webkit.org/" maintainer="admin at webkit.org" exporter="eric at webkit.org">
+ %s
+ %s
+</bugzilla>
+""" % (_bug_xml, _bug_xml)
+
+ def test_parse_bugs_from_xml(self):
+ bugzilla = Bugzilla()
+ bugs = bugzilla._parse_bugs_from_xml(self._sample_multi_bug_xml)
+ self.assertEquals(len(bugs), 2)
+ self.assertEquals(bugs[0].id(), self._expected_example_bug_parsing['id'])
+ bugs = bugzilla._parse_bugs_from_xml("")
+ self.assertEquals(len(bugs), 0)
+
# This could be combined into test_bug_parsing later if desired.
def test_attachment_parsing(self):
bugzilla = Bugzilla()
@@ -328,6 +348,16 @@ class BugzillaQueriesTest(unittest.TestCase):
</html>
"""
+ def _assert_result_count(self, queries, html, count):
+ self.assertEquals(queries._parse_result_count(html), count)
+
+ def test_parse_result_count(self):
+ queries = BugzillaQueries(None)
+ # Pages with results, always list the count at least twice.
+ self._assert_result_count(queries, '<span class="bz_result_count">314 bugs found.</span><span class="bz_result_count">314 bugs found.</span>', 314)
+ self._assert_result_count(queries, '<span class="bz_result_count">Zarro Boogs found.</span>', 0)
+ self.assertRaises(Exception, queries._parse_result_count, ['Invalid'])
+
def test_request_page_parsing(self):
queries = BugzillaQueries(None)
self.assertEquals([40511, 40722, 40723], queries._parse_attachment_ids_request_query(self._sample_request_page))
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
index d2aa503..bae26bf 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
@@ -1,5 +1,6 @@
# Required for Python to search this directory for module files
+from webkitpy.tool.commands.bugsearch import BugSearch
from webkitpy.tool.commands.download import *
from webkitpy.tool.commands.earlywarningsystem import *
from webkitpy.tool.commands.openbugs import OpenBugs
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/bugsearch.py b/WebKitTools/Scripts/webkitpy/tool/commands/bugsearch.py
new file mode 100644
index 0000000..5cbc1a0
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/bugsearch.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2010 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.multicommandtool import AbstractDeclarativeCommand
+
+
+class BugSearch(AbstractDeclarativeCommand):
+ name = "bug-search"
+ help_text = "List bugs matching a query"
+
+ def execute(self, options, args, tool):
+ search_string = args[0]
+ bugs = tool.bugs.queries.fetch_bugs_matching_quicksearch(search_string)
+ for bug in bugs:
+ print "%5s %s" % (bug.id(), bug.title())
+ if not bugs:
+ print "No bugs found matching '%s'" % search_string
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list