WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 # Copyright (C) 2009 Google Inc. All rights reserved.
       
     2 #
       
     3 # Redistribution and use in source and binary forms, with or without
       
     4 # modification, are permitted provided that the following conditions are
       
     5 # met:
       
     6 #
       
     7 #    * Redistributions of source code must retain the above copyright
       
     8 # notice, this list of conditions and the following disclaimer.
       
     9 #    * Redistributions in binary form must reproduce the above
       
    10 # copyright notice, this list of conditions and the following disclaimer
       
    11 # in the documentation and/or other materials provided with the
       
    12 # distribution.
       
    13 #    * Neither the name of Google Inc. nor the names of its
       
    14 # contributors may be used to endorse or promote products derived from
       
    15 # this software without specific prior written permission.
       
    16 #
       
    17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    28 
       
    29 import unittest
       
    30 
       
    31 import datetime
       
    32 
       
    33 from webkitpy.common.config.committers import CommitterList, Reviewer, Committer
       
    34 from webkitpy.common.net.bugzilla import Bugzilla, BugzillaQueries, parse_bug_id, CommitterValidator, Bug
       
    35 from webkitpy.common.system.outputcapture import OutputCapture
       
    36 from webkitpy.thirdparty.mock import Mock
       
    37 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup
       
    38 
       
    39 
       
    40 class MockBrowser(object):
       
    41     def open(self, url):
       
    42         pass
       
    43 
       
    44     def select_form(self, name):
       
    45         pass
       
    46 
       
    47     def __setitem__(self, key, value):
       
    48         pass
       
    49 
       
    50     def submit(self):
       
    51         pass
       
    52 
       
    53 
       
    54 class BugTest(unittest.TestCase):
       
    55     def test_is_unassigned(self):
       
    56         for email in Bug.unassigned_emails:
       
    57             bug = Bug({"assigned_to_email" : email}, bugzilla=None)
       
    58             self.assertTrue(bug.is_unassigned())
       
    59         bug = Bug({"assigned_to_email" : "test@test.com"}, bugzilla=None)
       
    60         self.assertFalse(bug.is_unassigned())
       
    61 
       
    62 
       
    63 class CommitterValidatorTest(unittest.TestCase):
       
    64     def test_flag_permission_rejection_message(self):
       
    65         validator = CommitterValidator(bugzilla=None)
       
    66         self.assertEqual(validator._committers_py_path(), "WebKitTools/Scripts/webkitpy/common/config/committers.py")
       
    67         expected_messsage="""foo@foo.com does not have review permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
       
    68 
       
    69 - If you do not have review rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
       
    70 
       
    71 - If you have review rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed).  Due to bug 30084 the commit-queue will require a restart after your change.  Please contact eseidel@chromium.org to request a commit-queue restart.  After restart the commit-queue will correctly respect your review rights."""
       
    72         self.assertEqual(validator._flag_permission_rejection_message("foo@foo.com", "review"), expected_messsage)
       
    73 
       
    74 
       
    75 class BugzillaTest(unittest.TestCase):
       
    76     _example_attachment = '''
       
    77         <attachment
       
    78           isobsolete="1"
       
    79           ispatch="1"
       
    80           isprivate="0"
       
    81         >
       
    82         <attachid>33721</attachid>
       
    83         <date>2009-07-29 10:23 PDT</date>
       
    84         <desc>Fixed whitespace issue</desc>
       
    85         <filename>patch</filename>
       
    86         <type>text/plain</type>
       
    87         <size>9719</size>
       
    88         <attacher>christian.plesner.hansen@gmail.com</attacher>
       
    89           <flag name="review"
       
    90                 id="17931"
       
    91                 status="+"
       
    92                 setter="one@test.com"
       
    93            />
       
    94           <flag name="commit-queue"
       
    95                 id="17932"
       
    96                 status="+"
       
    97                 setter="two@test.com"
       
    98            />
       
    99           <flag name="in-rietveld"
       
   100                 id="17933"
       
   101                 status="+"
       
   102                 setter="three@test.com"
       
   103            />
       
   104         </attachment>
       
   105 '''
       
   106     _expected_example_attachment_parsing = {
       
   107         'attach_date': datetime.datetime(2009, 07, 29, 10, 23),
       
   108         'bug_id' : 100,
       
   109         'is_obsolete' : True,
       
   110         'is_patch' : True,
       
   111         'id' : 33721,
       
   112         'url' : "https://bugs.webkit.org/attachment.cgi?id=33721",
       
   113         'name' : "Fixed whitespace issue",
       
   114         'type' : "text/plain",
       
   115         'review' : '+',
       
   116         'reviewer_email' : 'one@test.com',
       
   117         'commit-queue' : '+',
       
   118         'committer_email' : 'two@test.com',
       
   119         'in-rietveld': '+',
       
   120         'rietveld_uploader_email': 'three@test.com',
       
   121         'attacher_email' : 'christian.plesner.hansen@gmail.com',
       
   122     }
       
   123 
       
   124     def test_url_creation(self):
       
   125         # FIXME: These would be all better as doctests
       
   126         bugs = Bugzilla()
       
   127         self.assertEquals(None, bugs.bug_url_for_bug_id(None))
       
   128         self.assertEquals(None, bugs.short_bug_url_for_bug_id(None))
       
   129         self.assertEquals(None, bugs.attachment_url_for_id(None))
       
   130 
       
   131     def test_parse_bug_id(self):
       
   132         # FIXME: These would be all better as doctests
       
   133         bugs = Bugzilla()
       
   134         self.assertEquals(12345, parse_bug_id("http://webkit.org/b/12345"))
       
   135         self.assertEquals(12345, parse_bug_id("http://bugs.webkit.org/show_bug.cgi?id=12345"))
       
   136         self.assertEquals(12345, parse_bug_id(bugs.short_bug_url_for_bug_id(12345)))
       
   137         self.assertEquals(12345, parse_bug_id(bugs.bug_url_for_bug_id(12345)))
       
   138         self.assertEquals(12345, parse_bug_id(bugs.bug_url_for_bug_id(12345, xml=True)))
       
   139 
       
   140         # Our bug parser is super-fragile, but at least we're testing it.
       
   141         self.assertEquals(None, parse_bug_id("http://www.webkit.org/b/12345"))
       
   142         self.assertEquals(None, parse_bug_id("http://bugs.webkit.org/show_bug.cgi?ctype=xml&id=12345"))
       
   143 
       
   144     _example_bug = """
       
   145 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
       
   146 <!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd">
       
   147 <bugzilla version="3.2.3"
       
   148           urlbase="https://bugs.webkit.org/"
       
   149           maintainer="admin@webkit.org"
       
   150           exporter="eric@webkit.org"
       
   151 >
       
   152     <bug>
       
   153           <bug_id>32585</bug_id>
       
   154           <creation_ts>2009-12-15 15:17 PST</creation_ts>
       
   155           <short_desc>bug to test webkit-patch and commit-queue failures</short_desc>
       
   156           <delta_ts>2009-12-27 21:04:50 PST</delta_ts>
       
   157           <reporter_accessible>1</reporter_accessible>
       
   158           <cclist_accessible>1</cclist_accessible>
       
   159           <classification_id>1</classification_id>
       
   160           <classification>Unclassified</classification>
       
   161           <product>WebKit</product>
       
   162           <component>Tools / Tests</component>
       
   163           <version>528+ (Nightly build)</version>
       
   164           <rep_platform>PC</rep_platform>
       
   165           <op_sys>Mac OS X 10.5</op_sys>
       
   166           <bug_status>NEW</bug_status>
       
   167           <priority>P2</priority>
       
   168           <bug_severity>Normal</bug_severity>
       
   169           <target_milestone>---</target_milestone>
       
   170           <everconfirmed>1</everconfirmed>
       
   171           <reporter name="Eric Seidel">eric@webkit.org</reporter>
       
   172           <assigned_to name="Nobody">webkit-unassigned@lists.webkit.org</assigned_to>
       
   173           <cc>foo@bar.com</cc>
       
   174     <cc>example@example.com</cc>
       
   175           <long_desc isprivate="0">
       
   176             <who name="Eric Seidel">eric@webkit.org</who>
       
   177             <bug_when>2009-12-15 15:17:28 PST</bug_when>
       
   178             <thetext>bug to test webkit-patch and commit-queue failures
       
   179 
       
   180 Ignore this bug.  Just for testing failure modes of webkit-patch and the commit-queue.</thetext>
       
   181           </long_desc>
       
   182           <attachment 
       
   183               isobsolete="0"
       
   184               ispatch="1"
       
   185               isprivate="0"
       
   186           > 
       
   187             <attachid>45548</attachid> 
       
   188             <date>2009-12-27 23:51 PST</date> 
       
   189             <desc>Patch</desc> 
       
   190             <filename>bug-32585-20091228005112.patch</filename> 
       
   191             <type>text/plain</type> 
       
   192             <size>10882</size> 
       
   193             <attacher>mjs@apple.com</attacher> 
       
   194             
       
   195               <token>1261988248-dc51409e9c421a4358f365fa8bec8357</token> 
       
   196               <data encoding="base64">SW5kZXg6IFdlYktpdC9tYWMvQ2hhbmdlTG9nCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
       
   197 removed-because-it-was-really-long
       
   198 ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg==
       
   199 </data>        
       
   200  
       
   201             <flag name="review"
       
   202                 id="27602"
       
   203                 status="?"
       
   204                 setter="mjs@apple.com"
       
   205             />
       
   206         </attachment>
       
   207     </bug>
       
   208 </bugzilla>
       
   209 """
       
   210     _expected_example_bug_parsing = {
       
   211         "id" : 32585,
       
   212         "title" : u"bug to test webkit-patch and commit-queue failures",
       
   213         "cc_emails" : ["foo@bar.com", "example@example.com"],
       
   214         "reporter_email" : "eric@webkit.org",
       
   215         "assigned_to_email" : "webkit-unassigned@lists.webkit.org",
       
   216         "attachments" : [{
       
   217             "attach_date": datetime.datetime(2009, 12, 27, 23, 51),
       
   218             'name': u'Patch',
       
   219             'url' : "https://bugs.webkit.org/attachment.cgi?id=45548",
       
   220             'is_obsolete': False,
       
   221             'review': '?',
       
   222             'is_patch': True,
       
   223             'attacher_email': 'mjs@apple.com',
       
   224             'bug_id': 32585,
       
   225             'type': 'text/plain',
       
   226             'id': 45548
       
   227         }],
       
   228     }
       
   229 
       
   230     # FIXME: This should move to a central location and be shared by more unit tests.
       
   231     def _assert_dictionaries_equal(self, actual, expected):
       
   232         # Make sure we aren't parsing more or less than we expect
       
   233         self.assertEquals(sorted(actual.keys()), sorted(expected.keys()))
       
   234 
       
   235         for key, expected_value in expected.items():
       
   236             self.assertEquals(actual[key], expected_value, ("Failure for key: %s: Actual='%s' Expected='%s'" % (key, actual[key], expected_value)))
       
   237 
       
   238     def test_bug_parsing(self):
       
   239         bug = Bugzilla()._parse_bug_page(self._example_bug)
       
   240         self._assert_dictionaries_equal(bug, self._expected_example_bug_parsing)
       
   241 
       
   242     # This could be combined into test_bug_parsing later if desired.
       
   243     def test_attachment_parsing(self):
       
   244         bugzilla = Bugzilla()
       
   245         soup = BeautifulSoup(self._example_attachment)
       
   246         attachment_element = soup.find("attachment")
       
   247         attachment = bugzilla._parse_attachment_element(attachment_element, self._expected_example_attachment_parsing['bug_id'])
       
   248         self.assertTrue(attachment)
       
   249         self._assert_dictionaries_equal(attachment, self._expected_example_attachment_parsing)
       
   250 
       
   251     _sample_attachment_detail_page = """
       
   252 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       
   253                       "http://www.w3.org/TR/html4/loose.dtd">
       
   254 <html>
       
   255   <head>
       
   256     <title>
       
   257   Attachment 41073 Details for Bug 27314</title>
       
   258 <link rel="Top" href="https://bugs.webkit.org/">
       
   259     <link rel="Up" href="show_bug.cgi?id=27314">
       
   260 """
       
   261 
       
   262     def test_attachment_detail_bug_parsing(self):
       
   263         bugzilla = Bugzilla()
       
   264         self.assertEquals(27314, bugzilla._parse_bug_id_from_attachment_page(self._sample_attachment_detail_page))
       
   265 
       
   266     def test_add_cc_to_bug(self):
       
   267         bugzilla = Bugzilla()
       
   268         bugzilla.browser = MockBrowser()
       
   269         bugzilla.authenticate = lambda: None
       
   270         expected_stderr = "Adding ['adam@example.com'] to the CC list for bug 42\n"
       
   271         OutputCapture().assert_outputs(self, bugzilla.add_cc_to_bug, [42, ["adam@example.com"]], expected_stderr=expected_stderr)
       
   272 
       
   273     def _mock_control_item(self, name):
       
   274         mock_item = Mock()
       
   275         mock_item.name = name
       
   276         return mock_item
       
   277 
       
   278     def _mock_find_control(self, item_names=[], selected_index=0):
       
   279         mock_control = Mock()
       
   280         mock_control.items = [self._mock_control_item(name) for name in item_names]
       
   281         mock_control.value = [item_names[selected_index]] if item_names else None
       
   282         return lambda name, type: mock_control
       
   283 
       
   284     def _assert_reopen(self, item_names=None, selected_index=None, extra_stderr=None):
       
   285         bugzilla = Bugzilla()
       
   286         bugzilla.browser = MockBrowser()
       
   287         bugzilla.authenticate = lambda: None
       
   288 
       
   289         mock_find_control = self._mock_find_control(item_names, selected_index)
       
   290         bugzilla.browser.find_control = mock_find_control
       
   291         expected_stderr = "Re-opening bug 42\n['comment']\n"
       
   292         if extra_stderr:
       
   293             expected_stderr += extra_stderr
       
   294         OutputCapture().assert_outputs(self, bugzilla.reopen_bug, [42, ["comment"]], expected_stderr=expected_stderr)
       
   295 
       
   296     def test_reopen_bug(self):
       
   297         self._assert_reopen(item_names=["REOPENED", "RESOLVED", "CLOSED"], selected_index=1)
       
   298         self._assert_reopen(item_names=["UNCONFIRMED", "RESOLVED", "CLOSED"], selected_index=1)
       
   299         extra_stderr = "Did not reopen bug 42, it appears to already be open with status ['NEW'].\n"
       
   300         self._assert_reopen(item_names=["NEW", "RESOLVED"], selected_index=0, extra_stderr=extra_stderr)
       
   301 
       
   302 
       
   303 class BugzillaQueriesTest(unittest.TestCase):
       
   304     _sample_request_page = """
       
   305 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       
   306                       "http://www.w3.org/TR/html4/loose.dtd">
       
   307 <html>
       
   308   <head>
       
   309     <title>Request Queue</title>
       
   310   </head>
       
   311 <body>
       
   312 
       
   313 <h3>Flag: review</h3>
       
   314   <table class="requests" cellspacing="0" cellpadding="4" border="1">
       
   315     <tr>
       
   316         <th>Requester</th>
       
   317         <th>Requestee</th>
       
   318         <th>Bug</th>
       
   319         <th>Attachment</th>
       
   320         <th>Created</th>
       
   321     </tr>
       
   322     <tr>
       
   323         <td>Shinichiro Hamaji &lt;hamaji&#64;chromium.org&gt;</td>
       
   324         <td></td>
       
   325         <td><a href="show_bug.cgi?id=30015">30015: text-transform:capitalize is failing in CSS2.1 test suite</a></td>
       
   326         <td><a href="attachment.cgi?id=40511&amp;action=review">
       
   327 40511: Patch v0</a></td>
       
   328         <td>2009-10-02 04:58 PST</td>
       
   329     </tr>
       
   330     <tr>
       
   331         <td>Zan Dobersek &lt;zandobersek&#64;gmail.com&gt;</td>
       
   332         <td></td>
       
   333         <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playing html5 video.</a></td>
       
   334         <td><a href="attachment.cgi?id=40722&amp;action=review">
       
   335 40722: Media controls, the simple approach</a></td>
       
   336         <td>2009-10-06 09:13 PST</td>
       
   337     </tr>
       
   338     <tr>
       
   339         <td>Zan Dobersek &lt;zandobersek&#64;gmail.com&gt;</td>
       
   340         <td></td>
       
   341         <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playing html5 video.</a></td>
       
   342         <td><a href="attachment.cgi?id=40723&amp;action=review">
       
   343 40723: Adjust the media slider thumb size</a></td>
       
   344         <td>2009-10-06 09:15 PST</td>
       
   345     </tr>
       
   346   </table>
       
   347 </body>
       
   348 </html>
       
   349 """
       
   350     _sample_quip_page = u"""
       
   351 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       
   352                       "http://www.w3.org/TR/html4/loose.dtd">
       
   353 <html>
       
   354   <head>
       
   355     <title>Bugzilla Quip System</title>
       
   356   </head>
       
   357   <body>
       
   358     <h2>
       
   359 
       
   360       Existing quips:
       
   361     </h2>
       
   362     <ul>
       
   363         <li>Everything should be made as simple as possible, but not simpler. - Albert Einstein</li>
       
   364         <li>Good artists copy. Great artists steal. - Pablo Picasso</li>
       
   365         <li>\u00e7gua mole em pedra dura, tanto bate at\u008e que fura.</li>
       
   366 
       
   367     </ul>
       
   368   </body>
       
   369 </html>
       
   370 """
       
   371 
       
   372     def test_request_page_parsing(self):
       
   373         queries = BugzillaQueries(None)
       
   374         self.assertEquals([40511, 40722, 40723], queries._parse_attachment_ids_request_query(self._sample_request_page))
       
   375 
       
   376     def test_quip_page_parsing(self):
       
   377         queries = BugzillaQueries(None)
       
   378         expected_quips = ["Everything should be made as simple as possible, but not simpler. - Albert Einstein", "Good artists copy. Great artists steal. - Pablo Picasso", u"\u00e7gua mole em pedra dura, tanto bate at\u008e que fura."]
       
   379         self.assertEquals(expected_quips, queries._parse_quips(self._sample_quip_page))
       
   380 
       
   381     def test_load_query(self):
       
   382         queries = BugzillaQueries(Mock())
       
   383         queries._load_query("request.cgi?action=queue&type=review&group=type")