WebKitTools/Scripts/webkitpy/tool/commands/queues_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 os
       
    30 
       
    31 from webkitpy.common.net.bugzilla import Attachment
       
    32 from webkitpy.common.system.outputcapture import OutputCapture
       
    33 from webkitpy.thirdparty.mock import Mock
       
    34 from webkitpy.tool.commands.commandtest import CommandsTest
       
    35 from webkitpy.tool.commands.queues import *
       
    36 from webkitpy.tool.commands.queuestest import QueuesTest
       
    37 from webkitpy.tool.mocktool import MockTool, MockSCM
       
    38 
       
    39 
       
    40 class TestQueue(AbstractPatchQueue):
       
    41     name = "test-queue"
       
    42 
       
    43 
       
    44 class TestReviewQueue(AbstractReviewQueue):
       
    45     name = "test-review-queue"
       
    46 
       
    47 
       
    48 class MockPatch(object):
       
    49     def is_rollout(self):
       
    50         return True
       
    51 
       
    52     def bug_id(self):
       
    53         return 12345
       
    54 
       
    55     def id(self):
       
    56         return 76543
       
    57 
       
    58 
       
    59 class AbstractQueueTest(CommandsTest):
       
    60     def _assert_log_progress_output(self, patch_ids, progress_output):
       
    61         OutputCapture().assert_outputs(self, TestQueue().log_progress, [patch_ids], expected_stderr=progress_output)
       
    62 
       
    63     def test_log_progress(self):
       
    64         self._assert_log_progress_output([1,2,3], "3 patches in test-queue [1, 2, 3]\n")
       
    65         self._assert_log_progress_output(["1","2","3"], "3 patches in test-queue [1, 2, 3]\n")
       
    66         self._assert_log_progress_output([1], "1 patch in test-queue [1]\n")
       
    67 
       
    68     def test_log_directory(self):
       
    69         self.assertEquals(TestQueue()._log_directory(), "test-queue-logs")
       
    70 
       
    71     def _assert_run_webkit_patch(self, run_args):
       
    72         queue = TestQueue()
       
    73         tool = MockTool()
       
    74         tool.executive = Mock()
       
    75         queue.bind_to_tool(tool)
       
    76 
       
    77         queue.run_webkit_patch(run_args)
       
    78         expected_run_args = ["echo", "--status-host=example.com"] + run_args
       
    79         tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
       
    80 
       
    81     def test_run_webkit_patch(self):
       
    82         self._assert_run_webkit_patch([1])
       
    83         self._assert_run_webkit_patch(["one", 2])
       
    84 
       
    85     def test_iteration_count(self):
       
    86         queue = TestQueue()
       
    87         queue.options = Mock()
       
    88         queue.options.iterations = 3
       
    89         self.assertTrue(queue.should_continue_work_queue())
       
    90         self.assertTrue(queue.should_continue_work_queue())
       
    91         self.assertTrue(queue.should_continue_work_queue())
       
    92         self.assertFalse(queue.should_continue_work_queue())
       
    93 
       
    94     def test_no_iteration_count(self):
       
    95         queue = TestQueue()
       
    96         queue.options = Mock()
       
    97         self.assertTrue(queue.should_continue_work_queue())
       
    98         self.assertTrue(queue.should_continue_work_queue())
       
    99         self.assertTrue(queue.should_continue_work_queue())
       
   100         self.assertTrue(queue.should_continue_work_queue())
       
   101 
       
   102 
       
   103 class AbstractReviewQueueTest(CommandsTest):
       
   104     def test_patch_collection_delegate_methods(self):
       
   105         queue = TestReviewQueue()
       
   106         tool = MockTool()
       
   107         queue.bind_to_tool(tool)
       
   108         self.assertEquals(queue.collection_name(), "test-review-queue")
       
   109         self.assertEquals(queue.fetch_potential_patch_ids(), [103])
       
   110         queue.status_server()
       
   111         self.assertTrue(queue.is_terminal_status("Pass"))
       
   112         self.assertTrue(queue.is_terminal_status("Fail"))
       
   113         self.assertTrue(queue.is_terminal_status("Error: Your patch exploded"))
       
   114         self.assertFalse(queue.is_terminal_status("Foo"))
       
   115 
       
   116 
       
   117 class CommitQueueTest(QueuesTest):
       
   118     def test_commit_queue(self):
       
   119         expected_stderr = {
       
   120             "begin_work_queue" : "CAUTION: commit-queue will discard all local changes in \"%s\"\nRunning WebKit commit-queue.\n" % MockSCM.fake_checkout_root,
       
   121             "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing patch\n",
       
   122             # FIXME: The commit-queue warns about bad committers twice.  This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
       
   123             "next_work_item" : """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   124 Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   125 MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.\n\n- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.\n\n- If you have committer 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 committer rights.'
       
   126 MOCK: update_work_items: commit-queue [106, 197]
       
   127 2 patches in commit-queue [106, 197]
       
   128 """,
       
   129             "process_work_item" : "MOCK: update_status: commit-queue Pass\n",
       
   130             "handle_unexpected_error" : "MOCK setting flag 'commit-queue' to '-' on attachment '1234' with comment 'Rejecting patch 1234 from commit-queue.' and additional comment 'Mock error message'\n",
       
   131             "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '1234' with comment 'Rejecting patch 1234 from commit-queue.' and additional comment 'ScriptError error message'\n",
       
   132         }
       
   133         self.assert_queue_outputs(CommitQueue(), expected_stderr=expected_stderr)
       
   134 
       
   135     def test_rollout(self):
       
   136         tool = MockTool(log_executive=True)
       
   137         tool.buildbot.light_tree_on_fire()
       
   138         expected_stderr = {
       
   139             "begin_work_queue" : "CAUTION: commit-queue will discard all local changes in \"%s\"\nRunning WebKit commit-queue.\n" % MockSCM.fake_checkout_root,
       
   140             "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing patch\n",
       
   141             # FIXME: The commit-queue warns about bad committers twice.  This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
       
   142             "next_work_item" : """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   143 Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   144 MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
       
   145 
       
   146 - If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
       
   147 
       
   148 - If you have committer 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 committer rights.'
       
   149 MOCK: update_work_items: commit-queue [106, 197]
       
   150 2 patches in commit-queue [106, 197]
       
   151 """,
       
   152             "process_work_item" : "MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--build', '--non-interactive', '--ignore-builders', '--build-style=both', '--quiet', 1234, '--test']\nMOCK: update_status: commit-queue Pass\n",
       
   153             "handle_unexpected_error" : "MOCK setting flag 'commit-queue' to '-' on attachment '1234' with comment 'Rejecting patch 1234 from commit-queue.' and additional comment 'Mock error message'\n",
       
   154             "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '1234' with comment 'Rejecting patch 1234 from commit-queue.' and additional comment 'ScriptError error message'\n",
       
   155         }
       
   156         self.assert_queue_outputs(CommitQueue(), tool=tool, expected_stderr=expected_stderr)
       
   157 
       
   158     def test_rollout_lands(self):
       
   159         tool = MockTool(log_executive=True)
       
   160         tool.buildbot.light_tree_on_fire()
       
   161         rollout_patch = MockPatch()
       
   162         expected_stderr = {
       
   163             "begin_work_queue": "CAUTION: commit-queue will discard all local changes in \"%s\"\nRunning WebKit commit-queue.\n" % MockSCM.fake_checkout_root,
       
   164             "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing rollout patch\n",
       
   165             # FIXME: The commit-queue warns about bad committers twice.  This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
       
   166             "next_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   167 Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
       
   168 MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
       
   169 
       
   170 - If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
       
   171 
       
   172 - If you have committer 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 committer rights.'
       
   173 MOCK: update_work_items: commit-queue [106, 197]
       
   174 2 patches in commit-queue [106, 197]
       
   175 """,
       
   176             "process_work_item": "MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--build', '--non-interactive', '--ignore-builders', '--build-style=both', '--quiet', 76543]\nMOCK: update_status: commit-queue Pass\n",
       
   177             "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '76543' with comment 'Rejecting patch 76543 from commit-queue.' and additional comment 'Mock error message'\n",
       
   178             "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '1234' with comment 'Rejecting patch 1234 from commit-queue.' and additional comment 'ScriptError error message'\n",
       
   179         }
       
   180         self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_stderr=expected_stderr)
       
   181 
       
   182     def test_can_build_and_test(self):
       
   183         queue = CommitQueue()
       
   184         tool = MockTool()
       
   185         tool.executive = Mock()
       
   186         queue.bind_to_tool(tool)
       
   187         self.assertTrue(queue._can_build_and_test())
       
   188         expected_run_args = ["echo", "--status-host=example.com", "build-and-test", "--force-clean", "--build", "--test", "--non-interactive", "--no-update", "--build-style=both", "--quiet"]
       
   189         tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
       
   190 
       
   191     def _mock_attachment(self, is_rollout, attach_date):
       
   192         attachment = Mock()
       
   193         attachment.is_rollout = lambda: is_rollout
       
   194         attachment.attach_date = lambda: attach_date
       
   195         return attachment
       
   196 
       
   197     def test_patch_cmp(self):
       
   198         long_ago_date = datetime(1900, 1, 21)
       
   199         recent_date = datetime(2010, 1, 21)
       
   200         attachment1 = self._mock_attachment(is_rollout=False, attach_date=recent_date)
       
   201         attachment2 = self._mock_attachment(is_rollout=False, attach_date=long_ago_date)
       
   202         attachment3 = self._mock_attachment(is_rollout=True, attach_date=recent_date)
       
   203         attachment4 = self._mock_attachment(is_rollout=True, attach_date=long_ago_date)
       
   204         attachments = [attachment1, attachment2, attachment3, attachment4]
       
   205         expected_sort = [attachment4, attachment3, attachment2, attachment1]
       
   206         queue = CommitQueue()
       
   207         attachments.sort(queue._patch_cmp)
       
   208         self.assertEqual(attachments, expected_sort)
       
   209 
       
   210 
       
   211 class RietveldUploadQueueTest(QueuesTest):
       
   212     def test_rietveld_upload_queue(self):
       
   213         expected_stderr = {
       
   214             "begin_work_queue": "CAUTION: rietveld-upload-queue will discard all local changes in \"%s\"\nRunning WebKit rietveld-upload-queue.\n" % MockSCM.fake_checkout_root,
       
   215             "should_proceed_with_work_item": "MOCK: update_status: rietveld-upload-queue Uploading patch\n",
       
   216             "process_work_item": "MOCK: update_status: rietveld-upload-queue Pass\n",
       
   217             "handle_unexpected_error": "Mock error message\nMOCK setting flag 'in-rietveld' to '-' on attachment '1234' with comment 'None' and additional comment 'None'\n",
       
   218             "handle_script_error": "ScriptError error message\nMOCK: update_status: rietveld-upload-queue ScriptError error message\nMOCK setting flag 'in-rietveld' to '-' on attachment '1234' with comment 'None' and additional comment 'None'\n",
       
   219         }
       
   220         self.assert_queue_outputs(RietveldUploadQueue(), expected_stderr=expected_stderr)
       
   221 
       
   222 
       
   223 class StyleQueueTest(QueuesTest):
       
   224     def test_style_queue(self):
       
   225         expected_stderr = {
       
   226             "begin_work_queue" : "CAUTION: style-queue will discard all local changes in \"%s\"\nRunning WebKit style-queue.\n" % MockSCM.fake_checkout_root,
       
   227             "next_work_item": "MOCK: update_work_items: style-queue [103]\n",
       
   228             "should_proceed_with_work_item": "MOCK: update_status: style-queue Checking style\n",
       
   229             "process_work_item" : "MOCK: update_status: style-queue Pass\n",
       
   230             "handle_unexpected_error" : "Mock error message\n",
       
   231             "handle_script_error": "MOCK: update_status: style-queue ScriptError error message\nMOCK bug comment: bug_id=345, cc=[]\n--- Begin comment ---\\Attachment 1234 did not pass style-queue:\n\nScriptError error message\n\nIf any of these errors are false positives, please file a bug against check-webkit-style.\n--- End comment ---\n\n",
       
   232         }
       
   233         expected_exceptions = {
       
   234             "handle_script_error": SystemExit,
       
   235         }
       
   236         self.assert_queue_outputs(StyleQueue(), expected_stderr=expected_stderr, expected_exceptions=expected_exceptions)