[llvm-commits] [zorg] r108308 - in /zorg/trunk/lnt/lnt: util/NTEmailReport.py viewer/simple.ptl
Daniel Dunbar
daniel at zuster.org
Tue Jul 13 18:39:58 PDT 2010
Author: ddunbar
Date: Tue Jul 13 20:39:58 2010
New Revision: 108308
URL: http://llvm.org/viewvc/llvm-project?rev=108308&view=rev
Log:
LNT/simple: Add HTML email reports for simple style tests.
Also, add support to web view to see text/HTML reports directly.
Modified:
zorg/trunk/lnt/lnt/util/NTEmailReport.py
zorg/trunk/lnt/lnt/viewer/simple.ptl
Modified: zorg/trunk/lnt/lnt/util/NTEmailReport.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/util/NTEmailReport.py?rev=108308&r1=108307&r2=108308&view=diff
==============================================================================
--- zorg/trunk/lnt/lnt/util/NTEmailReport.py (original)
+++ zorg/trunk/lnt/lnt/util/NTEmailReport.py Tue Jul 13 20:39:58 2010
@@ -14,10 +14,13 @@
from lnt import viewer
from lnt.db import runinfo
from lnt.db import perfdbsummary
+from lnt.viewer import GraphUtil
from lnt.viewer import Util
from lnt.viewer import PerfDB
from lnt.viewer.NTUtil import *
+from lnt.viewer.PerfDB import Run, Sample
+
def main():
global opts
from optparse import OptionParser
@@ -79,7 +82,9 @@
best = r
return best
-def getSimpleReport(db, run, baseurl, was_added, will_commit):
+def getSimpleReport(db, run, baseurl, was_added, will_commit,
+ only_html_body = False, show_graphs = False):
+ machine = run.machine
tag = run.info['tag'].value
# Get the run summary.
@@ -140,14 +145,18 @@
# Generate the report.
report = StringIO.StringIO()
+ html_report = StringIO.StringIO()
machine = run.machine
subject = """%s nightly tester results""" % machine.name
+
# Generate the report header.
if baseurl[-1] == '/':
baseurl = baseurl[:-1]
- print >>report, """%s/simple/%s/%d/""" % (baseurl, tag, run.id)
+
+ report_url = """%s/simple/%s/%d/""" % (baseurl, tag, run.id)
+ print >>report, report_url
print >>report, """Nickname: %s:%d""" % (machine.name, machine.number)
if 'name' in machine.info:
print >>report, """Name: %s""" % (machine.info['name'].value,)
@@ -168,11 +177,53 @@
print >>report, """ To: (none)"""
print >>report
+ # Generate the HTML report header.
+ print >>html_report, """\
+<h1>%s</h1>
+<table>""" % subject
+ print >>html_report, """\
+<tr><td>URL</td><td><a href="%s">%s</a></td></tr>""" % (report_url, report_url)
+ print >>html_report, "<tr><td>Nickname</td><td>%s:%d</td></tr>" % (
+ machine.name, machine.number)
+ if 'name' in machine.info:
+ print >>html_report, """<tr><td>Name</td<td>%s</td></tr>""" % (
+ machine.info['name'].value,)
+ print >>html_report, """</table>"""
+ print >>html_report, """\
+<p>
+<table>
+ <tr>
+ <th>Run</th>
+ <th>ID</th>
+ <th>Order</th>
+ <th>Start Time</th>
+ <th>End Time</th>
+ </tr>"""
+ print >>html_report, """\
+<tr><td>Current</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (
+ run.id, run.info['run_order'].value, run.start_time, run.end_time)
+ if compare_to:
+ print >>html_report, """\
+<tr><td>Previous</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (
+ compare_to.id, compare_to.info['run_order'].value,
+ compare_to.start_time, compare_to.end_time)
+ else:
+ print >>html_report, """<tr><td colspan=4>No Previous Run</td></tr>"""
+ print >>html_report, """</table>"""
+ if compare_to and run.machine != compare_to.machine:
+ print >>html_report, """<p><b>*** WARNING ***:""",
+ print >>html_report, """comparison is against a different machine""",
+ print >>html_report, """(%s:%d)</b></p>""" % (compare_to.machine.name,
+ compare_to.machine.number)
+
if existing_failures:
- print >>report, 'Total Existing Failures:', sum(
- map(len, existing_failures.values()))
+ num_existing_failures = sum(map(len, existing_failures.values()))
+ print >>report, 'Total Existing Failures:', num_existing_failures
print >>report
+ print >>html_report, """\
+<p><b>Total Existing Failures:</b> %d</p>""" % num_existing_failures
+
# Generate the summary of the changes.
items_info = (('New Failures', new_failures, False),
('New Passes', new_passes, False),
@@ -182,23 +233,39 @@
('Added Tests', added_tests, False))
total_changes = sum([sum(map(len, items.values()))
for _,items,_ in items_info])
+ graphs = []
if total_changes:
print >>report, """==============="""
print >>report, """Changes Summary"""
print >>report, """==============="""
print >>report
+ print >>html_report, """
+<hr>
+<h3>Changes Summary</h3>
+<table>
+<tr><th>Change Kind</th><th>#</th></tr>"""
for name,items,_ in items_info:
if items:
- print >>report, '%s: %d' % (name, sum(map(len, items.values())))
+ num_items = sum(map(len, items.values()))
+ print >>report, '%s: %d' % (name, num_items)
+ print >>html_report, """
+<tr><td>%s</td><td>%d</td></tr>""" % (name, num_items)
print >>report
+ print >>html_report, """
+</table>
+"""
print >>report, """=============="""
print >>report, """Changes Detail"""
print >>report, """=============="""
+ print >>html_report, """
+<p>
+<h3>Changes Detail</h3>"""
for name,items,show_perf in items_info:
if not items:
continue
+ show_pset = items.items()[0][0] or len(items) > 1
print >>report
print >>report, name
print >>report, '-' * len(name)
@@ -206,36 +273,130 @@
if show_perf:
tests.sort(key = lambda (_,cr): -abs(cr.pct_delta))
- if pset or len(items) > 1:
+ if show_pset:
print >>report
print >>report, "Parameter Set:", pset
- for name,cr in tests:
+ table_name = "%s - %s" % (name, pset)
+ else:
+ table_name = name
+ print >>html_report, """
+<p>
+<table class="sortable">
+<tr><th>%s</th>""" % table_name
+ if show_perf:
+ print >>html_report, """
+<th>Δ</th><th>Previous</th><th>Current</th> <th>σ</th>"""
+ print >>html_report, """</tr>"""
+
+ for i,(name,cr) in enumerate(tests):
if show_perf:
print >>report, (' %s: %.2f%%'
'(%.4f => %.4f, std. dev.: %.4f)') % (
name, 100. * cr.pct_delta,
cr.previous, cr.current, cr.stddev)
+
+ # Show inline charts for top 10 changes.
+ if show_graphs and i < 10:
+ graph_name = "graph.%d" % len(graphs)
+ graphs.append( (graph_name,name,pset) )
+ extra_cell_value = """
+<br><canvas id="%s" width="400" height="100"></canvas/>
+""" % (graph_name)
+ else:
+ extra_cell_value = ""
+ pct_value = Util.PctCell(cr.pct_delta).render()
+ print >>html_report, """
+<tr><td>%s%s</td>%s<td>%.4f</td><td>%.4f</td><td>%.4f</td></tr>""" %(
+ name, extra_cell_value, pct_value,
+ cr.previous, cr.current, cr.stddev)
else:
print >>report, ' %s' % (name,)
+ print >>html_report, """
+<tr><td>%s</td></tr>""" % (name,)
+ print >>html_report, """
+</table>"""
# Generate a list of the existing failures.
if existing_failures:
+ show_pset = existing_failures.items()[0][0] or len(items) > 1
+
print >>report
print >>report, """================="""
print >>report, """Existing Failures"""
print >>report, """================="""
+ print >>html_report, """
+<hr>
+<h3>Existing Failures</h3>"""
for pset,tests in existing_failures.items():
- if pset or len(existing_failures) > 1:
+ if show_pset:
print >>report
print >>report, "Parameter Set:", pset
+ table_name = "Existing Failures - %s" % (name, pset)
+ else:
+ table_name = "Existing Failures"
# Print at most 10 failures in an email report.
+ print >>html_report, """
+<p>
+<table class="sortable">
+<tr><th>%s</th></tr>""" % table_name
N = 10
for name,cr in tests[:N]:
print >>report, ' %s' % (name,)
+ print >>html_report, """<tr><td>%s</td></tr>""" % (name,)
if len(tests) > 10:
print >>report, ' ... and %d more ...' % (len(tests) - 10,)
+ print >>html_report, """
+<tfoot><tr><td>... and %d more ...</td></tr></tfoot>""" % (
+ len(tests) - 10,)
+ print >>html_report, """
+</table>"""
+
+ # Finish up the HTML report.
+ if graphs:
+ # Get the test ids we want data for.
+ test_ids = [ts_summary.test_id_map[(name,pset)]
+ for _,name,pset in graphs]
+
+ plots_iter = GraphUtil.get_test_plots(db, machine, test_ids,
+ run_summary, ts_summary,
+ show_mad_error = True,
+ show_points = True)
+
+ print >>html_report, """
+<script type="text/javascript">
+function init_report() {"""
+ for (graph_item, plot_info) in zip(graphs, plots_iter):
+ graph_name = graph_item[0]
+ plot_js = plot_info[1]
+ print >>html_report, """
+ graph = new Graph2D("%s");
+ graph.clearColor = [1, 1, 1];
+ %s
+ graph.draw();
+""" % (graph_name, plot_js)
+ print >>html_report, """
+}
+</script>"""
+
+ html_report = html_report.getvalue()
+ if not only_html_body:
+ html_report = """
+<html>
+ <head>
+ <link rel="stylesheet" href="%(baseurl)s/resources/style.css"
+ type="text/css"/>
+ <script src="%(baseurl)s/resources/sorttable.js"></script>
+ <script src="%(baseurl)s/resources/mootools-1.2.4-core-nc.js"></script>
+ <script src="%(baseurl)s/js/View2D.js"></script>
+ <title>%(subject)s</title>
+ </head>
+ <body onload="init_report()">
+%(html_report)s
+ </body>
+</html>""" % locals()
+ return subject, report.getvalue(), html_report
return subject, report.getvalue(), None
def getReport(db, run, baseurl, was_added, will_commit):
Modified: zorg/trunk/lnt/lnt/viewer/simple.ptl
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/simple.ptl?rev=108308&r1=108307&r2=108308&view=diff
==============================================================================
--- zorg/trunk/lnt/lnt/viewer/simple.ptl (original)
+++ zorg/trunk/lnt/lnt/viewer/simple.ptl Tue Jul 13 20:39:58 2010
@@ -10,10 +10,12 @@
import quixote
from quixote.directory import Directory
from quixote.errors import TraversalError
+from quixote.html import htmltext
from lnt.db import runinfo
from lnt.db import perfdbsummary
from lnt.util import stats
+from lnt.util import NTEmailReport
from lnt.viewer import GraphUtil
import Util
@@ -23,7 +25,7 @@
from PerfDB import Machine, Run, RunInfo, Test
class SimpleRunUI(Directory):
- _q_exports = ["", "graph"]
+ _q_exports = ["", "graph", "report", "text_report"]
def __init__(self, root, tag, idstr):
self.root = root
@@ -196,13 +198,23 @@
run,run_summary,compare_to = self.getInfo(db)
machine = run.machine
+ # Add JS to run the init_report function, if embedded.
+ init = """\
+ function init() {
+ if (init_report) {
+ init_report();
+ }
+ }
+ """
self.root.getHeader('Run Results', "../../..",
components=((self.tag,
'%s/%s' % ('simple',self.tag)),
('machine',
'simple/%s/machines/%d'%(self.tag,
machine.id))),
- addPopupJS=True, addFormCSS=True)
+ addPopupJS=True, addFormCSS=True, addGraphJS=True,
+ addJSScript=init,
+ onload="init()")
self.show_run_page(db, run, run_summary, compare_to,
lambda: self._q_index_body(db, run, run_summary,
@@ -393,6 +405,35 @@
self.show_run_page(db, run, run_summary, compare_to, graph_body)
+ def report(self):
+ db = self.root.getDB()
+
+ request = quixote.get_request()
+ show_graphs = bool(request.form.get('show_graphs'))
+ run,run_summary,compare_to = self.getInfo(db)
+
+ _, _, html_report = NTEmailReport.getSimpleReport(
+ db, run, str("%s/db_%s/") % (self.root.config.zorgURL,
+ self.root.dbName),
+ True, True, show_graphs = show_graphs)
+
+ return htmltext(html_report)
+
+ def text_report(self):
+ db = self.root.getDB()
+
+ run,run_summary,compare_to = self.getInfo(db)
+
+ _, text_report, _ = NTEmailReport.getSimpleReport(
+ db, run, str("%s/db_%s/") % (self.root.config.zorgURL,
+ self.root.dbName),
+ True, True)
+
+ response = quixote.get_response()
+ response.set_content_type('text/plain')
+
+ return text_report
+
def _q_index_body [html] (self, db, run, run_summary, compare_to):
# Load the test suite summary.
ts_summary = perfdbsummary.get_simple_suite_summary(db, self.tag)
@@ -410,13 +451,17 @@
title="Show All Values")
form.add(quixote.form.IntWidget, "num_comparison_runs",
title="Number of Comparison Runs")
+ form.add(quixote.form.CheckboxWidget, "show_graphs",
+ title="Show Report Graphs")
form.add_submit("submit", "Update")
request = quixote.get_request()
+ show_graphs = bool(form['show_graphs'])
show_delta = bool(form['show_delta'])
show_stddev = bool(form['show_stddev'])
show_mad = bool(form['show_mad'])
show_all = bool(form['show_all'])
+ show_graphs = bool(form['show_graphs'])
try:
num_comparison_runs = int(form['num_comparison_runs'])
except:
@@ -426,6 +471,19 @@
form.render()
self.renderPopupEnd()
+ _, text_report, html_report = NTEmailReport.getSimpleReport(
+ db, run, str("%s/db_%s/") % (self.root.config.zorgURL,
+ self.root.dbName),
+ True, True, only_html_body = True, show_graphs = show_graphs)
+ self.renderPopupBegin('text_report', 'Report (Text)', True)
+ """
+ <pre>%s</pre>""" % (text_report,)
+ self.renderPopupEnd()
+
+ self.renderPopupBegin('html_report', 'Report (HTML)', False)
+ htmltext(html_report)
+ self.renderPopupEnd()
+
# Gather the runs to use for statistical data.
cur_id = run.id
comparison_window = []
More information about the llvm-commits
mailing list