2012-02-01 18:08:03 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
|
|
#
|
|
|
|
# Use of this source code is governed by a BSD-style license
|
|
|
|
# that can be found in the LICENSE file in the root of the source
|
|
|
|
# tree. An additional intellectual property rights grant can be found
|
|
|
|
# in the file PATENTS. All contributing project authors may
|
|
|
|
# be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
2012-04-17 10:49:10 +02:00
|
|
|
"""Contains functions for parsing the build master's transposed grid page.
|
|
|
|
|
|
|
|
Compatible with build bot 0.8.4 P1.
|
|
|
|
"""
|
2012-02-01 18:08:03 +01:00
|
|
|
|
|
|
|
__author__ = 'phoglund@webrtc.org (Patrik Höglund)'
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
2012-04-17 10:49:10 +02:00
|
|
|
# This is here to work around a buggy build bot status message which makes no
|
|
|
|
# sense, but which means the build failed when the slave was lost.
|
|
|
|
BB_084_P1_BUGGY_STATUS = 'build<br/>successful<br/>exception<br/>slave<br/>lost'
|
|
|
|
|
|
|
|
|
2012-02-01 18:08:03 +01:00
|
|
|
class FailedToParseBuildStatus(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2012-03-02 13:37:28 +01:00
|
|
|
def _map_status(status):
|
2012-04-17 10:49:10 +02:00
|
|
|
if status == 'exception' or status == BB_084_P1_BUGGY_STATUS:
|
2012-03-02 13:37:28 +01:00
|
|
|
return 'failed'
|
|
|
|
return status
|
|
|
|
|
|
|
|
|
2012-02-01 18:08:03 +01:00
|
|
|
def _parse_builds(revision, html):
|
|
|
|
"""Parses the bot list, which is a sequence of <td></td> lines.
|
|
|
|
|
2012-03-02 13:37:28 +01:00
|
|
|
See contract for parse_tgrid_page for more information on how this function
|
|
|
|
behaves.
|
|
|
|
|
2012-02-01 18:08:03 +01:00
|
|
|
Example input:
|
|
|
|
<td class="build success"><a href="builders/Android/builds/119">OK</a></td>
|
|
|
|
The first regular expression group captures Android, second 119, third OK.
|
|
|
|
"""
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
for match in re.finditer('<td.*?>.*?<a href="builders/(.+?)/builds/(\d+)">'
|
2012-04-17 10:49:10 +02:00
|
|
|
'(OK|failed|building|warnings|exception|' +
|
|
|
|
BB_084_P1_BUGGY_STATUS + ')'
|
|
|
|
'.*?</a>.*?</td>',
|
2012-02-27 16:42:25 +01:00
|
|
|
html, re.DOTALL):
|
2012-02-01 18:08:03 +01:00
|
|
|
revision_and_bot_name = revision + "--" + match.group(1)
|
2012-03-02 13:37:28 +01:00
|
|
|
build_number_and_status = match.group(2) + "--" + _map_status(
|
|
|
|
match.group(3))
|
2012-02-01 18:08:03 +01:00
|
|
|
|
|
|
|
result[revision_and_bot_name] = build_number_and_status
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def parse_tgrid_page(html):
|
|
|
|
"""Parses the build master's tgrid page.
|
|
|
|
|
|
|
|
Example input:
|
|
|
|
<tr>
|
|
|
|
<td valign="bottom" class="sourcestamp">1568</td>
|
|
|
|
LIST OF BOTS
|
|
|
|
</tr>
|
|
|
|
The first regular expression group captures 1568, second group captures
|
|
|
|
everything in LIST OF BOTS. The list of bots is then passed into a
|
|
|
|
separate function for parsing.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
html: The raw HTML from the tgrid page.
|
|
|
|
|
|
|
|
Returns: A dictionary with <svn revision>--<bot name> mapped to
|
2012-02-27 16:42:25 +01:00
|
|
|
<bot build number>--<status>, where status is either OK, failed,
|
2012-03-02 13:37:28 +01:00
|
|
|
building or warnings. The status may be 'exception' in the input, but
|
|
|
|
we simply map that to failed.
|
2012-02-01 18:08:03 +01:00
|
|
|
"""
|
|
|
|
result = {}
|
|
|
|
|
2012-05-16 11:05:57 +02:00
|
|
|
for match in re.finditer('<td.*?class="sourcestamp">(\d+).*?</td>(.*?)</tr>',
|
2012-02-01 18:08:03 +01:00
|
|
|
html, re.DOTALL):
|
|
|
|
revision = match.group(1)
|
|
|
|
builds_for_revision_html = match.group(2)
|
|
|
|
result.update(_parse_builds(revision, builds_for_revision_html))
|
|
|
|
|
|
|
|
if not result:
|
2012-02-06 11:55:12 +01:00
|
|
|
raise FailedToParseBuildStatus('Could not find any build statuses in %s.' %
|
|
|
|
html)
|
2012-02-01 18:08:03 +01:00
|
|
|
|
|
|
|
return result
|