Changeset 73688 in webkit


Ignore:
Timestamp:
Dec 9, 2010 10:45:42 PM (13 years ago)
Author:
eric@webkit.org
Message:

2010-12-09 Eric Seidel <eric@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.
Location:
trunk/WebKitTools
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r73682 r73688  
     12010-12-09  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        Teach webkit-patch how to search bugzilla
     6        https://bugs.webkit.org/show_bug.cgi?id=50500
     7
     8        This is a step towards teaching webkitpy how to file
     9        new bugs for flaky tests and update them when new flakes occur.
     10
     11        * Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
     12        * Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py:
     13        * Scripts/webkitpy/tool/commands/__init__.py:
     14        * Scripts/webkitpy/tool/commands/bugsearch.py: Added.
     15
    1162010-12-09  Adam Barth  <abarth@webkit.org>
    217
  • trunk/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py

    r71958 r73688  
    3434import re
    3535import StringIO
     36import urllib
    3637
    3738from datetime import datetime # used in timestamp()
     
    7374        self._bugzilla = bugzilla
    7475
    75     # Note: _load_query and _fetch_bug are the only two methods which access
    76     # self._bugzilla.
     76    def _is_xml_bugs_form(self, form):
     77        # ClientForm.HTMLForm.find_control throws if the control is not found,
     78        # so we do a manual search instead:
     79        return "xml" in [control.id for control in form.controls]
     80
     81    # This is kinda a hack.  There is probably a better way to get this information from bugzilla.
     82    def _parse_result_count(self, results_page):
     83        result_count_text = BeautifulSoup(results_page).find(attrs={'class': 'bz_result_count'}).string
     84        result_count_parts = result_count_text.split(" ")
     85        if result_count_parts[0] == "Zarro":
     86            return 0
     87        return int(result_count_parts[0])
     88
     89    # Note: _load_query, _fetch_bug and _fetch_bugs_from_advanced_query
     90    # are the only methods which access self._bugzilla.
    7791
    7892    def _load_query(self, query):
    7993        self._bugzilla.authenticate()
    80 
    8194        full_url = "%s%s" % (self._bugzilla.bug_server_url, query)
    8295        return self._bugzilla.browser.open(full_url)
     96
     97    def _fetch_bugs_from_advanced_query(self, query):
     98        results_page = self._load_query(query)
     99        if not self._parse_result_count(results_page):
     100            return []
     101        # Bugzilla results pages have an "XML" submit button at the bottom
     102        # which can be used to get an XML page containing all of the <bug> elements.
     103        # This is slighty lame that this assumes that _load_query used
     104        # self._bugzilla.browser and that it's in an acceptable state.
     105        self._bugzilla.browser.select_form(predicate=self._is_xml_bugs_form)
     106        bugs_xml = self._bugzilla.browser.submit()
     107        return self._bugzilla._parse_bugs_from_xml(bugs_xml)
    83108
    84109    def _fetch_bug(self, bug_id):
     
    114139        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"
    115140        return self._fetch_bug_ids_advanced_query(needs_commit_query_url)
     141
     142    def fetch_bugs_matching_quicksearch(self, search_string):
     143        # We may want to use a more explicit query than "quicksearch".
     144        # If quicksearch changes we should probably change to use
     145        # a normal buglist.cgi?query_format=advanced query.
     146        quicksearch_url = "buglist.cgi?quicksearch=%s" % urllib.quote(search_string)
     147        return self._fetch_bugs_from_advanced_query(quicksearch_url)
    116148
    117149    def fetch_patches_from_pending_commit_list(self):
     
    251283        return attachment
    252284
    253     def _parse_bug_page(self, page):
     285    def _parse_bugs_from_xml(self, page):
     286        soup = BeautifulSoup(page)
     287        # Without the unicode() call, BeautifulSoup occasionally complains of being
     288        # passed None for no apparent reason.
     289        return [Bug(self._parse_bug_dictionary_from_xml(unicode(bug_xml)), self) for bug_xml in soup('bug')]
     290
     291    def _parse_bug_dictionary_from_xml(self, page):
    254292        soup = BeautifulSoup(page)
    255293        bug = {}
     
    274312    def fetch_bug_dictionary(self, bug_id):
    275313        try:
    276             return self._parse_bug_page(self._fetch_bug_page(bug_id))
     314            return self._parse_bug_dictionary_from_xml(self._fetch_bug_page(bug_id))
    277315        except KeyboardInterrupt:
    278316            raise
    279317        except:
    280318            self.authenticate()
    281             return self._parse_bug_page(self._fetch_bug_page(bug_id))
     319            return self._parse_bug_dictionary_from_xml(self._fetch_bug_page(bug_id))
    282320
    283321    # FIXME: A BugzillaCache object should provide all these fetch_ methods.
  • trunk/WebKitTools/Scripts/webkitpy/common/net/bugzilla/bugzilla_unittest.py

    r71856 r73688  
    100100        self.assertEquals(None, parse_bug_id("http://bugs.webkit.org/show_bug.cgi?ctype=xml&id=12345"))
    101101
    102     _example_bug = """
    103 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    104 <!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd">
    105 <bugzilla version="3.2.3"
    106           urlbase="https://bugs.webkit.org/"
    107           maintainer="admin@webkit.org"
    108           exporter="eric@webkit.org"
    109 >
     102    _bug_xml = """
    110103    <bug>
    111104          <bug_id>32585</bug_id>
     
    150143            <size>10882</size>
    151144            <attacher>mjs@apple.com</attacher>
    152            
     145
    153146              <token>1261988248-dc51409e9c421a4358f365fa8bec8357</token>
    154147              <data encoding="base64">SW5kZXg6IFdlYktpdC9tYWMvQ2hhbmdlTG9nCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
     
    156149ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
    157150</data>       
    158  
     151
    159152            <flag name="review"
    160153                id="27602"
     
    164157        </attachment>
    165158    </bug>
     159"""
     160
     161    _single_bug_xml = """
     162<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
     163<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd">
     164<bugzilla version="3.2.3"
     165          urlbase="https://bugs.webkit.org/"
     166          maintainer="admin@webkit.org"
     167          exporter="eric@webkit.org"
     168>
     169%s
    166170</bugzilla>
    167 """
     171""" % _bug_xml
     172
    168173    _expected_example_bug_parsing = {
    169174        "id" : 32585,
     
    195200            self.assertEquals(actual[key], expected_value, ("Failure for key: %s: Actual='%s' Expected='%s'" % (key, actual[key], expected_value)))
    196201
    197     def test_bug_parsing(self):
    198         bug = Bugzilla()._parse_bug_page(self._example_bug)
     202    def test_parse_bug_dictionary_from_xml(self):
     203        bug = Bugzilla()._parse_bug_dictionary_from_xml(self._single_bug_xml)
    199204        self._assert_dictionaries_equal(bug, self._expected_example_bug_parsing)
     205
     206    _sample_multi_bug_xml = """
     207<bugzilla version="3.2.3" urlbase="https://bugs.webkit.org/" maintainer="admin@webkit.org" exporter="eric@webkit.org">
     208    %s
     209    %s
     210</bugzilla>
     211""" % (_bug_xml, _bug_xml)
     212
     213    def test_parse_bugs_from_xml(self):
     214        bugzilla = Bugzilla()
     215        bugs = bugzilla._parse_bugs_from_xml(self._sample_multi_bug_xml)
     216        self.assertEquals(len(bugs), 2)
     217        self.assertEquals(bugs[0].id(), self._expected_example_bug_parsing['id'])
     218        bugs = bugzilla._parse_bugs_from_xml("")
     219        self.assertEquals(len(bugs), 0)
    200220
    201221    # This could be combined into test_bug_parsing later if desired.
     
    329349"""
    330350
     351    def _assert_result_count(self, queries, html, count):
     352        self.assertEquals(queries._parse_result_count(html), count)
     353
     354    def test_parse_result_count(self):
     355        queries = BugzillaQueries(None)
     356        # Pages with results, always list the count at least twice.
     357        self._assert_result_count(queries, '<span class="bz_result_count">314 bugs found.</span><span class="bz_result_count">314 bugs found.</span>', 314)
     358        self._assert_result_count(queries, '<span class="bz_result_count">Zarro Boogs found.</span>', 0)
     359        self.assertRaises(Exception, queries._parse_result_count, ['Invalid'])
     360
    331361    def test_request_page_parsing(self):
    332362        queries = BugzillaQueries(None)
  • trunk/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py

    r71667 r73688  
    11# Required for Python to search this directory for module files
    22
     3from webkitpy.tool.commands.bugsearch import BugSearch
    34from webkitpy.tool.commands.download import *
    45from webkitpy.tool.commands.earlywarningsystem import *
Note: See TracChangeset for help on using the changeset viewer.