[LNT] r343462 - Introduce Latest Runs Report.
Martin Liska via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 1 05:20:54 PDT 2018
Author: marxin
Date: Mon Oct 1 05:20:54 2018
New Revision: 343462
URL: http://llvm.org/viewvc/llvm-project?rev=343462&view=rev
Log:
Introduce Latest Runs Report.
Differential Revision: https://reviews.llvm.org/D51405
Modified:
lnt/trunk/lnt/server/reporting/dailyreport.py
lnt/trunk/lnt/server/ui/templates/layout.html
lnt/trunk/lnt/server/ui/templates/reporting/daily_report.html
lnt/trunk/lnt/server/ui/views.py
lnt/trunk/tests/server/ui/V4Pages.py
Modified: lnt/trunk/lnt/server/reporting/dailyreport.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/reporting/dailyreport.py?rev=343462&r1=343461&r2=343462&view=diff
==============================================================================
--- lnt/trunk/lnt/server/reporting/dailyreport.py (original)
+++ lnt/trunk/lnt/server/reporting/dailyreport.py Mon Oct 1 05:20:54 2018
@@ -1,7 +1,7 @@
from collections import namedtuple
from lnt.server.reporting.analysis import REGRESSED, UNCHANGED_FAIL
+from lnt.server.reporting.report import RunResult, RunResults, report_css_styles, pairs, OrderAndHistory
from lnt.util import multidict
-import colorsys
import datetime
import lnt.server.reporting.analysis
import lnt.server.ui.app
@@ -9,118 +9,6 @@ import re
import sqlalchemy.sql
import urllib
-OrderAndHistory = namedtuple('OrderAndHistory', ['max_order', 'recent_orders'])
-
-
-def _pairs(list):
- return zip(list[:-1], list[1:])
-
-
-# The hash color palette avoids green and red as these colours are already used
-# in quite a few places to indicate "good" or "bad".
-_hash_color_palette = (
- colorsys.hsv_to_rgb(h=45. / 360, s=0.3, v=0.9999), # warm yellow
- colorsys.hsv_to_rgb(h=210. / 360, s=0.3, v=0.9999), # blue cyan
- colorsys.hsv_to_rgb(h=300. / 360, s=0.3, v=0.9999), # mid magenta
- colorsys.hsv_to_rgb(h=150. / 360, s=0.3, v=0.9999), # green cyan
- colorsys.hsv_to_rgb(h=225. / 360, s=0.3, v=0.9999), # cool blue
- colorsys.hsv_to_rgb(h=180. / 360, s=0.3, v=0.9999), # mid cyan
-)
-
-
-def _clamp(v, minVal, maxVal):
- return min(max(v, minVal), maxVal)
-
-
-def _toColorString(col):
- r, g, b = [_clamp(int(v * 255), 0, 255)
- for v in col]
- return "#%02x%02x%02x" % (r, g, b)
-
-
-def _get_rgb_colors_for_hashes(hash_strings):
- hash2color = {}
- unique_hash_counter = 0
- for hash_string in hash_strings:
- if hash_string is not None:
- if hash_string in hash2color:
- continue
- hash2color[hash_string] = _hash_color_palette[unique_hash_counter]
- unique_hash_counter += 1
- if unique_hash_counter >= len(_hash_color_palette):
- break
- result = []
- for hash_string in hash_strings:
- if hash_string is None:
- result.append(None)
- else:
- # If not one of the first N hashes, return rgb value 0,0,0 which is
- # white.
- rgb = hash2color.get(hash_string, (0.999, 0.999, 0.999))
- result.append(_toColorString(rgb))
- return result
-
-
-# Helper classes to make the sparkline chart construction easier in the jinja
-# template.
-class DayResult:
- def __init__(self, comparisonResult):
- self.cr = comparisonResult
- self.hash = self.cr.cur_hash
- self.samples = self.cr.samples
- if self.samples is None:
- self.samples = []
-
-
-class DayResults:
- """
- DayResults contains pre-processed data to easily construct the HTML for
- a single row in the results table, showing how one test on one board
- evolved over a number of runs/days.
- """
- def __init__(self):
- self.day_results = []
- self._complete = False
- self.min_sample = None
- self.max_sample = None
-
- def __getitem__(self, i):
- return self.day_results[i]
-
- def __len__(self):
- return len(self.day_results)
-
- def append(self, day_result):
- assert not self._complete
- self.day_results.append(day_result)
-
- def complete(self):
- """
- complete() needs to be called after all appends to this object, but
- before the data is used the jinja template.
- """
- self._complete = True
- all_samples = []
- for dr in self.day_results:
- if dr is None:
- continue
- if dr.cr.samples is not None and not dr.cr.failed:
- all_samples.extend(dr.cr.samples)
- if len(all_samples) > 0:
- self.min_sample = min(all_samples)
- self.max_sample = max(all_samples)
- hashes = []
- for dr in self.day_results:
- if dr is None:
- hashes.append(None)
- else:
- hashes.append(dr.hash)
- rgb_colors = _get_rgb_colors_for_hashes(hashes)
- for i, dr in enumerate(self.day_results):
- if dr is not None:
- dr.hash_rgb_color = rgb_colors[i]
-
-
class DailyReport(object):
def __init__(self, ts, year, month, day, num_prior_days_to_include=3,
day_start_offset_hours=16, for_mail=False,
@@ -212,7 +100,7 @@ class DailyReport(object):
prior_runs = [session.query(ts.Run).
filter(ts.Run.start_time > prior_day).
filter(ts.Run.start_time <= day).all()
- for day, prior_day in _pairs(self.prior_days)]
+ for day, prior_day in pairs(self.prior_days)]
if self.filter_machine_re is not None:
prior_runs = [[run for run in runs
@@ -380,8 +268,8 @@ class DailyReport(object):
continue
# Otherwise, compute the results for all the days.
- day_results = DayResults()
- day_results.append(DayResult(cr))
+ day_results = RunResults()
+ day_results.append(RunResult(cr))
for i in range(1, self.num_prior_days_to_include):
day_runs = machine_runs.get((machine.id, i), ())
if len(day_runs) == 0:
@@ -394,7 +282,7 @@ class DailyReport(object):
cr = sri.get_comparison_result(
day_runs, prev_runs, test.id, field,
self.hash_of_binary_field)
- day_results.append(DayResult(cr))
+ day_results.append(RunResult(cr))
day_results.complete()
@@ -431,23 +319,6 @@ class DailyReport(object):
env = lnt.server.ui.app.create_jinja_environment()
template = env.get_template('reporting/daily_report.html')
- # Compute static CSS styles for elements. We use the style directly on
- # elements instead of via a stylesheet to support major email clients
- # (like Gmail) which can't deal with embedded style sheets.
- #
- # These are derived from the static style.css file we use elsewhere.
- styles = {
- "body": ("color:#000000; background-color:#ffffff; "
- "font-family: Helvetica, sans-serif; font-size:9pt"),
- "table": ("font-size:9pt; border-spacing: 0px; "
- "border: 1px solid black"),
- "th": (
- "background-color:#eee; color:#666666; font-weight: bold; "
- "cursor: default; text-align:center; font-weight: bold; "
- "font-family: Verdana; padding:5px; padding-left:8px"),
- "td": "padding:5px; padding-left:8px",
- }
-
return template.render(
- report=self, styles=styles, analysis=lnt.server.reporting.analysis,
+ report=self, styles=report_css_styles, analysis=lnt.server.reporting.analysis,
ts_url=ts_url, only_html_body=only_html_body)
Modified: lnt/trunk/lnt/server/ui/templates/layout.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/layout.html?rev=343462&r1=343461&r2=343462&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/layout.html (original)
+++ lnt/trunk/lnt/server/ui/templates/layout.html Mon Oct 1 05:20:54 2018
@@ -161,6 +161,7 @@
<li><a href="{{ v4_url_for('.v4_recent_activity') }}">Recent Activity</a></li>
<li><a href="{{ v4_url_for('.v4_global_status') }}">Global Status</a></li>
<li><a href="{{ v4_url_for('.v4_daily_report_overview') }}">Daily Report</a></li>
+ <li><a href="{{ v4_url_for('.v4_latest_runs_report') }}">Latest Runs Report</a></li>
<li><a href="{{ v4_url_for('.v4_machines') }}">All Machines</a></li>
<li class="divider"></li>
<li class="disabled"><a href="#">Changes</a></li>
Modified: lnt/trunk/lnt/server/ui/templates/reporting/daily_report.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/reporting/daily_report.html?rev=343462&r1=343461&r2=343462&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/reporting/daily_report.html (original)
+++ lnt/trunk/lnt/server/ui/templates/reporting/daily_report.html Mon Oct 1 05:20:54 2018
@@ -1,4 +1,5 @@
{% import "utils.html" as utils %}
+{% import "reportutils.html" as reportutils %}
{% if not only_html_body %}
<html>
<head>
@@ -110,39 +111,6 @@
</tbody>
</table>
-{% macro get_initial_cell_value(day_result) %}
-{%- set cr = day_result.cr -%}
-{%- set test_status = cr.get_test_status() -%}
-
-{%- if (test_status == analysis.REGRESSED or
- test_status == analysis.UNCHANGED_FAIL) %}
- <td style="{{ styles.td }}; background-color:#e98080">FAIL</td>
-{%- else %}
- <td style="{{ styles.td }}; background-color:#d2d2d2"> {#- -#}
- {{ ("%.4f" % cr.current) if cr.current != none else "N/A" }}</td>
-{%- endif -%}
-
-{% endmacro %}
-
-{% macro get_cell_value(day_result) %}
-{%- set cr = day_result.cr -%}
-{%- set test_status = cr.get_test_status() -%}
-{%- set value_status = cr.get_value_status() -%}
-{%- if (test_status == analysis.REGRESSED or
- test_status == analysis.UNCHANGED_FAIL) %}
- <td style="{{ styles.td }}; background-color:#e98080">FAIL</td>
-{%- elif test_status == analysis.IMPROVED %}
- <td style="{{ styles.td }}; background-color:#8fdf5f">PASS</td>
-{%- else -%}
-{%- if (value_status == analysis.REGRESSED or
- value_status == analysis.IMPROVED) %}
- {{ cr.pct_delta|aspctcell(reverse=cr.bigger_is_better)|safe }}
-{%- else %}
- <td style="{{ styles.td }}">-</td>
-{%- endif -%}
-{%- endif -%}
-{% endmacro %}
-
{# Generate the table showing the raw sample data. #}
{# If the report is for mail, we put the table header on each test. This is
@@ -164,73 +132,6 @@
</thead>
{% endmacro %}
-{% macro spark_plot(day_results) %}
-{%- set x_border_size = 5 %}
-{%- set y_border_size = 2 %}
-{%- set height = 18 %}
-{%- set full_height = height + 2*y_border_size %}
-{%- set x_day_spacing = 10 %}
-{%- set sample_fuzzing = 0.5 %}
-{%- set nr_days = day_results|length %}
-{%- set width = x_day_spacing * nr_days + 2*x_border_size %}
-{%- if day_results.max_sample != day_results.min_sample %}
- {%- set scaling_factor = (1.0*height)
- / (day_results.max_sample-day_results.min_sample) -%}
-{%- else %}
- {%- set scaling_factor = 1.0 -%}
-{%- endif %}
-{%- macro spark_y_coord(day_nr, value) -%}
- {{ (value-day_results.min_sample) * scaling_factor + y_border_size }}
-{%- endmacro -%}
-{%- macro spark_x_coord(day_nr) -%}
- {{ (nr_days - day_nr) * x_day_spacing + x_border_size }}
-{%- endmacro -%}
-{%- macro spark_hash_background(day_nr, dr) -%}
- {%- if dr.cr.cur_hash is not none -%}
- {%- set style = "fill: "+dr.hash_rgb_color+";" -%}
- {%- else -%}
- {%- set style = "fill: none;" -%}
- {%- endif -%}
- <rect x="{{(nr_days-day_nr-0.5) * x_day_spacing + x_border_size}}" y="0"
- width="{{x_day_spacing}}" height="{{full_height}}" style="{{style}}"/>
-{%- endmacro -%}
- <span>
- <svg width="{{width}}" height="{{full_height}}">
- <rect width="{{width}}" height="{{full_height}}" fill="#f7f7f7"/>
-{#- Make y-axis go upwards instead of downwards: #}
- <g transform="translate(0, {{full_height}}) scale(1, -1) ">
-{%- for dr in day_results -%}
- {%- if dr is not none and not dr.cr.failed -%}
- {%- set day_nr = loop.index %}
- {%- set nr_samples_for_day = dr.samples|length %}
- {{ spark_hash_background(day_nr, dr) }}
- {%- for sample in dr.samples -%}
- {# fuzz the x-coordinate slightly so that multiple samples with the same
- value can be noticed #}
- {%- set sample_fuzz = (-sample_fuzzing*1.25) +
- (2.0*sample_fuzzing/nr_samples_for_day) * loop.index %}
- <circle cx="{{ spark_x_coord(day_nr)|float + sample_fuzz }}" {# -#}
- cy="{{ spark_y_coord(day_nr, sample) }}" r="1"
- stroke-width="1" stroke="black" fill="black" />
- {%- endfor -%}
- {%- endif -%}
-{%- endfor %}
- <polyline points="
- {%- for dr in day_results -%}
- {%- if dr is not none -%}
- {%- set cr = dr.cr -%}
- {%- set day_nr = loop.index -%}
- {%- if not cr.failed and cr.current is not none %}
- {{ spark_x_coord(day_nr) }} {{ spark_y_coord(day_nr, cr.current) }}
- {%- endif -%}
- {%- endif -%}
- {%- endfor -%}
- " fill="none" stroke="red" stroke-width="1"/>
- </g>
- </svg>
- </span>
-{%- endmacro %}
-
{% for field,field_results in report.result_table|reverse %}
{%- if field_results -%}
<h3>Result Table ({{ field.display_name }})</h3>
@@ -255,14 +156,14 @@
<td style="{{ styles.td }}">-</td>
{%- else -%}
{%- if first_result_shown -%}
- {{ get_cell_value(day_result) }}
+ {{ reportutils.get_cell_value(day_result, analysis, styles) }}
{%- else -%}
{%- set first_result_shown = true -%}
- {{ get_initial_cell_value(day_result) }}
+ {{ reportutils.get_initial_cell_value(day_result, analysis, styles) }}
{%- endif -%}
{%- endif -%}
{%- endfor %}
- <td>{{ spark_plot(day_results) }}</td>
+ <td>{{ reportutils.spark_plot(day_results) }}</td>
</tr>
{%- endfor %}
{{ "</tbody></table><p>" if report.for_mail }}
Modified: lnt/trunk/lnt/server/ui/views.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/views.py?rev=343462&r1=343461&r2=343462&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/views.py (original)
+++ lnt/trunk/lnt/server/ui/views.py Mon Oct 1 05:20:54 2018
@@ -26,6 +26,7 @@ import lnt.server.db.rules_manager
import lnt.server.db.search
import lnt.server.reporting.analysis
import lnt.server.reporting.dailyreport
+import lnt.server.reporting.latestrunsreport
import lnt.server.reporting.runs
import lnt.server.reporting.summaryreport
import lnt.server.ui.util
@@ -1513,6 +1514,23 @@ def v4_summary_report_ui():
config=config, all_machines=all_machines,
all_orders=all_orders, **ts_data(ts))
+ at v4_route("/latest_runs_report")
+def v4_latest_runs_report():
+ session = request.session
+ ts = request.get_testsuite()
+
+ num_runs_str = request.args.get('num_runs')
+ if num_runs_str is not None:
+ num_runs = int(num_runs_str)
+ else:
+ num_runs = 10
+
+ report = lnt.server.reporting.latestrunsreport.LatestRunsReport(ts, num_runs)
+ report.build(request.session)
+
+ return render_template("v4_latest_runs_report.html", report=report,
+ analysis=lnt.server.reporting.analysis,
+ **ts_data(ts))
@db_route("/summary_report")
def v4_summary_report():
Modified: lnt/trunk/tests/server/ui/V4Pages.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/V4Pages.py?rev=343462&r1=343461&r2=343462&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/V4Pages.py (original)
+++ lnt/trunk/tests/server/ui/V4Pages.py Mon Oct 1 05:20:54 2018
@@ -537,6 +537,9 @@ def main():
assert color2 is None
assert color1 != color3
+ # Check some variations of the latest runs report work.
+ check_html(client, '/v4/nts/latest_runs_report')
+
check_redirect(client, '/db_default/submitRun',
'/db_default/v4/nts/submitRun')
check_html(client, '/db_default/v4/nts/submitRun')
More information about the llvm-commits
mailing list