Changeset 57125 in webkit


Ignore:
Timestamp:
Apr 5, 2010 10:52:51 PM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-04-05 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

SheriffBot should force_build builders that are idle and have failed exactly once
https://bugs.webkit.org/show_bug.cgi?id=37059

We can get into a deadlocked state where the commit-queue is stopped
because the builders are red but the SheriffBot hasn't taken action
because the builder has failed only once. The SheriffBot should force
build idle builders that have failed exactly once to either turn the
tree green again (if the test was flaky) or trigger the "failed twice"
remedies (IRC and bug posts).

  • Scripts/webkitpy/common/net/buildbot.py:
  • Scripts/webkitpy/tool/bot/sheriff.py:
  • Scripts/webkitpy/tool/bot/sheriff_unittest.py:
  • Scripts/webkitpy/tool/commands/sheriffbot.py:
  • Scripts/webkitpy/tool/mocktool.py:
Location:
trunk/WebKitTools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r57119 r57125  
     12010-04-05  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        SheriffBot should force_build builders that are idle and have failed exactly once
     6        https://bugs.webkit.org/show_bug.cgi?id=37059
     7
     8        We can get into a deadlocked state where the commit-queue is stopped
     9        because the builders are red but the SheriffBot hasn't taken action
     10        because the builder has failed only once.  The SheriffBot should force
     11        build idle builders that have failed exactly once to either turn the
     12        tree green again (if the test was flaky) or trigger the "failed twice"
     13        remedies (IRC and bug posts).
     14
     15        * Scripts/webkitpy/common/net/buildbot.py:
     16        * Scripts/webkitpy/tool/bot/sheriff.py:
     17        * Scripts/webkitpy/tool/bot/sheriff_unittest.py:
     18        * Scripts/webkitpy/tool/commands/sheriffbot.py:
     19        * Scripts/webkitpy/tool/mocktool.py:
     20
    1212010-04-05  Chris Jerdonek  <cjerdonek@webkit.org>
    222
  • trunk/WebKitTools/Scripts/webkitpy/common/net/buildbot.py

    r57065 r57125  
    370370        return [builder["name"] for builder in self.red_core_builders()]
    371371
     372    def idle_red_core_builders(self):
     373        return [builder for builder in self.red_core_builders() if builder["activity"] == "idle"]
     374
    372375    def core_builders_are_green(self):
    373376        return not self.red_core_builders()
  • trunk/WebKitTools/Scripts/webkitpy/tool/bot/sheriff.py

    r57115 r57125  
    108108                                            comment,
    109109                                            cc=self._sheriffbot.watchers)
     110
     111    # FIXME: Should some of this logic be on BuildBot?
     112    def provoke_flaky_builders(self, revisions_causing_failures):
     113        # We force_build builders that are red but have not "failed" (i.e.,
     114        # been red twice). We do this to avoid a deadlock situation where a
     115        # flaky test blocks the commit-queue and there aren't any other
     116        # patches being landed to re-spin the builder.
     117        failed_builders = sum([revisions_causing_failures[key] for
     118                               key in revisions_causing_failures.keys()], [])
     119        failed_builder_names = \
     120            set([builder.name() for builder in failed_builders])
     121        idle_red_builder_names = \
     122            set([builder["name"]
     123                 for builder in self._tool.buildbot.idle_red_core_builders()])
     124
     125        # We only want to provoke these builders if they are idle and have not
     126        # yet "failed" (i.e., been red twice) to avoid overloading the bots.
     127        flaky_builder_names = idle_red_builder_names - failed_builder_names
     128
     129        for name in flaky_builder_names:
     130            flaky_builder = self._tool.buildbot.builder_with_name(name)
     131            flaky_builder.force_build(username=self._sheriffbot.name,
     132                                      comments="Probe for flakiness.")
  • trunk/WebKitTools/Scripts/webkitpy/tool/bot/sheriff_unittest.py

    r57115 r57125  
    3838
    3939class MockSheriffBot(object):
     40    name = "mock-sheriff-bot"
    4041    watchers = [
    4142        "watcher@example.com",
     
    7778        expected_stderr = u"MOCK bug comment: bug_id=1234, cc=['watcher@example.com']\n--- Begin comment ---\\http://trac.webkit.org/changeset/4321 might have broken Foo and Bar\n--- End comment ---\n\nMOCK bug comment: bug_id=1234, cc=['watcher@example.com']\n--- Begin comment ---\\http://trac.webkit.org/changeset/4321 might have broken Foo and Bar\n--- End comment ---\n\nMOCK bug comment: bug_id=1234, cc=['watcher@example.com']\n--- Begin comment ---\\http://trac.webkit.org/changeset/4321 might have broken Foo and Bar\nThe following changes are on the blame list:\nhttp://trac.webkit.org/changeset/841\nhttp://trac.webkit.org/changeset/5646\n--- End comment ---\n\n"
    7879        OutputCapture().assert_outputs(self, run, expected_stderr=expected_stderr)
     80
     81    def test_provoke_flaky_builders(self):
     82        def run():
     83            tool = MockTool()
     84            tool.buildbot.light_tree_on_fire()
     85            sheriff = Sheriff(tool, MockSheriffBot())
     86            revisions_causing_failures = {}
     87            sheriff.provoke_flaky_builders(revisions_causing_failures)
     88        expected_stderr = "MOCK: force_build: name=Builder2, username=mock-sheriff-bot, comments=Probe for flakiness.\n"
     89        OutputCapture().assert_outputs(self, run, expected_stderr=expected_stderr)
  • trunk/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py

    r57115 r57125  
    6262        self._update()
    6363        new_failures = {}
    64         for svn_revision, builders in self.tool.buildbot.revisions_causing_failures().items():
     64        revisions_causing_failures = self.tool.buildbot.revisions_causing_failures()
     65        for svn_revision, builders in revisions_causing_failures.items():
    6566            if self.tool.status_server.svn_revision(svn_revision):
    6667                # FIXME: We should re-process the work item after some time delay.
     
    6869                continue
    6970            new_failures[svn_revision] = builders
     71        self._sheriff.provoke_flaky_builders(revisions_causing_failures)
    7072        return new_failures
    7173
  • trunk/WebKitTools/Scripts/webkitpy/tool/mocktool.py

    r57115 r57125  
    297297
    298298
     299class MockBuilder(object):
     300    def __init__(self, name):
     301        self._name = name
     302
     303    def force_build(self, username, comments):
     304        log("MOCK: force_build: name=%s, username=%s, comments=%s" % (
     305            self._name, username, comments))
     306
     307
    299308class MockBuildBot(object):
    300 
    301309    def __init__(self):
    302         self._tree_is_on_fire = False
    303 
    304     def builder_statuses(self):
    305         return [{
     310        self._mock_builder1_status = {
    306311            "name": "Builder1",
    307312            "is_green": True,
    308         }, {
     313            "activity": "building",
     314        }
     315        self._mock_builder2_status = {
    309316            "name": "Builder2",
    310             "is_green": not self._tree_is_on_fire,
    311         }]
     317            "is_green": True,
     318            "activity": "idle",
     319        }
     320
     321    def builder_with_name(self, name):
     322        return MockBuilder(name)
     323
     324    def builder_statuses(self):
     325        return [
     326            self._mock_builder1_status,
     327            self._mock_builder2_status,
     328        ]
    312329
    313330    def red_core_builders_names(self):
    314         if self._tree_is_on_fire:
    315             return "Builder2"
     331        if not self._mock_builder2_status["is_green"]:
     332            return [self._mock_builder2_status["name"]]
     333        return []
     334
     335    def red_core_builders(self):
     336        if not self._mock_builder2_status["is_green"]:
     337            return [self._mock_builder2_status]
     338        return []
     339
     340    def idle_red_core_builders(self):
     341        if not self._mock_builder2_status["is_green"]:
     342            return [self._mock_builder2_status]
    316343        return []
    317344
     
    320347
    321348    def light_tree_on_fire(self):
    322         self._tree_is_on_fire = True
     349        self._mock_builder2_status["is_green"] = False
    323350
    324351    def revisions_causing_failures(self):
Note: See TracChangeset for help on using the changeset viewer.