Initial version of code coverage tracker / dashboard for WebRTC.
BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/350001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1440 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
121
tools/coverage/track_coverage.py
Executable file
121
tools/coverage/track_coverage.py
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/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.
|
||||
|
||||
"""This script grabs and reports coverage information.
|
||||
|
||||
It grabs coverage information from the latest Linux 32-bit build and
|
||||
pushes it to the coverage tracker, enabling us to track code coverage
|
||||
over time. This script is intended to run on the 32-bit Linux slave.
|
||||
"""
|
||||
|
||||
__author__ = 'phoglund@webrtc.org (Patrik Höglund)'
|
||||
|
||||
import httplib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
# The build-bot user which runs build bot jobs.
|
||||
BUILD_BOT_USER = 'phoglund'
|
||||
|
||||
# The server to send coverage data to.
|
||||
# TODO(phoglund): replace with real server once we get it up.
|
||||
DASHBOARD_SERVER = 'localhost:8080'
|
||||
|
||||
|
||||
class FailedToParseCoverageHtml(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FailedToReportToDashboard(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def _find_latest_32bit_debug_build(www_directory_contents):
|
||||
# Build directories have the form Linux32bitDebug_<number>. There may be other
|
||||
# directories in the list though, for instance for other build configurations.
|
||||
# This sort ensures we will encounter the directory with the highest number
|
||||
# first.
|
||||
www_directory_contents.sort(reverse=True)
|
||||
|
||||
for entry in www_directory_contents:
|
||||
match = re.match('Linux32bitDBG_\d+', entry)
|
||||
if match is not None:
|
||||
return entry
|
||||
|
||||
# Didn't find it
|
||||
return None
|
||||
|
||||
|
||||
def _grab_coverage_percentage(label, index_html_contents):
|
||||
"""Extracts coverage from a LCOV coverage report.
|
||||
|
||||
Grabs coverage by assuming that the label in the coverage HTML report
|
||||
is close to the actual number and that the number is followed by a space
|
||||
and a percentage sign.
|
||||
"""
|
||||
match = re.search('<td[^>]*>' + label + '</td>.*?(\d+\.\d) %',
|
||||
index_html_contents, re.DOTALL)
|
||||
if match is None:
|
||||
raise FailedToParseCoverageHtml('Missing coverage at label "%s".' % label)
|
||||
|
||||
try:
|
||||
return float(match.group(1))
|
||||
except ValueError:
|
||||
raise FailedToParseCoverageHtml('%s is not a float.' % match.group(1))
|
||||
|
||||
|
||||
def _report_coverage_to_dashboard(now, line_coverage, function_coverage):
|
||||
request_string = ('/add_coverage_data?'
|
||||
'date=%d&line_coverage=%f&function_coverage=%f' %
|
||||
(now, line_coverage, function_coverage))
|
||||
|
||||
connection = httplib.HTTPConnection(DASHBOARD_SERVER)
|
||||
connection.request('GET', request_string)
|
||||
response = connection.getresponse()
|
||||
if response.status != 200:
|
||||
message = ('Error: Failed to report to %s%s: got response %d (%s)' %
|
||||
(DASHBOARD_SERVER, request_string, response.status,
|
||||
response.reason))
|
||||
raise FailedToReportToDashboard(message)
|
||||
|
||||
# The response content should be empty on success, so check that:
|
||||
response_content = response.read()
|
||||
if response_content:
|
||||
message = ('Error: Dashboard reported the following error: %s.' %
|
||||
response_content)
|
||||
raise FailedToReportToDashboard(message)
|
||||
|
||||
|
||||
def _main():
|
||||
coverage_www_dir = os.path.join('/home', BUILD_BOT_USER, 'www')
|
||||
|
||||
www_dir_contents = os.listdir(coverage_www_dir)
|
||||
latest_build_directory = _find_latest_32bit_debug_build(www_dir_contents)
|
||||
|
||||
if latest_build_directory is None:
|
||||
print 'Error: Found no 32-bit debug build in directory ' + coverage_www_dir
|
||||
sys.exit(1)
|
||||
|
||||
index_html_path = os.path.join(coverage_www_dir, latest_build_directory,
|
||||
'index.html')
|
||||
index_html_file = open(index_html_path)
|
||||
whole_file = index_html_file.read()
|
||||
|
||||
line_coverage = _grab_coverage_percentage('Lines:', whole_file)
|
||||
function_coverage = _grab_coverage_percentage('Functions:', whole_file)
|
||||
now = int(time.time())
|
||||
|
||||
_report_coverage_to_dashboard(now, line_coverage, function_coverage)
|
||||
|
||||
if __name__ == '__main__':
|
||||
_main()
|
||||
|
||||
Reference in New Issue
Block a user