Reviewed by Eric Seidel.
StyleQueue scans ~100 bug pages every 5 minutes
https://bugs.webkit.org/show_bug.cgi?id=31947
Instead of getting the pending-review attachment ids by scanning each
bug (which results in a network request), we should just get them all
from webkit.org/pending-review in one shot.
* Scripts/modules/bugzilla.py:
* Scripts/modules/bugzilla_unittest.py:
* Scripts/modules/commands/queries.py:
* Scripts/modules/commands/queries_unittest.py:
* Scripts/modules/commands/queues.py:
* Scripts/modules/mock_bugzillatool.py:
* Scripts/modules/patchcollection.py:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51464
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2009-11-28 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ StyleQueue scans ~100 bug pages every 5 minutes
+ https://bugs.webkit.org/show_bug.cgi?id=31947
+
+ Instead of getting the pending-review attachment ids by scanning each
+ bug (which results in a network request), we should just get them all
+ from webkit.org/pending-review in one shot.
+
+ * Scripts/modules/bugzilla.py:
+ * Scripts/modules/bugzilla_unittest.py:
+ * Scripts/modules/commands/queries.py:
+ * Scripts/modules/commands/queries_unittest.py:
+ * Scripts/modules/commands/queues.py:
+ * Scripts/modules/mock_bugzillatool.py:
+ * Scripts/modules/patchcollection.py:
+
2009-11-28 Adam Barth <abarth@webkit.org>
Reviewed by Eric Seidel.
# WebKit includes a built copy of BeautifulSoup in Scripts/modules
# so this import should always succeed.
-from .BeautifulSoup import BeautifulSoup
+from .BeautifulSoup import BeautifulSoup, SoupStrainer
try:
from mechanize import Browser
return bug_ids
+ def _parse_attachment_ids_request_query(self, page):
+ digits = re.compile("\d+")
+ attachment_href = re.compile("attachment.cgi\?id=\d+&action=review")
+ attachment_links = SoupStrainer("a", href=attachment_href)
+ return [digits.search(tag["href"]).group(0) for tag in BeautifulSoup(page, parseOnlyThese=attachment_links)]
+
+ def _fetch_attachment_ids_request_query(self, query):
+ return self._parse_attachment_ids_request_query(urllib2.urlopen(query))
+
def fetch_bug_ids_from_commit_queue(self):
commit_queue_url = self.bug_server_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=commit-queue%2B"
return self._fetch_bug_ids_advanced_query(commit_queue_url)
review_queue_url = self.bug_server_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?"
return self._fetch_bug_ids_advanced_query(review_queue_url)
+ def fetch_attachment_ids_from_review_queue(self):
+ review_queue_url = self.bug_server_url + "request.cgi?action=queue&type=review&group=type"
+ return self._fetch_attachment_ids_request_query(review_queue_url)
+
def fetch_patches_from_commit_queue(self, reject_invalid_patches=False):
patches_to_land = []
for bug_id in self.fetch_bug_ids_from_commit_queue():
bugzilla = Bugzilla()
self.assertEquals(27314, bugzilla._parse_bug_id_from_attachment_page(self._sample_attachment_detail_page))
+ _sample_request_page = """
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <title>Request Queue</title>
+ </head>
+<body>
+
+<h3>Flag: review</h3>
+ <table class="requests" cellspacing="0" cellpadding="4" border="1">
+ <tr>
+ <th>Requester</th>
+ <th>Requestee</th>
+ <th>Bug</th>
+ <th>Attachment</th>
+ <th>Created</th>
+ </tr>
+ <tr>
+ <td>Shinichiro Hamaji <hamaji@chromium.org></td>
+ <td></td>
+ <td><a href="show_bug.cgi?id=30015">30015: text-transform:capitalize is failing in CSS2.1 test suite</a></td>
+ <td><a href="attachment.cgi?id=40511&action=review">
+40511: Patch v0</a></td>
+ <td>2009-10-02 04:58 PST</td>
+ </tr>
+ <tr>
+ <td>Zan Dobersek <zandobersek@gmail.com></td>
+ <td></td>
+ <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playing html5 video.</a></td>
+ <td><a href="attachment.cgi?id=40722&action=review">
+40722: Media controls, the simple approach</a></td>
+ <td>2009-10-06 09:13 PST</td>
+ </tr>
+ <tr>
+ <td>Zan Dobersek <zandobersek@gmail.com></td>
+ <td></td>
+ <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playing html5 video.</a></td>
+ <td><a href="attachment.cgi?id=40723&action=review">
+40723: Adjust the media slider thumb size</a></td>
+ <td>2009-10-06 09:15 PST</td>
+ </tr>
+ </table>
+</body>
+</html>
+"""
+
+ def test_request_page_parsing(self):
+ bugzilla = Bugzilla()
+ self.assertEquals([40511, 40722, 40723], bugzilla._parse_attachment_ids_request_query(self._sample_request_page))
+
if __name__ == '__main__':
unittest.main()
print "%s" % patch["url"]
+class PatchesToReview(Command):
+ name = "patches-to-review"
+ show_in_main_help = False
+ def __init__(self):
+ Command.__init__(self, "List patches that are pending review")
+
+ def execute(self, options, args, tool):
+ patch_ids = tool.bugs.fetch_attachment_ids_from_review_queue()
+ log("Patches pending review:")
+ for patch_id in patch_ids:
+ print patch_id
+
+
class ReviewedPatches(Command):
name = "reviewed-patches"
show_in_main_help = False
expected_stderr = "Patches in commit queue:\n"
self.assert_execute_outputs(PatchesToCommit(), None, expected_stdout, expected_stderr)
+ def test_patches_to_review(self):
+ expected_stdout = "197\n128\n"
+ expected_stderr = "Patches pending review:\n"
+ self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr)
+
def test_reviewed_patches(self):
expected_stdout = "http://example.com/197\nhttp://example.com/128\n"
self.assert_execute_outputs(ReviewedPatches(), [42], expected_stdout)
def collection_name(self):
return self.name
- def fetch_potential_patches(self):
- return self.tool.bugs.fetch_patches_from_review_queue(limit=3)
+ def fetch_potential_patch_ids(self):
+ return self.tool.bugs.fetch_attachment_ids_from_review_queue()
def status_server(self):
return self.tool.status()
self._patches = PersistentPatchCollection(self)
def next_work_item(self):
- return self._patches.next()
+ patch_id = self._patches.next()
+ if patch_id:
+ return self.tool.bugs.fetch_attachment(patch_id)
def should_proceed_with_work_item(self, patch):
raise NotImplementedError, "subclasses must implement"
def fetch_bug_ids_from_commit_queue(self):
return [42, 75]
+ def fetch_attachment_ids_from_review_queue(self):
+ return [197, 128]
+
def fetch_patches_from_commit_queue(self):
return [self.patch1, self.patch2]
def collection_name(self):
raise NotImplementedError, "subclasses must implement"
- def fetch_potential_patches(self):
+ def fetch_potential_patch_ids(self):
raise NotImplementedError, "subclasses must implement"
def status_server(self):
self._status = self._delegate.status_server()
def next(self):
- patches = self._delegate.fetch_potential_patches()
- for patch in patches:
- last_status = self._status.patch_status(self._name, patch["id"])
+ patch_ids = self._delegate.fetch_potential_patch_ids()
+ for patch_id in patch_ids:
+ last_status = self._status.patch_status(self._name, patch_id)
if not last_status: # FIXME: Add support for "Try again"
- self._status.update_status(self._name, self._initial_status, patch)
- return patch
+ return patch_id
def done(self, patch):
self._status.update_status(self._name, self._terminal_status, patch)