#!/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.
"""Contains functions for parsing the build master's transposed grid page.
Compatible with build bot 0.8.4 P1.
"""
import re
import urllib
# 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
successful
exception
slave
lost'
class FailedToParseBuildStatus(Exception):
pass
def _map_status(status):
if status == 'exception' or status == BB_084_P1_BUGGY_STATUS:
return 'failed'
return status
def _parse_builds(revision, html):
"""Parses the bot list, which is a sequence of
| lines.
See contract for parse_tgrid_page for more information on how this function
behaves.
Example input:
OK |
The first regular expression group captures Android, second 119, third OK.
"""
result = {}
for match in re.finditer('.*?'
'(OK|failed|building|warnings|exception|' +
BB_084_P1_BUGGY_STATUS + ')'
'.*?.*?',
html, re.DOTALL):
revision_and_bot_name = revision + "--" + urllib.unquote(match.group(1))
build_number_and_status = match.group(2) + "--" + _map_status(
match.group(3))
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:
1568 |
LIST OF BOTS
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 -- mapped to
--, where status is either OK, failed,
building or warnings. The status may be 'exception' in the input, but
we simply map that to failed.
"""
result = {}
for match in re.finditer('(\d+).*?(.*?)',
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:
raise FailedToParseBuildStatus('Could not find any build statuses in %s.' %
html)
return result