html_gen.py
"""Generates HTML page containing the testresults"""
from testsuite_common import Result, processLogLine, getLastTwoLines
from runtests import parse_testconfig
import os
import sys
from datetime import datetime, timedelta
HTML_HEADING = """<html>
<head>
<title>Moses speed testing</title>
<link rel="stylesheet" type="text/css" href="style.css"></head><body>"""
HTML_ENDING = "</table></body></html>\n"
TABLE_HEADING = """<table><tr class="heading">
<th>Date</th>
<th>Time</th>
<th>Testname</th>
<th>Revision</th>
<th>Branch</th>
<th>Time</th>
<th>Prevtime</th>
<th>Prevrev</th>
<th>Change (%)</th>
<th>Time (Basebranch)</th>
<th>Change (%, Basebranch)</th>
<th>Time (Days -2)</th>
<th>Change (%, Days -2)</th>
<th>Time (Days -3)</th>
<th>Change (%, Days -3)</th>
<th>Time (Days -4)</th>
<th>Change (%, Days -4)</th>
<th>Time (Days -5)</th>
<th>Change (%, Days -5)</th>
<th>Time (Days -6)</th>
<th>Change (%, Days -6)</th>
<th>Time (Days -7)</th>
<th>Change (%, Days -7)</th>
<th>Time (Days -14)</th>
<th>Change (%, Days -14)</th>
<th>Time (Years -1)</th>
<th>Change (%, Years -1)</th>
</tr>"""
def get_prev_days(date, numdays):
"""Gets the date numdays previous days so that we could search for
that test in the config file"""
date_obj = datetime.strptime(date, '%d.%m.%Y').date()
past_date = date_obj - timedelta(days=numdays)
return past_date.strftime('%d.%m.%Y')
def gather_necessary_lines(logfile, date):
"""Gathers the necessary lines corresponding to past dates
and parses them if they exist"""
#Get a dictionary of dates
dates = {}
dates[get_prev_days(date, 2)] = ('-2', None)
dates[get_prev_days(date, 3)] = ('-3', None)
dates[get_prev_days(date, 4)] = ('-4', None)
dates[get_prev_days(date, 5)] = ('-5', None)
dates[get_prev_days(date, 6)] = ('-6', None)
dates[get_prev_days(date, 7)] = ('-7', None)
dates[get_prev_days(date, 14)] = ('-14', None)
dates[get_prev_days(date, 365)] = ('-365', None)
openfile = open(logfile, 'r')
for line in openfile:
if line.split()[0] in dates.keys():
day = dates[line.split()[0]][0]
dates[line.split()[0]] = (day, processLogLine(line))
openfile.close()
return dates
def append_date_to_table(resline):
"""Appends past dates to the html"""
cur_html = '<td>' + str(resline.previous) + '</td>'
if resline.percentage > 0.05: #If we have improvement of more than 5%
cur_html = cur_html + '<td class="better">' + str(resline.percentage) + '</td>'
elif resline.percentage < -0.05: #We have a regression of more than 5%
cur_html = cur_html + '<td class="worse">' + str(resline.percentage) + '</td>'
else:
cur_html = cur_html + '<td class="unchanged">' + str(resline.percentage) + '</td>'
return cur_html
def compare_rev(filename, rev1, rev2, branch1=False, branch2=False):
"""Compare the test results of two lines. We can specify either a
revision or a branch for comparison. The first rev should be the
base version and the second revision should be the later version"""
#In the log file the index of the revision is 2 but the index of
#the branch is 12. Alternate those depending on whether we are looking
#for a specific revision or branch.
firstidx = 2
secondidx = 2
if branch1 == True:
firstidx = 12
if branch2 == True:
secondidx = 12
rev1line = ''
rev2line = ''
resfile = open(filename, 'r')
for line in resfile:
if rev1 == line.split()[firstidx]:
rev1line = line
elif rev2 == line.split()[secondidx]:
rev2line = line
if rev1line != '' and rev2line != '':
break
resfile.close()
if rev1line == '':
raise ValueError('Revision ' + rev1 + " was not found!")
if rev2line == '':
raise ValueError('Revision ' + rev2 + " was not found!")
logLine1 = processLogLine(rev1line)
logLine2 = processLogLine(rev2line)
res = Result(logLine1.testname, logLine1.real, logLine2.real,\
logLine2.revision, logLine2.branch, logLine1.revision, logLine1.branch)
return res
def produce_html(path, global_config):
"""Produces html file for the report."""
html = '' #The table HTML
for filenam in os.listdir(global_config.testlogs):
#Generate html for the newest two lines
#Get the lines from the config file
(ll1, ll2) = getLastTwoLines(filenam, global_config.testlogs)
logLine1 = processLogLine(ll1)
logLine2 = processLogLine(ll2) #This is the life from the latest revision
#Generate html
res1 = Result(logLine1.testname, logLine1.real, logLine2.real,\
logLine2.revision, logLine2.branch, logLine1.revision, logLine1.branch)
html = html + '<tr><td>' + logLine2.date + '</td><td>' + logLine2.time + '</td><td>' +\
res1.testname + '</td><td>' + res1.revision[:10] + '</td><td>' + res1.branch + '</td><td>' +\
str(res1.current) + '</td><td>' + str(res1.previous) + '</td><td>' + res1.prevrev[:10] + '</td>'
#Add fancy colours depending on the change
if res1.percentage > 0.05: #If we have improvement of more than 5%
html = html + '<td class="better">' + str(res1.percentage) + '</td>'
elif res1.percentage < -0.05: #We have a regression of more than 5%
html = html + '<td class="worse">' + str(res1.percentage) + '</td>'
else:
html = html + '<td class="unchanged">' + str(res1.percentage) + '</td>'
#Get comparison against the base version
filenam = global_config.testlogs + '/' + filenam #Get proper directory
res2 = compare_rev(filenam, global_config.basebranch, res1.revision, branch1=True)
html = html + '<td>' + str(res2.previous) + '</td>'
#Add fancy colours depending on the change
if res2.percentage > 0.05: #If we have improvement of more than 5%
html = html + '<td class="better">' + str(res2.percentage) + '</td>'
elif res2.percentage < -0.05: #We have a regression of more than 5%
html = html + '<td class="worse">' + str(res2.percentage) + '</td>'
else:
html = html + '<td class="unchanged">' + str(res2.percentage) + '</td>'
#Add extra dates comparison dating from the beginning of time if they exist
past_dates = list(range(2, 8))
past_dates.append(14)
past_dates.append(365) # Get the 1 year ago day
linesdict = gather_necessary_lines(filenam, logLine2.date)
for days in past_dates:
act_date = get_prev_days(logLine2.date, days)
if linesdict[act_date][1] is not None:
logline_date = linesdict[act_date][1]
restemp = Result(logline_date.testname, logline_date.real, logLine2.real,\
logLine2.revision, logLine2.branch, logline_date.revision, logline_date.branch)
html = html + append_date_to_table(restemp)
else:
html = html + '<td>N/A</td><td>N/A</td>'
html = html + '</tr>' #End row
#Write out the file
basebranch_info = '<text><b>Basebranch:</b> ' + res2.prevbranch + ' <b>Revision:</b> ' +\
res2.prevrev + '</text>'
writeoutstr = HTML_HEADING + basebranch_info + TABLE_HEADING + html + HTML_ENDING
writefile = open(path, 'w')
writefile.write(writeoutstr)
writefile.close()
if __name__ == '__main__':
CONFIG = parse_testconfig(sys.argv[1])
produce_html('index.html', CONFIG)