Changeset 56233 in webkit


Ignore:
Timestamp:
Mar 19, 2010 2:44:25 AM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-03-19 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Second cut at SheriffBot
https://bugs.webkit.org/show_bug.cgi?id=36353

This patch should contain a complete SheriffBot that's capable of
saying reasonable things on IRC. I had to refactor the use of
CommitInfo to make the SheriffBot testable, but I did the minimum
necessary. We should grow webkitcheckout over time to contain the
knowledge of ChangeLogs from scm.

  • Scripts/webkitpy/commands/sheriffbot.py:
  • Scripts/webkitpy/commands/sheriffbot_unittest.py:
  • Scripts/webkitpy/mock_bugzillatool.py:
  • Scripts/webkitpy/patch/patcher.py:
  • Scripts/webkitpy/webkitcheckout.py: Added.
Location:
trunk/WebKitTools
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r56232 r56233  
     12010-03-19  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Second cut at SheriffBot
     6        https://bugs.webkit.org/show_bug.cgi?id=36353
     7
     8        This patch should contain a complete SheriffBot that's capable of
     9        saying reasonable things on IRC.  I had to refactor the use of
     10        CommitInfo to make the SheriffBot testable, but I did the minimum
     11        necessary.  We should grow webkitcheckout over time to contain the
     12        knowledge of ChangeLogs from scm.
     13
     14        * Scripts/webkitpy/commands/sheriffbot.py:
     15        * Scripts/webkitpy/commands/sheriffbot_unittest.py:
     16        * Scripts/webkitpy/mock_bugzillatool.py:
     17        * Scripts/webkitpy/patch/patcher.py:
     18        * Scripts/webkitpy/webkitcheckout.py: Added.
     19
    1202010-03-19  Adam Barth  <abarth@webkit.org>
    221
  • trunk/WebKitTools/Scripts/webkitpy/commands/sheriffbot.py

    r56181 r56233  
    3030
    3131from webkitpy.commands.queues import AbstractQueue
    32 from webkitpy.irc.ircproxy import IRCProxy
    3332from webkitpy.webkit_logging import log
    3433
     
    4342        self.tool.ensure_irc_connected()
    4443
    45     def work_item_log_path(self, svn_revision):
    46         return os.path.join("%s-logs" % self.name, "%s.log" % svn_revision)
     44    def work_item_log_path(self, failure_info):
     45        return os.path.join("%s-logs" % self.name, "%s.log" % failure_info["svn_revision"])
    4746
    4847    def next_work_item(self):
    49         # FIXME: Call methods that analyze the build bots.
    50         return None # FIXME: Should be an SVN revision number.
     48        for svn_revision, builders in self.tool.buildbot.revisions_causing_failures().items():
     49            if self.tool.status_server.svn_revision(svn_revision):
     50                continue
     51            return {
     52                "svn_revision": svn_revision,
     53                "builders": builders
     54            }
     55        return None
    5156
    52     def should_proceed_with_work_item(self, svn_revision):
     57    def should_proceed_with_work_item(self, failure_info):
    5358        # Currently, we don't have any reasons not to proceed with work items.
    5459        return True
    5560
    56     def process_work_item(self, svn_revision):
    57         message = "r%s appears to have broken the build." % svn_revision
    58         self.tool.irc().post(message)
    59         # FIXME: What if run_webkit_patch throws an exception?
    60         self.run_webkit_patch([
    61             "create-rollout",
    62             "--force-clean",
    63             "--non-interactive",
    64             "--parent-command=%s" % self.name,
    65             # FIXME: We also need to CC the reviewer, committer, and contributor.
    66             "--cc=%s" % ",".join(self.watchers),
    67             svn_revision
    68         ])
     61    def process_work_item(self, failure_info):
     62        svn_revision = failure_info["svn_revision"]
     63        builders = failure_info["builders"]
    6964
    70     def handle_unexpected_error(self, svn_revision, message):
     65        commit_info = self.tool.checkout().commit_info_for_revision(svn_revision)
     66        responsible_parties = [
     67            commit_info.committer(),
     68            commit_info.author(),
     69            commit_info.reviewer()
     70        ]
     71        irc_nicknames = sorted(set([party.irc_nickname for party in responsible_parties if party and party.irc_nickname]))
     72        irc_prefix = ": " if irc_nicknames else ""
     73        irc_message = "%s%sr%s appears to have broken %s" % (
     74            ", ".join(irc_nicknames),
     75            irc_prefix,
     76            svn_revision,
     77            ", ".join([builder.name() for builder in builders]))
     78
     79        self.tool.irc().post(irc_message)
     80
     81        for builder in builders:
     82            self.tool.status_server.update_svn_revision(svn_revision, builder.name())
     83
     84    def handle_unexpected_error(self, failure_info, message):
    7185        log(message)
  • trunk/WebKitTools/Scripts/webkitpy/commands/sheriffbot_unittest.py

    r56181 r56233  
    3131from webkitpy.commands.queuestest import QueuesTest
    3232from webkitpy.commands.sheriffbot import SheriffBot
    33 from webkitpy.mock_bugzillatool import MockBugzillaTool
     33from webkitpy.mock_bugzillatool import MockBugzillaTool, mock_builder
    3434
    3535class SheriffBotTest(QueuesTest):
    3636    def test_sheriff_bot(self):
     37        mock_work_item = {
     38            "svn_revision": 29837,
     39            "builders": [mock_builder]
     40        }
    3741        expected_stderr = {
    3842            "begin_work_queue": "CAUTION: sheriff-bot will discard all local changes in \"%s\"\nRunning WebKit sheriff-bot.\n" % os.getcwd(),
    3943            "next_work_item": "",
    40             "process_work_item": "MOCK: irc.post: r29837 appears to have broken the build.\n",
     44            "process_work_item": "MOCK: irc.post: abarth, darin, eseidel: r29837 appears to have broken Mock builder name (Tests)\n",
    4145            "handle_unexpected_error": "Mock error message\n"
    4246        }
    43         self.assert_queue_outputs(SheriffBot(), work_item=29837, expected_stderr=expected_stderr)
     47        self.assert_queue_outputs(SheriffBot(), work_item=mock_work_item, expected_stderr=expected_stderr)
  • trunk/WebKitTools/Scripts/webkitpy/mock_bugzillatool.py

    r56181 r56233  
    3030
    3131from webkitpy.bugzilla import Bug, Attachment
     32from webkitpy.commitinfo import CommitInfo
    3233from webkitpy.committers import CommitterList, Reviewer
    3334from webkitpy.scm import CommitMessage
     
    180181    "attachments": [_patch4, _patch5, _patch6],
    181182}
     183
     184
     185class MockBuilder(object):
     186
     187    def name(self):
     188        return "Mock builder name (Tests)"
     189
     190
     191mock_builder = MockBuilder()
    182192
    183193
     
    285295
    286296
    287 class MockBuildBot(Mock):
     297class MockBuildBot(object):
    288298
    289299    def __init__(self):
     
    307317        self._tree_is_on_fire = True
    308318
     319    def revisions_causing_failures(self):
     320        return {
     321            "29837": [mock_builder]
     322        }
    309323
    310324class MockSCM(Mock):
     
    354368
    355369
     370class MockWebKitCheckout(object):
     371
     372    def commit_info_for_revision(self, svn_revision):
     373        return CommitInfo(svn_revision, "eric@webkit.org", {
     374            "bug_id": 42,
     375            "author_name": "Adam Barth",
     376            "author_email": "abarth@webkit.org",
     377            "reviewer_text": "Darin Adler"
     378        })
     379
     380
    356381class MockUser(object):
    357382
     
    391416        return None
    392417
     418    def svn_revision(self, svn_revision):
     419        return None
     420
    393421    def update_status(self, queue_name, status, patch=None, results_file=None):
    394422        return 187
     423
     424    def update_svn_revision(self, svn_revision, broken_bot):
     425        return 191
    395426
    396427
     
    404435        self.user = MockUser()
    405436        self._scm = MockSCM()
     437        self._checkout = MockWebKitCheckout()
    406438        self.status_server = MockStatusServer()
    407439
    408440    def scm(self):
    409441        return self._scm
     442
     443    def checkout(self):
     444        return self._checkout
    410445
    411446    def ensure_irc_connected(self):
  • trunk/WebKitTools/Scripts/webkitpy/patch/patcher.py

    r56219 r56233  
    4242from webkitpy.executive import Executive
    4343from webkitpy.webkit_logging import log
     44from webkitpy.webkitcheckout import WebKitCheckout
    4445from webkitpy.multicommandtool import MultiCommandTool
    4546from webkitpy.scm import detect_scm_system
     
    6465        self.user = User()
    6566        self._scm = None
     67        self._checkout = None
    6668        self.status_server = StatusServer()
    6769
     
    8183
    8284        return self._scm
     85
     86    def checkout():
     87        if not self._checkout:
     88            self._checkout = WebKitCheckout(self.scm())
     89        return self._checkout
    8390
    8491    # FIXME: Add a parameter for nickname?
  • trunk/WebKitTools/Scripts/webkitpy/webkitcheckout.py

    r56232 r56233  
    1 # Copyright (C) 2010 Google Inc. All rights reserved.
    2 #
     1# Copyright (c) 2010 Google Inc. All rights reserved.
     2# 
    33# Redistribution and use in source and binary forms, with or without
    44# modification, are permitted provided that the following conditions are
    55# met:
    6 #
    7 #    * Redistributions of source code must retain the above copyright
     6# 
     7#     * Redistributions of source code must retain the above copyright
    88# notice, this list of conditions and the following disclaimer.
    9 #    * Redistributions in binary form must reproduce the above
     9#     * Redistributions in binary form must reproduce the above
    1010# copyright notice, this list of conditions and the following disclaimer
    1111# in the documentation and/or other materials provided with the
    1212# distribution.
    13 #    * Neither the name of Google Inc. nor the names of its
     13#     * Neither the name of Google Inc. nor the names of its
    1414# contributors may be used to endorse or promote products derived from
    1515# this software without specific prior written permission.
    16 #
     16# 
    1717# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1818# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     
    2727# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828
    29 import os
     29from webkitpy.commitinfo import CommitInfo
    3030
    31 from webkitpy.commands.queuestest import QueuesTest
    32 from webkitpy.commands.sheriffbot import SheriffBot
    33 from webkitpy.mock_bugzillatool import MockBugzillaTool
    3431
    35 class SheriffBotTest(QueuesTest):
    36     def test_sheriff_bot(self):
    37         expected_stderr = {
    38             "begin_work_queue": "CAUTION: sheriff-bot will discard all local changes in \"%s\"\nRunning WebKit sheriff-bot.\n" % os.getcwd(),
    39             "next_work_item": "",
    40             "process_work_item": "MOCK: irc.post: r29837 appears to have broken the build.\n",
    41             "handle_unexpected_error": "Mock error message\n"
    42         }
    43         self.assert_queue_outputs(SheriffBot(), work_item=29837, expected_stderr=expected_stderr)
     32# This class represents the WebKit-specific parts of the checkout (like
     33# ChangeLogs).
     34# FIXME: Move a bunch of ChangeLog-specific processing from SCM to this object.
     35class WebKitCheckout(object):
     36    def __init__(self, scm):
     37        self._scm = scm
     38
     39    def commit_info_for_revision(self, svn_revision):
     40        return CommitInfo.commit_info_for_revision(self._scm, svn_revision)
Note: See TracChangeset for help on using the changeset viewer.