173 lines
6.0 KiB
Python
173 lines
6.0 KiB
Python
import os
|
|
import sys
|
|
from textwrap import dedent
|
|
from bs4 import BeautifulSoup
|
|
import multiprocessing
|
|
|
|
|
|
FIRST = dedent(
|
|
'''<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
|
<title>CMS Python Test Coverage Report</title>
|
|
<link rel='stylesheet' href='https://googledrive.com/host/0B0bNP036USIkLWdyRFFlSDNzZHc/style.css' type='text/css'>
|
|
|
|
<script type='text/javascript' src='https://googledrive.com/host/0B0bNP036USIkLWdyRFFlSDNzZHc/jquery.min.js'></script>
|
|
<script type='text/javascript' src='https://googledrive.com/host/0B0bNP036USIkLWdyRFFlSDNzZHc/jquery.tablesorter.min.js'></script>
|
|
<script type='text/javascript' src='https://googledrive.com/host/0B0bNP036USIkLWdyRFFlSDNzZHc/jquery.hotkeys.js'></script>
|
|
<script type='text/javascript' src='https://googledrive.com/host/0B0bNP036USIkLWdyRFFlSDNzZHc/coverage_html.js'></script>
|
|
<script type='text/javascript' charset='utf-8'>
|
|
jQuery(document).ready(coverage.index_ready);
|
|
</script>
|
|
<style>
|
|
.hide-content {
|
|
display: none;
|
|
}
|
|
</style>
|
|
</head>''')
|
|
|
|
|
|
LAST = dedent(
|
|
'''<script type="text/javascript">
|
|
String.prototype.replaceAll = function (find, replace) {
|
|
var str = this;
|
|
return str.replace(new RegExp(find, 'g'), replace);
|
|
};
|
|
|
|
$('.file a').click(function(event) {
|
|
event.preventDefault();
|
|
var id = "#" + event.currentTarget.innerHTML.replaceAll('/', '_');
|
|
if (typeof window.last_source_file_id !== 'undefined'){
|
|
$(window.last_source_file_id).addClass( "hide-content" );
|
|
}
|
|
window.last_source_file_id = id;
|
|
$(id).removeClass( "hide-content" );
|
|
location.href = id;
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>''')
|
|
|
|
|
|
class ReportMerge(object):
|
|
"""Merge multiple html coverage reports"""
|
|
|
|
DESTINATION = os.path.join(os.environ['HOME'], 'results', os.environ['TDDIUM_SESSION_ID'], 'session')
|
|
|
|
def __init__(self):
|
|
self.reports_dir = os.path.realpath(__file__).replace("scripts/cov_merge.py", "reports/")
|
|
|
|
def _files(self, cover_path):
|
|
"""
|
|
Return list of file paths in `cover_path`. `cover_path` will be something like */reports/cms/cover
|
|
"""
|
|
include = lambda f: f.endswith('.html') and os.path.basename(f) != 'index.html'
|
|
return [os.path.join(cover_path, f) for f in os.listdir(cover_path) if include(f)]
|
|
|
|
def merge(self, modules, output_file=None):
|
|
"""
|
|
Merge reports for `modules`
|
|
|
|
Arguments:
|
|
output_file (str): name of output report file -- only used for bok_choy reports
|
|
|
|
"""
|
|
for module in modules:
|
|
for (path, _, _) in os.walk(os.path.join(self.reports_dir, module)):
|
|
if os.path.basename(path) == 'cover':
|
|
self.merge_report(path, output_file)
|
|
|
|
def merge_report(self, path, output_file):
|
|
"""
|
|
Collect multiple parts of a report and join them to create a single report.
|
|
|
|
Arguments:
|
|
path (str): path where multiple files are located to be merged
|
|
output_file (str): name of output report file -- only used for bok_choy reports
|
|
|
|
"""
|
|
content = list()
|
|
|
|
# Extract total coverage percentage and file links table
|
|
index_html = os.path.join(path, 'index.html')
|
|
with open(index_html) as index_file:
|
|
soup = BeautifulSoup(index_file)
|
|
total_percentage = soup.find('div', id='header')
|
|
total_percentage.find('img').decompose()
|
|
index_table = soup.find('div', id='index')
|
|
|
|
# Extract file names
|
|
files = [os.path.join(path, name['href']) for name in index_table.find_all('a')]
|
|
if not files:
|
|
return
|
|
|
|
print 'Merging Report for {}'.format(path)
|
|
|
|
# Collect different parts of html report
|
|
content.append(FIRST)
|
|
content.append('<body>')
|
|
content.append(str(total_percentage))
|
|
content.append(str(index_table))
|
|
for html in files:
|
|
content.append(self._html_content(html))
|
|
|
|
content.append(LAST)
|
|
|
|
if output_file:
|
|
report_path = os.path.join(self.DESTINATION, output_file)
|
|
else:
|
|
report_filename = path.split('reports/')[1].split('/cover')[0].replace('/', '_')
|
|
report_path = os.path.join(self.DESTINATION, report_filename+'_coverage.html')
|
|
|
|
# Write everything to single report file
|
|
with open(report_path, 'w') as report_file:
|
|
report_file.write('\n'.join(content))
|
|
|
|
print 'Report Merged for {}'.format(path)
|
|
|
|
def _html_content(self, html):
|
|
"""
|
|
Returns html tags of interest for file specified by `html`
|
|
"""
|
|
# Create id for each link in file links table
|
|
navigate_div_id = os.path.basename(html).split('.')[0].replace('/', '_')
|
|
navigate_div_start = "<div id='{}' class='hide-content'>\n".format(navigate_div_id)
|
|
navigate_div_close = "\n</div>".format(navigate_div_id)
|
|
|
|
content = list()
|
|
content.append(navigate_div_start)
|
|
|
|
with open(html) as html_file:
|
|
soup = BeautifulSoup(html_file)
|
|
header = soup.find('div', id='header')
|
|
header.find('img').decompose()
|
|
source = soup.find('div', id='source')
|
|
source_img = source.find('img')
|
|
if source_img:
|
|
source_img.decompose()
|
|
|
|
content.append(str(header))
|
|
content.append(str(source))
|
|
|
|
content.append(navigate_div_close)
|
|
|
|
return '\n'.join(content)
|
|
|
|
if __name__ == '__main__':
|
|
args = sys.argv
|
|
|
|
if 'bok_choy' in args[1]:
|
|
paths = ['bok_choy']
|
|
rm = ReportMerge()
|
|
rm.merge(paths, output_file=args[2])
|
|
elif 'unit' in args[1]:
|
|
paths = ['common', 'cms', 'lms']
|
|
for pth in paths:
|
|
rm = ReportMerge()
|
|
mp = multiprocessing.Process(target=rm.merge, args=([pth],))
|
|
mp.start()
|
|
else:
|
|
print 'Unsupported Test Suit'
|