1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Copyright (C) 2009 Google Inc. All rights reserved.
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Redistribution and use in source and binary forms, with or without
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# modification, are permitted provided that the following conditions are
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# met:
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#    * Redistributions of source code must retain the above copyright
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# notice, this list of conditions and the following disclaimer.
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#    * Redistributions in binary form must reproduce the above
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# copyright notice, this list of conditions and the following disclaimer
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# in the documentation and/or other materials provided with the
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# distribution.
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#    * Neither the name of Google Inc. nor the names of its
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# contributors may be used to endorse or promote products derived from
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# this software without specific prior written permission.
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport os
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochimport StringIO
31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickfrom webkitpy.common.checkout.scm import CheckoutNeedsUpdate
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.common.net.bugzilla import Attachment
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochfrom webkitpy.common.system.filesystem_mock import MockFileSystem
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.common.system.outputcapture import OutputCapture
36cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.layout_tests.layout_package import test_results
37cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.layout_tests.layout_package import test_failures
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.thirdparty.mock import Mock
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.tool.commands.commandtest import CommandsTest
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.tool.commands.queues import *
41e14391e94c850b8bd03680c23b38978db68687a8John Reckfrom webkitpy.tool.commands.queuestest import QueuesTest
425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickfrom webkitpy.tool.commands.stepsequence import StepSequence
4368513a70bcd92384395513322f1b801e7bf9c729Steve Blockfrom webkitpy.tool.mocktool import MockTool, MockSCM, MockStatusServer
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass TestQueue(AbstractPatchQueue):
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    name = "test-queue"
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass TestReviewQueue(AbstractReviewQueue):
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    name = "test-review-queue"
52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
54bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass TestFeederQueue(FeederQueue):
55bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    _sleep_duration = 0
56bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
57bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass AbstractQueueTest(CommandsTest):
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_log_directory(self):
60cad810f21b803229eb11403f9209855525a25d57Steve Block        self.assertEquals(TestQueue()._log_directory(), os.path.join("..", "test-queue-logs"))
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def _assert_run_webkit_patch(self, run_args, port=None):
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        queue = TestQueue()
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool = MockTool()
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        tool.status_server.bot_id = "gort"
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool.executive = Mock()
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        queue.bind_to_tool(tool)
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options = Mock()
69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options.port = port
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        queue.run_webkit_patch(run_args)
72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        expected_run_args = ["echo", "--status-host=example.com", "--bot-id=gort"]
73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if port:
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            expected_run_args.append("--port=%s" % port)
75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        expected_run_args.extend(run_args)
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_run_webkit_patch(self):
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._assert_run_webkit_patch([1])
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._assert_run_webkit_patch(["one", 2])
81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        self._assert_run_webkit_patch([1], port="mockport")
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_iteration_count(self):
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        queue = TestQueue()
85a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options = Mock()
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options.iterations = 3
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertFalse(queue.should_continue_work_queue())
91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_no_iteration_count(self):
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        queue = TestQueue()
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options = Mock()
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assertTrue(queue.should_continue_work_queue())
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
100e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    def _assert_log_message(self, script_error, log_message):
101e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        failure_log = AbstractQueue._log_from_script_error_for_upload(script_error, output_limit=10)
102e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        self.assertTrue(failure_log.read(), log_message)
103e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
104e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    def test_log_from_script_error_for_upload(self):
105e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        self._assert_log_message(ScriptError("test"), "test")
106e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        # In python 2.5 unicode(Exception) is busted. See:
107e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        # http://bugs.python.org/issue2517
108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        # With no good workaround, we just ignore these tests.
109e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if not hasattr(Exception, "__unicode__"):
110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            return
111e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
112e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
113e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        utf8_tor = unicode_tor.encode("utf-8")
114e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        self._assert_log_message(ScriptError(unicode_tor), utf8_tor)
115e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        script_error = ScriptError(unicode_tor, output=unicode_tor)
116e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        expected_output = "%s\nLast %s characters of output:\n%s" % (utf8_tor, 10, utf8_tor[-10:])
117e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        self._assert_log_message(script_error, expected_output)
118e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
120bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass FeederQueueTest(QueuesTest):
121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    def test_feeder_queue(self):
122bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        queue = TestFeederQueue()
123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        tool = MockTool(log_executive=True)
124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        expected_stderr = {
125bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "begin_work_queue": self._default_begin_work_queue_stderr("feeder-queue", MockSCM.fake_checkout_root),
126bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "should_proceed_with_work_item": "",
127bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "next_work_item": "",
128bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "process_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
129bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenWarning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
130f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting attachment 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy/common/config/committers.py.
131bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
133bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch- If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed).  The commit-queue restarts itself every 2 hours.  After restart the commit-queue will correctly respect your committer rights.'
135bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_work_items: commit-queue [106, 197]
136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenFeeding commit-queue items [106, 197]
137a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochFeeding EWS (1 r? patch, 1 new)
138a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochMOCK: submit_to_ews: 103
139bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen""",
140bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "handle_unexpected_error": "Mock error message\n",
141bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
142bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        self.assert_queue_outputs(queue, tool=tool, expected_stderr=expected_stderr)
143bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
144bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
14568513a70bcd92384395513322f1b801e7bf9c729Steve Blockclass AbstractPatchQueueTest(CommandsTest):
146e14391e94c850b8bd03680c23b38978db68687a8John Reck    def test_next_patch(self):
14768513a70bcd92384395513322f1b801e7bf9c729Steve Block        queue = AbstractPatchQueue()
14868513a70bcd92384395513322f1b801e7bf9c729Steve Block        tool = MockTool()
14968513a70bcd92384395513322f1b801e7bf9c729Steve Block        queue.bind_to_tool(tool)
150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options = Mock()
151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options.port = None
152e14391e94c850b8bd03680c23b38978db68687a8John Reck        self.assertEquals(queue._next_patch(), None)
153e14391e94c850b8bd03680c23b38978db68687a8John Reck        tool.status_server = MockStatusServer(work_items=[2, 197])
154e14391e94c850b8bd03680c23b38978db68687a8John Reck        expected_stdout = "MOCK: fetch_attachment: 2 is not a known attachment id\n"  # A mock-only message to prevent us from making mistakes.
155e14391e94c850b8bd03680c23b38978db68687a8John Reck        expected_stderr = "MOCK: release_work_item: None 2\n"
156e14391e94c850b8bd03680c23b38978db68687a8John Reck        patch_id = OutputCapture().assert_outputs(self, queue._next_patch, [], expected_stdout=expected_stdout, expected_stderr=expected_stderr)
157e14391e94c850b8bd03680c23b38978db68687a8John Reck        self.assertEquals(patch_id, None)  # 2 is an invalid patch id
158e14391e94c850b8bd03680c23b38978db68687a8John Reck        self.assertEquals(queue._next_patch().id(), 197)
15968513a70bcd92384395513322f1b801e7bf9c729Steve Block
16068513a70bcd92384395513322f1b801e7bf9c729Steve Block
1615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickclass NeedsUpdateSequence(StepSequence):
1625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    def _run(self, tool, options, state):
1635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        raise CheckoutNeedsUpdate([], 1, "", None)
1645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickclass AlwaysCommitQueueTool(object):
16768513a70bcd92384395513322f1b801e7bf9c729Steve Block    def __init__(self):
16868513a70bcd92384395513322f1b801e7bf9c729Steve Block        self.status_server = MockStatusServer()
16968513a70bcd92384395513322f1b801e7bf9c729Steve Block
1705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    def command_by_name(self, name):
1715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return CommitQueue
1725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
17468513a70bcd92384395513322f1b801e7bf9c729Steve Blockclass SecondThoughtsCommitQueue(CommitQueue):
175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def __init__(self):
176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        self._reject_patch = False
177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        CommitQueue.__init__(self)
178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def run_command(self, command):
180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        # We want to reject the patch after the first validation,
181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        # so wait to reject it until after some other command has run.
182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        self._reject_patch = True
183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return CommitQueue.run_command(self, command)
184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def refetch_patch(self, patch):
186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if not self._reject_patch:
187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return self._tool.bugs.fetch_attachment(patch.id())
188a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
18968513a70bcd92384395513322f1b801e7bf9c729Steve Block        attachment_dictionary = {
19068513a70bcd92384395513322f1b801e7bf9c729Steve Block            "id": patch.id(),
19168513a70bcd92384395513322f1b801e7bf9c729Steve Block            "bug_id": patch.bug_id(),
19268513a70bcd92384395513322f1b801e7bf9c729Steve Block            "name": "Rejected",
19368513a70bcd92384395513322f1b801e7bf9c729Steve Block            "is_obsolete": True,
19468513a70bcd92384395513322f1b801e7bf9c729Steve Block            "is_patch": False,
19568513a70bcd92384395513322f1b801e7bf9c729Steve Block            "review": "-",
19668513a70bcd92384395513322f1b801e7bf9c729Steve Block            "reviewer_email": "foo@bar.com",
19768513a70bcd92384395513322f1b801e7bf9c729Steve Block            "commit-queue": "-",
19868513a70bcd92384395513322f1b801e7bf9c729Steve Block            "committer_email": "foo@bar.com",
19968513a70bcd92384395513322f1b801e7bf9c729Steve Block            "attacher_email": "Contributer1",
20068513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Attachment(attachment_dictionary, None)
20268513a70bcd92384395513322f1b801e7bf9c729Steve Block
20368513a70bcd92384395513322f1b801e7bf9c729Steve Block
204dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass CommitQueueTest(QueuesTest):
205cad810f21b803229eb11403f9209855525a25d57Steve Block    def _mock_test_result(self, testname):
206cad810f21b803229eb11403f9209855525a25d57Steve Block        return test_results.TestResult(testname, [test_failures.FailureTextMismatch()])
207cad810f21b803229eb11403f9209855525a25d57Steve Block
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_commit_queue(self):
209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        expected_stderr = {
21068513a70bcd92384395513322f1b801e7bf9c729Steve Block            "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
211bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
212bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "next_work_item": "",
213f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "process_work_item": """MOCK: update_status: commit-queue Cleaned working directory
214f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Updated working directory
215f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Applied patch
216bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Built patch
217bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Passed tests
218bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Landed patch
219bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Pass
220e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK: release_work_item: commit-queue 197
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block""",
222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting attachment 197 from commit-queue.' and additional comment 'Mock error message'\n",
223bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "handle_script_error": "ScriptError error message\n",
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assert_queue_outputs(CommitQueue(), expected_stderr=expected_stderr)
226dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
227bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    def test_commit_queue_failure(self):
228bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        expected_stderr = {
229bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
230bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
231bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "next_work_item": "",
232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "process_work_item": """MOCK: update_status: commit-queue Cleaned working directory
233f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Updated working directory
234f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Patch does not apply
235f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting attachment 197 from commit-queue.' and additional comment 'MOCK script error'
236bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Fail
237a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochMOCK: release_work_item: commit-queue 197
238bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen""",
239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting attachment 197 from commit-queue.' and additional comment 'Mock error message'\n",
240bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "handle_script_error": "ScriptError error message\n",
241bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
242bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        queue = CommitQueue()
243bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
244bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        def mock_run_webkit_patch(command):
245f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if command == ['clean'] or command == ['update']:
246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                # We want cleaning to succeed so we can error out on a step
247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                # that causes the commit-queue to reject the patch.
248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                return
249bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            raise ScriptError('MOCK script error')
250bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
251bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        queue.run_webkit_patch = mock_run_webkit_patch
252bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        self.assert_queue_outputs(queue, expected_stderr=expected_stderr)
253bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
254dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_rollout(self):
255dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool = MockTool(log_executive=True)
2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        tool.filesystem.write_text_file('/mock/results.html', '')  # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem.
257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool.buildbot.light_tree_on_fire()
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        expected_stderr = {
25968513a70bcd92384395513322f1b801e7bf9c729Steve Block            "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
260bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
261bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "next_work_item": "",
262f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean']
263f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Cleaned working directory
264f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update']
265f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Updated working directory
266f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 197]
267bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Applied patch
268e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both']
269bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Built patch
270e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive']
271bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Passed tests
272e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 197]
273bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Landed patch
274bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Pass
275e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK: release_work_item: commit-queue 197
276dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block""",
277f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting attachment 197 from commit-queue.' and additional comment 'Mock error message'\n",
278bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "handle_script_error": "ScriptError error message\n",
279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
280dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assert_queue_outputs(CommitQueue(), tool=tool, expected_stderr=expected_stderr)
281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
282dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_rollout_lands(self):
283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool = MockTool(log_executive=True)
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        tool.buildbot.light_tree_on_fire()
285e14391e94c850b8bd03680c23b38978db68687a8John Reck        rollout_patch = tool.bugs.fetch_attachment(106)  # _patch6, a rollout patch.
286e14391e94c850b8bd03680c23b38978db68687a8John Reck        assert(rollout_patch.is_rollout())
287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        expected_stderr = {
28868513a70bcd92384395513322f1b801e7bf9c729Steve Block            "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
289bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing rollout patch\n",
290bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "next_work_item": "",
291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean']
292f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Cleaned working directory
293f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update']
294f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Updated working directory
295f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 106]
296bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Applied patch
297e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 106]
298bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Landed patch
299bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Pass
300e14391e94c850b8bd03680c23b38978db68687a8John ReckMOCK: release_work_item: commit-queue 106
301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block""",
302f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '106' with comment 'Rejecting attachment 106 from commit-queue.' and additional comment 'Mock error message'\n",
303bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            "handle_script_error": "ScriptError error message\n",
304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_stderr=expected_stderr)
306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    def test_auto_retry(self):
3085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        queue = CommitQueue()
3095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        options = Mock()
3105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        options.parent_command = "commit-queue"
3115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        tool = AlwaysCommitQueueTool()
3125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        sequence = NeedsUpdateSequence(None)
3135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
31468513a70bcd92384395513322f1b801e7bf9c729Steve Block        expected_stderr = "Commit failed because the checkout is out of date.  Please update and try again.\nMOCK: update_status: commit-queue Tests passed, but commit failed (checkout out of date).  Updating, then landing without building or re-running tests.\n"
31568513a70bcd92384395513322f1b801e7bf9c729Steve Block        state = {'patch': None}
31668513a70bcd92384395513322f1b801e7bf9c729Steve Block        OutputCapture().assert_outputs(self, sequence.run_and_handle_errors, [tool, options, state], expected_exception=TryAgain, expected_stderr=expected_stderr)
3175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
3185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        self.assertEquals(options.update, True)
3195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        self.assertEquals(options.build, False)
3205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        self.assertEquals(options.test, False)
3215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
32268513a70bcd92384395513322f1b801e7bf9c729Steve Block    def test_manual_reject_during_processing(self):
32368513a70bcd92384395513322f1b801e7bf9c729Steve Block        queue = SecondThoughtsCommitQueue()
32468513a70bcd92384395513322f1b801e7bf9c729Steve Block        queue.bind_to_tool(MockTool())
3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue._tool.filesystem.write_text_file('/mock/results.html', '')  # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem.
326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options = Mock()
327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._options.port = None
328f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        expected_stderr = """MOCK: update_status: commit-queue Cleaned working directory
329f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Updated working directory
330f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK: update_status: commit-queue Applied patch
331bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Built patch
332bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenMOCK: update_status: commit-queue Passed tests
333a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochMOCK: update_status: commit-queue Retry
334a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochMOCK: release_work_item: commit-queue 197
335bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen"""
336e14391e94c850b8bd03680c23b38978db68687a8John Reck        OutputCapture().assert_outputs(self, queue.process_work_item, [QueuesTest.mock_work_item], expected_stderr=expected_stderr)
337e14391e94c850b8bd03680c23b38978db68687a8John Reck
338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def test_report_flaky_tests(self):
339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue = CommitQueue()
340a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue.bind_to_tool(MockTool())
341f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        expected_stderr = """MOCK bug comment: bug_id=76, cc=None
342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch--- Begin comment ---
343cad810f21b803229eb11403f9209855525a25d57Steve BlockThe commit-queue just saw foo/bar.html flake (Text diff mismatch) while processing attachment 197 on bug 42.
344f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPort: MockPort  Platform: MockPlatform 1.0
345f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch--- End comment ---
346f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
34765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochMOCK add_attachment_to_bug: bug_id=76, description=Failure diff from bot filename=failure.diff
348f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK bug comment: bug_id=76, cc=None
349f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch--- Begin comment ---
350cad810f21b803229eb11403f9209855525a25d57Steve BlockThe commit-queue just saw bar/baz.html flake (Text diff mismatch) while processing attachment 197 on bug 42.
351f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPort: MockPort  Platform: MockPlatform 1.0
352f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch--- End comment ---
353a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
35465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochMOCK add_attachment_to_bug: bug_id=76, description=Archive of layout-test-results from bot filename=layout-test-results.zip
355f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochMOCK bug comment: bug_id=42, cc=None
356f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch--- Begin comment ---
357f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochThe commit-queue encountered the following flaky tests while processing attachment 197:
358a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
359f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochfoo/bar.html bug 76 (author: abarth@webkit.org)
360f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbar/baz.html bug 76 (author: abarth@webkit.org)
361f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochThe commit-queue is continuing to process your patch.
362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch--- End comment ---
363a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch"""
365cad810f21b803229eb11403f9209855525a25d57Steve Block        test_names = ["foo/bar.html", "bar/baz.html"]
366cad810f21b803229eb11403f9209855525a25d57Steve Block        test_results = [self._mock_test_result(name) for name in test_names]
36765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
36865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        class MockZipFile(object):
36965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            def __init__(self):
37065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                self.fp = StringIO()
37165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
37265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            def read(self, path):
37365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return ""
37465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
37565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            def namelist(self):
37665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                # This is intentionally missing one diffs.txt to exercise the "upload the whole zip" codepath.
37765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return ['foo/bar-diffs.txt']
37865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
37965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        OutputCapture().assert_outputs(self, queue.report_flaky_tests, [QueuesTest.mock_work_item, test_results, MockZipFile()], expected_stderr=expected_stderr)
380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
3812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def test_missing_layout_test_results(self):
3822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue = CommitQueue()
3832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        tool = MockTool()
3842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        results_path = '/mock/results.html'
3852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        tool.filesystem = MockFileSystem({results_path: None})
3862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue.bind_to_tool(tool)
3872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        # Make sure that our filesystem mock functions as we expect.
3882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertRaises(IOError, tool.filesystem.read_text_file, results_path)
3892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        # layout_test_results shouldn't raise even if the results.html file is missing.
3902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertEquals(queue.layout_test_results(), None)
3912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
392a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    def test_layout_test_results(self):
393a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue = CommitQueue()
394a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue.bind_to_tool(MockTool())
395a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._read_file_contents = lambda path: None
396a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        self.assertEquals(queue.layout_test_results(), None)
397a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        queue._read_file_contents = lambda path: ""
398a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        self.assertEquals(queue.layout_test_results(), None)
3992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue._create_layout_test_results = lambda: LayoutTestResults([])
4002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        results = queue.layout_test_results()
4012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertNotEquals(results, None)
4022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertEquals(results.failure_limit_count(), 10)  # This value matches RunTests.NON_INTERACTIVE_FAILURE_LIMIT_COUNT
403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
40465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    def test_archive_last_layout_test_results(self):
40565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        queue = CommitQueue()
40665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        queue.bind_to_tool(MockTool())
40765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        patch = queue._tool.bugs.fetch_attachment(128)
4082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        # This is just to test that the method doesn't raise.
40965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        queue.archive_last_layout_test_results(patch)
41065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def test_upload_results_archive_for_patch(self):
4122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue = CommitQueue()
4132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        queue.bind_to_tool(MockTool())
4142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        patch = queue._tool.bugs.fetch_attachment(128)
4152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        expected_stderr = """MOCK add_attachment_to_bug: bug_id=42, description=Archive of layout-test-results from bot filename=layout-test-results.zip
4162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch-- Begin comment --
4172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochThe attached test failures were seen while running run-webkit-tests on the commit-queue.
4182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPort: MockPort  Platform: MockPlatform 1.0
4192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch-- End comment --
4202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch"""
4212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        OutputCapture().assert_outputs(self, queue._upload_results_archive_for_patch, [patch, Mock()], expected_stderr=expected_stderr)
4222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
423545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
424dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass StyleQueueTest(QueuesTest):
425dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def test_style_queue(self):
426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        expected_stderr = {
42768513a70bcd92384395513322f1b801e7bf9c729Steve Block            "begin_work_queue": self._default_begin_work_queue_stderr("style-queue", MockSCM.fake_checkout_root),
428a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            "next_work_item": "",
4296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            "should_proceed_with_work_item": "MOCK: update_status: style-queue Checking style\n",
430a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            "process_work_item": "MOCK: update_status: style-queue Pass\nMOCK: release_work_item: style-queue 197\n",
43168513a70bcd92384395513322f1b801e7bf9c729Steve Block            "handle_unexpected_error": "Mock error message\n",
432e14391e94c850b8bd03680c23b38978db68687a8John Reck            "handle_script_error": "MOCK: update_status: style-queue ScriptError error message\nMOCK bug comment: bug_id=42, cc=[]\n--- Begin comment ---\nAttachment 197 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",
433545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
434545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        expected_exceptions = {
435545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            "handle_script_error": SystemExit,
436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
437545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        self.assert_queue_outputs(StyleQueue(), expected_stderr=expected_stderr, expected_exceptions=expected_exceptions)
438