Changeset 104729 in webkit


Ignore:
Timestamp:
Jan 11, 2012 11:53:00 AM (12 years ago)
Author:
rniwa@webkit.org
Message:

last-green-revision should give us per-bot information
https://bugs.webkit.org/show_bug.cgi?id=76011

Reviewed by Adam Barth.

Rewrote last-green-revision command. Instead of finding a revision for which all bots succeeded,
we report the latest green run on each bot from the last 100 runs.

  • Scripts/webkitpy/common/net/buildbot/buildbot.py:

(BuildBot._fetch_builder_page):
(BuildBot):
(BuildBot._green_revision_for_builder):
(BuildBot.last_green_revision):

  • Scripts/webkitpy/common/net/buildbot/buildbot_unittest.py:

(test_green_revision_for_builder):
(test_last_green_revision):

  • Scripts/webkitpy/tool/bot/irc_command.py:

(LastGreenRevision.execute):

  • Scripts/webkitpy/tool/commands/queries.py:

(LastGreenRevision.execute):

Location:
trunk/Tools
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r104725 r104729  
     12012-01-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        last-green-revision should give us per-bot information
     4        https://bugs.webkit.org/show_bug.cgi?id=76011
     5
     6        Reviewed by Adam Barth.
     7
     8        Rewrote last-green-revision command. Instead of finding a revision for which all bots succeeded,
     9        we report the latest green run on each bot from the last 100 runs.
     10
     11        * Scripts/webkitpy/common/net/buildbot/buildbot.py:
     12        (BuildBot._fetch_builder_page):
     13        (BuildBot):
     14        (BuildBot._green_revision_for_builder):
     15        (BuildBot.last_green_revision):
     16        * Scripts/webkitpy/common/net/buildbot/buildbot_unittest.py:
     17        (test_green_revision_for_builder):
     18        (test_last_green_revision):
     19        * Scripts/webkitpy/tool/bot/irc_command.py:
     20        (LastGreenRevision.execute):
     21        * Scripts/webkitpy/tool/commands/queries.py:
     22        (LastGreenRevision.execute):
     23
    1242012-01-11  Dirk Pranke  <dpranke@chromium.org>
    225
  • trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py

    r104417 r104729  
    433433            build = build.previous_build()
    434434
    435     def last_green_revision(self):
    436         builds = self._latest_builds_from_builders()
    437         target_revision = builds[0].revision()
    438         # An alternate way to do this would be to start at one revision and walk backwards
    439         # checking builder.build_for_revision, however build_for_revision is very slow on first load.
    440         while True:
    441             # Make builds agree on revision
    442             builds = [self._build_at_or_before_revision(build, target_revision) for build in builds]
    443             if None in builds: # One of the builds failed to load from the server.
    444                 return None
    445             min_revision = min(map(lambda build: build.revision(), builds))
    446             if min_revision != target_revision:
    447                 target_revision = min_revision
    448                 continue # Builds don't all agree on revision, keep searching
    449             # Check to make sure they're all green
    450             all_are_green = reduce(operator.and_, map(lambda build: build.is_green(), builds))
    451             if not all_are_green:
    452                 target_revision -= 1
     435    def _fetch_builder_page(self, builder):
     436        builder_page_url = "%s/builders/%s?numbuilds=100" % (self.buildbot_url, urllib2.quote(builder.name()))
     437        return urllib2.urlopen(builder_page_url)
     438
     439    def _green_revision_for_builder(self, builder):
     440        soup = BeautifulSoup(self._fetch_builder_page(builder))
     441        revision = None
     442        number_of_revisions = 0
     443        for status_row in soup.find('table').findAll('tr'):
     444            revision_anchor = status_row.find('a')
     445            table_cells = status_row.findAll('td')
     446            if not revision_anchor or not table_cells or len(table_cells) < 3 or not table_cells[2].string:
    453447                continue
    454             return min_revision
     448            number_of_revisions += 1
     449            if revision == None and 'success' in table_cells[2].string:
     450                revision = int(revision_anchor.string)
     451        return revision, number_of_revisions
     452
     453    def last_green_revision(self, builder_name_regex):
     454        compiled_builder_name_regex = re.compile(builder_name_regex, flags=re.IGNORECASE)
     455        builders = [builder for builder in self.builders() if compiled_builder_name_regex.search(builder.name())]
     456        if len(builders) > 10:
     457            return '"%s" matches too many bots' % builder_name_regex
     458        elif not len(builders):
     459            return '"%s" doesn\'t match any bot' % builder_name_regex
     460
     461        result = ''
     462        for builder in builders:
     463            revision, number_of_revisions = self._green_revision_for_builder(builder)
     464            if revision == None:
     465                result += '%s has had no green revision in the last %d runs' % (builder.name(), number_of_revisions)
     466            else:
     467                result += '%s: %d' % (builder.name(), revision)
     468            result += "\n"
     469
     470        return result
  • trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot_mock.py

    r104417 r104729  
    9191        ]
    9292
    93     def last_green_revision(self):
    94         return 9479
     93    def last_green_revision(self, builder_name):
     94        return builder_name + ': ' + str(9479)
    9595
    9696    def light_tree_on_fire(self):
  • trunk/Tools/Scripts/webkitpy/common/net/buildbot/buildbot_unittest.py

    r104417 r104729  
    300300        self.assertEqual(self._expected_files, files)
    301301
    302     # Revision, is_green
    303     # Ordered from newest (highest number) to oldest.
    304     fake_builder1 = [
    305         [2, False],
    306         [1, True],
    307     ]
    308     fake_builder2 = [
    309         [2, False],
    310         [1, True],
    311     ]
    312     fake_builders = [
    313         fake_builder1,
    314         fake_builder2,
    315     ]
    316     def _build_from_fake(self, fake_builder, index):
    317         if index >= len(fake_builder):
    318             return None
    319         fake_build = fake_builder[index]
    320         build = Build(
    321             builder=fake_builder,
    322             build_number=index,
    323             revision=fake_build[0],
    324             is_green=fake_build[1],
    325         )
    326         def mock_previous_build():
    327             return self._build_from_fake(fake_builder, index + 1)
    328         build.previous_build = mock_previous_build
    329         return build
    330 
    331     def _fake_builds_at_index(self, index):
    332         return [self._build_from_fake(builder, index) for builder in self.fake_builders]
     302    _fake_builder_page = '''
     303    <body>
     304    <div class="content">
     305    <h1>Some Builder</h1>
     306    <p>(<a href="../waterfall?show=Some Builder">view in waterfall</a>)</p>
     307    <div class="column">
     308    <h2>Recent Builds:</h2>
     309    <table class="info">
     310      <tr>
     311        <th>Time</th>
     312        <th>Revision</th>
     313        <th>Result</th>    <th>Build #</th>
     314        <th>Info</th>
     315      </tr>
     316      <tr class="alt">
     317        <td>Jan 10 15:49</td>
     318        <td><span class="revision" title="Revision 104643"><a href="http://trac.webkit.org/changeset/104643">104643</a></span></td>
     319        <td class="success">failure</td>    <td><a href=".../37604">#37604</a></td>
     320        <td class="left">Build successful</td>
     321      </tr>
     322      <tr class="">
     323        <td>Jan 10 15:32</td>
     324        <td><span class="revision" title="Revision 104636"><a href="http://trac.webkit.org/changeset/104636">104636</a></span></td>
     325        <td class="success">failure</td>    <td><a href=".../37603">#37603</a></td>
     326        <td class="left">Build successful</td>
     327      </tr>
     328      <tr class="alt">
     329        <td>Jan 10 15:18</td>
     330        <td><span class="revision" title="Revision 104635"><a href="http://trac.webkit.org/changeset/104635">104635</a></span></td>
     331        <td class="success">success</td>    <td><a href=".../37602">#37602</a></td>
     332        <td class="left">Build successful</td>
     333      </tr>
     334      <tr class="">
     335        <td>Jan 10 14:51</td>
     336        <td><span class="revision" title="Revision 104633"><a href="http://trac.webkit.org/changeset/104633">104633</a></span></td>
     337        <td class="failure">failure</td>    <td><a href=".../37601">#37601</a></td>
     338        <td class="left">Failed compile-webkit</td>
     339      </tr>
     340    </table>
     341    </body>'''
     342    _fake_builder_page_without_success = '''
     343    <body>
     344    <table>
     345      <tr class="alt">
     346        <td>Jan 10 15:49</td>
     347        <td><span class="revision" title="Revision 104643"><a href="http://trac.webkit.org/changeset/104643">104643</a></span></td>
     348        <td class="success">failure</td>
     349      </tr>
     350      <tr class="">
     351        <td>Jan 10 15:32</td>
     352        <td><span class="revision" title="Revision 104636"><a href="http://trac.webkit.org/changeset/104636">104636</a></span></td>
     353        <td class="success">failure</td>
     354      </tr>
     355      <tr class="alt">
     356        <td>Jan 10 15:18</td>
     357        <td><span class="revision" title="Revision 104635"><a href="http://trac.webkit.org/changeset/104635">104635</a></span></td>
     358        <td class="success">failure</td>
     359      </tr>
     360      <tr class="">
     361        <td>Jan 10 14:51</td>
     362        <td><span class="revision" title="Revision 104633"><a href="http://trac.webkit.org/changeset/104633">104633</a></span></td>
     363        <td class="failure">failure</td>
     364      </tr>
     365    </table>
     366    </body>'''
     367
     368    def test_green_revision_for_builder(self):
     369        buildbot = BuildBot()
     370        buildbot._fetch_builder_page = lambda builder: builder.page
     371        builder_with_success = Builder('Some builder', None)
     372        builder_with_success.page = self._fake_builder_page
     373        self.assertEqual(buildbot._green_revision_for_builder(builder_with_success), (104635, 4))
     374
     375        builder_without_success = Builder('Some builder', None)
     376        builder_without_success.page = self._fake_builder_page_without_success
     377        self.assertEqual(buildbot._green_revision_for_builder(builder_without_success), (None, 4))
    333378
    334379    def test_last_green_revision(self):
     
    338383            return self._fake_builds_at_index(0)
    339384
     385        # Revision, is_green
     386        # Ordered from newest (highest number) to oldest.
     387        fake_builder1 = Builder("Fake Builder 1", None)
     388        fake_builder1.revision = 1234
     389        fake_builder1.revision_count = 3
     390        fake_builder2 = Builder("Fake Builder 2", None)
     391        fake_builder2.revision = 1230
     392        fake_builder2.revision_count = 4
     393        some_builder = Builder("Some Builder", None)
     394        some_builder.revision = None
     395        some_builder.revision_count = 3
     396
     397        buildbot.builders = lambda: [fake_builder1, fake_builder2, some_builder]
     398        buildbot._green_revision_for_builder = lambda builder: (builder.revision, builder.revision_count)
    340399        buildbot._latest_builds_from_builders = mock_builds_from_builders
    341         self.assertEqual(buildbot.last_green_revision(), 1)
     400        self.assertEqual(buildbot.last_green_revision(''),
     401            "Fake Builder 1: 1234\nFake Builder 2: 1230\nSome Builder has had no green revision in the last 3 runs\n")
    342402
    343403    def _fetch_build(self, build_number):
  • trunk/Tools/Scripts/webkitpy/tool/bot/irc_command.py

    r98315 r104729  
    5656class LastGreenRevision(IRCCommand):
    5757    def execute(self, nick, args, tool, sheriff):
    58         return "%s: %s" % (nick,
    59             urls.view_revision_url(tool.buildbot.last_green_revision()))
     58        if not args:
     59            return "%s: Usage: last-green-revision BUILDER_NAME" % nick
     60        return "%s: %s" % (nick, tool.buildbot.last_green_revision(args[0]))
    6061
    6162
  • trunk/Tools/Scripts/webkitpy/tool/bot/sheriffircbot_unittest.py

    r97198 r104729  
    8787
    8888    def test_lgr(self):
    89         expected_stderr = "MOCK: irc.post: mock_nick: http://trac.webkit.org/changeset/9479\n"
    90         OutputCapture().assert_outputs(self, run, args=["last-green-revision"], expected_stderr=expected_stderr)
     89        expected_stderr = "MOCK: irc.post: mock_nick: Builder: 9479\n"
     90        OutputCapture().assert_outputs(self, run, args=["last-green-revision Builder"], expected_stderr=expected_stderr)
    9191
    9292    def test_restart(self):
  • trunk/Tools/Scripts/webkitpy/tool/commands/queries.py

    r102163 r104729  
    133133
    134134    def execute(self, options, args, tool):
    135         print self._tool.buildbot.last_green_revision()
     135        print self._tool.buildbot.last_green_revision(args[0])
    136136
    137137
Note: See TracChangeset for help on using the changeset viewer.