Changeset 56947 in webkit
- Timestamp:
- Apr 1, 2010 4:34:40 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 1 added
- 8 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r56942 r56947 1 2010-04-01 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 Add rollout command to sheriffbot 6 https://bugs.webkit.org/show_bug.cgi?id=36986 7 8 This IRC command creates a new bug an attaches a rollout patch. To 9 actually commit the rollout, a committer needs to mark the patch 10 commit-queue+ in bugs.webkit.org. 11 12 Also, factored out some of the logic from the queue into a separate 13 object for easier testing. 14 15 * Scripts/webkitpy/common/system/executive.py: 16 * Scripts/webkitpy/tool/bot/irc_command.py: 17 * Scripts/webkitpy/tool/bot/sheriff.py: Added. 18 * Scripts/webkitpy/tool/bot/sheriff_unittest.py: Added. 19 * Scripts/webkitpy/tool/bot/sheriffircbot.py: 20 * Scripts/webkitpy/tool/bot/sheriffircbot_unittest.py: 21 * Scripts/webkitpy/tool/commands/queues.py: 22 * Scripts/webkitpy/tool/commands/sheriffbot.py: 23 * Scripts/webkitpy/tool/commands/sheriffbot_unittest.py: 24 1 25 2010-04-01 Eric Seidel <eric@webkit.org> 2 26 -
trunk/WebKitTools/Scripts/webkitpy/common/system/executive.py
r56544 r56947 117 117 exit_code=exit_code, 118 118 output=child_output) 119 return child_output 119 120 120 121 @staticmethod -
trunk/WebKitTools/Scripts/webkitpy/tool/bot/irc_command.py
r56883 r56947 29 29 from webkitpy.common.checkout.changelog import view_source_url 30 30 from webkitpy.tool.bot.queueengine import TerminateQueue 31 31 from webkitpy.common.system.executive import ScriptError 32 32 33 33 # FIXME: Merge with Command? 34 34 class IRCCommand(object): 35 def execute(self, args, tool ):35 def execute(self, args, tool, sheriff): 36 36 raise NotImplementedError, "subclasses must implement" 37 37 38 38 39 39 class LastGreenRevision(IRCCommand): 40 def execute(self, args, tool ):40 def execute(self, args, tool, sheriff): 41 41 return view_source_url(tool.buildbot.last_green_revision()) 42 42 43 43 44 44 class Restart(IRCCommand): 45 def execute(self, args, tool ):45 def execute(self, args, tool, sheriff): 46 46 tool.irc().post("Restarting...") 47 47 raise TerminateQueue() 48 48 49 49 50 class Rollout(IRCCommand): 51 def execute(self, args, tool, sheriff): 52 if len(args) < 2: 53 tool.irc().post("Usage: SVN_REVISION REASON") 54 return 55 svn_revision = args[0] 56 rollout_reason = " ".join(args[1:]) 57 tool.irc().post("Preparing rollout for r%s..." % svn_revision) 58 try: 59 bug_id = sheriff.post_rollout_patch(svn_revision, rollout_reason) 60 bug_url = tool.bugs.bug_url_for_bug_id(bug_id) 61 tool.irc().post("Created rollout: %s" % bug_url) 62 except ScriptError, e: 63 tool.irc().post("Failed to create rollout patch:") 64 tool.irc().post("%s" % e) 65 66 50 67 class Hi(IRCCommand): 51 def execute(self, args, tool ):68 def execute(self, args, tool, sheriff): 52 69 return '"Only you can prevent forest fires." -- Smokey the Bear' -
trunk/WebKitTools/Scripts/webkitpy/tool/bot/sheriff_unittest.py
r56946 r56947 28 28 29 29 import os 30 import unittest 30 31 31 32 from webkitpy.common.net.buildbot import Builder 32 33 from webkitpy.thirdparty.mock import Mock 33 from webkitpy.tool.commands.queuestest import QueuesTest 34 from webkitpy.tool.commands.sheriffbot import SheriffBot 34 from webkitpy.tool.bot.sheriff import Sheriff 35 35 from webkitpy.tool.mocktool import MockTool, mock_builder 36 36 37 class SheriffBotTest(QueuesTest):38 def test_sheriff_bot(self):39 mock_work_item = {40 "svn_revision": 29837,41 "builders": [mock_builder]42 }43 expected_stderr = {44 "begin_work_queue": "CAUTION: sheriff-bot will discard all local changes in \"%s\"\nRunning WebKit sheriff-bot.\n" % os.getcwd(),45 "next_work_item": "",46 "process_work_item": "MOCK: irc.post: abarth, darin, eseidel: http://trac.webkit.org/changeset/29837 appears to have broken Mock builder name (Tests)\n",47 "handle_unexpected_error": "Mock error message\n"48 }49 self.assert_queue_outputs(SheriffBot(), work_item=mock_work_item, expected_stderr=expected_stderr)50 37 38 class MockSheriffBot(object): 39 def run_webkit_patch(self, args): 40 return "Created bug https://bugs.webkit.org/show_bug.cgi?id=36936\n" 41 42 43 class SheriffTest(unittest.TestCase): 51 44 def test_rollout_reason(self): 52 bot = SheriffBot()45 sheriff = Sheriff(MockTool(), MockSheriffBot()) 53 46 builders = [ 54 47 Builder("Foo", None), … … 56 49 ] 57 50 reason = "Caused builders Foo and Bar to fail." 58 self.assertEquals( bot._rollout_reason(builders), reason)51 self.assertEquals(sheriff._rollout_reason(builders), reason) 59 52 60 53 def test_post_blame_comment_on_bug(self): 61 bot = SheriffBot() 62 bot.tool = MockTool() 54 sheriff = Sheriff(MockTool(), MockSheriffBot()) 63 55 builders = [ 64 56 Builder("Foo", None), … … 66 58 ] 67 59 commit_info = Mock() 68 commit_info.bug_id = lambda: None69 commit_info.revision = lambda: 432160 commit_info.bug_id = lambda: None 61 commit_info.revision = lambda: 4321 70 62 # Should do nothing with no bug_id 71 bot._post_blame_comment_on_bug(commit_info, builders)63 sheriff.post_blame_comment_on_bug(commit_info, builders) 72 64 # Should try to post a comment to the bug, but MockTool.bugs does nothing. 73 commit_info.bug_id = lambda: 123474 bot._post_blame_comment_on_bug(commit_info, builders)65 commit_info.bug_id = lambda: 1234 66 sheriff.post_blame_comment_on_bug(commit_info, builders) -
trunk/WebKitTools/Scripts/webkitpy/tool/bot/sheriffircbot.py
r56883 r56947 33 33 34 34 35 class _IRCThreadTearoff( object):35 class _IRCThreadTearoff(IRCBotDelegate): 36 36 def __init__(self, password, message_queue, wakeup_event): 37 37 self._password = password … … 52 52 53 53 54 class SheriffIRCBot( IRCBotDelegate):54 class SheriffIRCBot(object): 55 55 # FIXME: Lame. We should have an auto-registering CommandCenter. 56 56 commands = { 57 57 "last-green-revision": irc_command.LastGreenRevision, 58 58 "restart": irc_command.Restart, 59 "rollout": irc_command.Rollout, 59 60 "hi": irc_command.Hi, 60 61 } 61 62 62 def __init__(self, tool ):63 def __init__(self, tool, sheriff): 63 64 self._tool = tool 65 self._sheriff = sheriff 64 66 self._message_queue = ThreadedMessageQueue() 65 67 66 68 def irc_delegate(self): 67 return _IRCThreadTearoff(self._tool.irc_password, self._message_queue, self._tool.wakeup_event) 69 return _IRCThreadTearoff(self._tool.irc_password, 70 self._message_queue, 71 self._tool.wakeup_event) 68 72 69 73 def process_message(self, message): … … 73 77 command = self.commands.get(tokenized_message[0]) 74 78 if not command: 75 self._tool.irc().post("Available commands: %s" % ", ".join(self.commands.keys())) 79 self._tool.irc().post( 80 "Available commands: %s" % ", ".join(self.commands.keys())) 76 81 return 77 response = command().execute(tokenized_message[1:], self._tool) 82 response = command().execute(tokenized_message[1:], 83 self._tool, 84 self._sheriff) 78 85 if response: 79 86 self._tool.irc().post(response) -
trunk/WebKitTools/Scripts/webkitpy/tool/bot/sheriffircbot_unittest.py
r56883 r56947 30 30 31 31 from webkitpy.common.system.outputcapture import OutputCapture 32 from webkitpy.tool.bot.sheriff import Sheriff 32 33 from webkitpy.tool.bot.sheriffircbot import SheriffIRCBot 34 from webkitpy.tool.bot.sheriff_unittest import MockSheriffBot 33 35 from webkitpy.tool.mocktool import MockTool 36 34 37 35 38 def run(message): 36 39 tool = MockTool() 37 40 tool.ensure_irc_connected(None) 38 bot = SheriffIRCBot(tool )41 bot = SheriffIRCBot(tool, Sheriff(tool, MockSheriffBot())) 39 42 bot._message_queue.post(message) 40 43 bot.process_pending_messages() … … 47 50 48 51 def test_bogus(self): 49 expected_stderr = "MOCK: irc.post: Available commands: hi, restart, last-green-revision\n"52 expected_stderr = "MOCK: irc.post: Available commands: rollout, hi, restart, last-green-revision\n" 50 53 OutputCapture().assert_outputs(self, run, args=["bogus"], expected_stderr=expected_stderr) 51 54 … … 53 56 expected_stderr = "MOCK: irc.post: http://trac.webkit.org/changeset/9479\n" 54 57 OutputCapture().assert_outputs(self, run, args=["last-green-revision"], expected_stderr=expected_stderr) 58 59 def test_rollout(self): 60 expected_stderr = "MOCK: irc.post: Preparing rollout for r21654...\nMOCK: irc.post: Created rollout: http://example.com/36936\n" 61 OutputCapture().assert_outputs(self, run, args=["rollout 21654 This patch broke the world"], expected_stderr=expected_stderr) 62 63 def test_rollout_bananas(self): 64 expected_stderr = "MOCK: irc.post: Usage: SVN_REVISION REASON\n" 65 OutputCapture().assert_outputs(self, run, args=["rollout bananas"], expected_stderr=expected_stderr) 66 67 def test_rollout_no_reason(self): 68 expected_stderr = "MOCK: irc.post: Usage: SVN_REVISION REASON\n" 69 OutputCapture().assert_outputs(self, run, args=["rollout 21654"], expected_stderr=expected_stderr) -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/queues.py
r56936 r56947 74 74 webkit_patch_args += ["--status-host=%s" % self.tool.status_server.host] 75 75 webkit_patch_args += map(str, args) 76 self.tool.executive.run_and_throw_if_fail(webkit_patch_args)76 return self.tool.executive.run_and_throw_if_fail(webkit_patch_args) 77 77 78 78 # QueueEngineDelegate methods -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py
r56936 r56947 30 30 31 31 from webkitpy.common.system.deprecated_logging import log 32 from webkitpy.common.checkout.changelog import view_source_url33 32 from webkitpy.common.config.ports import WebKitPort 33 from webkitpy.tool.bot.sheriff import Sheriff 34 34 from webkitpy.tool.bot.sheriffircbot import SheriffIRCBot 35 35 from webkitpy.tool.commands.queues import AbstractQueue 36 from webkitpy.tool.grammar import join_with_separators37 36 38 37 class SheriffBot(AbstractQueue): … … 46 45 def begin_work_queue(self): 47 46 AbstractQueue.begin_work_queue(self) 48 self._irc_bot = SheriffIRCBot(self.tool) 47 self._sheriff = Sheriff(self.tool, self) 48 self._irc_bot = SheriffIRCBot(self.tool, self._sheriff) 49 49 self.tool.ensure_irc_connected(self._irc_bot.irc_delegate()) 50 50 … … 63 63 "svn_revision": svn_revision, 64 64 "builders": builders, 65 # FIXME: _rollout_reason needs Build objects which we could pass here.65 # FIXME: Sheriff._rollout_reason needs Build objects which we could pass here. 66 66 } 67 67 return None … … 71 71 return True 72 72 73 # _post* methods should move onto some new class where they can share more logic and state.74 def _post_irc_warning(self, commit_info, builders):75 irc_nicknames = sorted([party.irc_nickname for party in commit_info.responsible_parties() if party.irc_nickname])76 irc_prefix = ": " if irc_nicknames else ""77 irc_message = "%s%s%s appears to have broken %s" % (78 ", ".join(irc_nicknames),79 irc_prefix,80 view_source_url(commit_info.revision()),81 join_with_separators([builder.name() for builder in builders]))82 83 self.tool.irc().post(irc_message)84 85 def _rollout_reason(self, builders):86 # FIXME: This should explain which layout tests failed87 # however, that would require Build objects here, either passed88 # in through failure_info, or through Builder.latest_build.89 builder_names = [builder.name() for builder in builders]90 return "Caused builders %s to fail." % join_with_separators(builder_names)91 92 def _post_rollout_patch(self, commit_info, rollout_reason):93 # For now we're only posting rollout patches for commit-queue'd patches.94 commit_bot_email = "eseidel@chromium.org"95 if commit_bot_email not in commit_info.committer().emails:96 return97 98 args = [99 "create-rollout",100 "--force-clean",101 "--non-interactive",102 "--parent-command=%s" % self.name,103 commit_info.revision(),104 self._rollout_reason(builders),105 ]106 try:107 self.run_webkit_patch(args)108 except:109 log("Failed to create-rollout.")110 111 def _post_blame_comment_on_bug(self, commit_info, builders):112 if not commit_info.bug_id():113 return114 comment = "%s appears to have broken %s" % (115 view_source_url(commit_info.revision()),116 join_with_separators([builder.name() for builder in builders]))117 self.tool.bugs.post_comment_to_bug(commit_info.bug_id(), comment)118 119 73 def process_work_item(self, failure_info): 120 74 svn_revision = failure_info["svn_revision"] … … 123 77 self.update() 124 78 commit_info = self.tool.checkout().commit_info_for_revision(svn_revision) 125 self._ post_irc_warning(commit_info, builders)126 self._ post_blame_comment_on_bug(commit_info, builders)127 self._ post_rollout_patch(commit_info, builders)79 self._sheriff.post_irc_warning(commit_info, builders) 80 self._sheriff.post_blame_comment_on_bug(commit_info, builders) 81 self._sheriff.post_automatic_rollout_patch(commit_info, builders) 128 82 129 83 for builder in builders: -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot_unittest.py
r56755 r56947 29 29 import os 30 30 31 from webkitpy.common.net.buildbot import Builder32 from webkitpy.thirdparty.mock import Mock33 31 from webkitpy.tool.commands.queuestest import QueuesTest 34 32 from webkitpy.tool.commands.sheriffbot import SheriffBot 35 from webkitpy.tool.mocktool import MockTool, mock_builder 33 from webkitpy.tool.mocktool import mock_builder 34 36 35 37 36 class SheriffBotTest(QueuesTest): … … 44 43 "begin_work_queue": "CAUTION: sheriff-bot will discard all local changes in \"%s\"\nRunning WebKit sheriff-bot.\n" % os.getcwd(), 45 44 "next_work_item": "", 46 "process_work_item": "MOCK: irc.post: abarth, darin, eseidel: http://trac.webkit.org/changeset/29837 appears tohave broken Mock builder name (Tests)\n",45 "process_work_item": "MOCK: irc.post: abarth, darin, eseidel: http://trac.webkit.org/changeset/29837 might have broken Mock builder name (Tests)\n", 47 46 "handle_unexpected_error": "Mock error message\n" 48 47 } 49 48 self.assert_queue_outputs(SheriffBot(), work_item=mock_work_item, expected_stderr=expected_stderr) 50 51 def test_rollout_reason(self):52 bot = SheriffBot()53 builders = [54 Builder("Foo", None),55 Builder("Bar", None),56 ]57 reason = "Caused builders Foo and Bar to fail."58 self.assertEquals(bot._rollout_reason(builders), reason)59 60 def test_post_blame_comment_on_bug(self):61 bot = SheriffBot()62 bot.tool = MockTool()63 builders = [64 Builder("Foo", None),65 Builder("Bar", None),66 ]67 commit_info = Mock()68 commit_info.bug_id = lambda:None69 commit_info.revision = lambda:432170 # Should do nothing with no bug_id71 bot._post_blame_comment_on_bug(commit_info, builders)72 # Should try to post a comment to the bug, but MockTool.bugs does nothing.73 commit_info.bug_id = lambda:123474 bot._post_blame_comment_on_bug(commit_info, builders)
Note: See TracChangeset
for help on using the changeset viewer.