summaryrefslogtreecommitdiffstats
path: root/scripts/lib/build_perf/html
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2017-03-31 17:07:29 +0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-04-01 23:28:20 +0100
commit9f299876f716f253b0a3d70eb4473a023c593fc5 (patch)
tree057d934e96df36ac3e28113b11f5b1ce70c7b614 /scripts/lib/build_perf/html
parent5a85d39c9d5502aabc2dde20f2a16bf7ac9f2d22 (diff)
downloadpoky-9f299876f716f253b0a3d70eb4473a023c593fc5.tar.gz
scripts: add oe-build-perf-report script
A new tool for pretty-printing build perf test results stored in a Git repository. The scripts is able to produce either simple plaintext report showing the difference between two commits, or, an html report that also displays trendcharts of the test results. The script uses Jinja2 templates for generating HTML reports so it requires python3-jinja2 to be installed on the system. [YOCTO #10931] (From OE-Core rev: 3b25404f0f99b72f222bdca815929be1cf1cee35) Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/build_perf/html')
-rw-r--r--scripts/lib/build_perf/html/measurement_chart.html50
-rw-r--r--scripts/lib/build_perf/html/report.html209
2 files changed, 259 insertions, 0 deletions
diff --git a/scripts/lib/build_perf/html/measurement_chart.html b/scripts/lib/build_perf/html/measurement_chart.html
new file mode 100644
index 0000000000..26fe1453c0
--- /dev/null
+++ b/scripts/lib/build_perf/html/measurement_chart.html
@@ -0,0 +1,50 @@
1<script type="text/javascript">
2 google.charts.setOnLoadCallback(drawChart_{{ chart_elem_id }});
3 function drawChart_{{ chart_elem_id }}() {
4 var data = new google.visualization.DataTable();
5
6 // Chart options
7 var options = {
8 theme : 'material',
9 legend: 'none',
10 hAxis: { format: '', title: 'Commit number',
11 minValue: {{ chart_opts.haxis.min }},
12 maxValue: {{ chart_opts.haxis.max }} },
13 {% if measurement.type == 'time' %}
14 vAxis: { format: 'h:mm:ss' },
15 {% else %}
16 vAxis: { format: '' },
17 {% endif %}
18 pointSize: 5,
19 chartArea: { left: 80, right: 15 },
20 };
21
22 // Define data columns
23 data.addColumn('number', 'Commit');
24 data.addColumn('{{ measurement.value_type.gv_data_type }}',
25 '{{ measurement.value_type.quantity }}');
26 // Add data rows
27 data.addRows([
28 {% for sample in measurement.samples %}
29 [{{ sample.commit_num }}, {{ sample.mean.gv_value() }}],
30 {% endfor %}
31 ]);
32
33 // Finally, draw the chart
34 chart_div = document.getElementById('{{ chart_elem_id }}');
35 var chart = new google.visualization.LineChart(chart_div);
36 google.visualization.events.addListener(chart, 'ready', function () {
37 //chart_div = document.getElementById('{{ chart_elem_id }}');
38 //chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
39 png_div = document.getElementById('{{ chart_elem_id }}_png');
40 png_div.outerHTML = '<a id="{{ chart_elem_id }}_png" href="' + chart.getImageURI() + '">PNG</a>';
41 console.log("CHART READY: {{ chart_elem_id }}");
42 {% if last_chart == true %}
43 console.log("ALL CHARTS READY");
44 {% endif %}
45 //console.log(chart_div.innerHTML);
46 });
47 chart.draw(data, options);
48}
49</script>
50
diff --git a/scripts/lib/build_perf/html/report.html b/scripts/lib/build_perf/html/report.html
new file mode 100644
index 0000000000..e42871177d
--- /dev/null
+++ b/scripts/lib/build_perf/html/report.html
@@ -0,0 +1,209 @@
1<!DOCTYPE html>
2<html lang="en">
3<head>
4{# Scripts, for visualization#}
5<!--START-OF-SCRIPTS-->
6<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
7<script type="text/javascript">
8google.charts.load('current', {'packages':['corechart']});
9</script>
10
11{# Render measurement result charts #}
12{% for test in test_data %}
13 {% set test_loop = loop %}
14 {% if test.status == 'SUCCESS' %}
15 {% for measurement in test.measurements %}
16 {% set chart_elem_id = test.name + '_' + measurement.name + '_chart' %}
17 {% if test_loop.last and loop.last %}
18 {% set last_chart = true %}
19 {% endif %}
20 {% include 'measurement_chart.html' %}
21 {% endfor %}
22 {% endif %}
23{% endfor %}
24
25<!--END-OF-SCRIPTS-->
26
27{# Styles #}
28<style>
29.meta-table {
30 font-size: 14px;
31 text-align: left;
32 border-collapse: collapse;
33}
34.meta-table tr:nth-child(even){background-color: #f2f2f2}
35meta-table th, .meta-table td {
36 padding: 4px;
37}
38.summary {
39 margin: 0;
40 font-size: 14px;
41 text-align: left;
42 border-collapse: collapse;
43}
44summary th, .meta-table td {
45 padding: 4px;
46}
47.measurement {
48 padding: 8px 0px 8px 8px;
49 border: 2px solid #f0f0f0;
50 margin-bottom: 10px;
51}
52.details {
53 margin: 0;
54 font-size: 12px;
55 text-align: left;
56 border-collapse: collapse;
57}
58.details th {
59 font-weight: normal;
60 padding-right: 8px;
61}
62.preformatted {
63 font-family: monospace;
64 white-space: pre-wrap;
65 background-color: #f0f0f0;
66 margin-left: 10px;
67}
68hr {
69 color: #f0f0f0;
70}
71h2 {
72 font-size: 20px;
73 margin-bottom: 0px;
74 color: #707070;
75}
76h3 {
77 font-size: 16px;
78 margin: 0px;
79 color: #707070;
80}
81</style>
82
83<title>{{ title }}</title>
84</head>
85
86{% macro poky_link(commit) -%}
87 <a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?id={{ commit }}">{{ commit[0:11] }}</a>
88{%- endmacro %}
89
90<body><div style="width: 700px">
91 {# Test metadata #}
92 <h2>General</h2>
93 <hr>
94 <table class="meta-table" style="width: 100%">
95 <tr>
96 <th></th>
97 <th>Current commit</th>
98 <th>Comparing with</th>
99 </tr>
100 {% for key, item in metadata.items() %}
101 <tr>
102 <th>{{ item.title }}</th>
103 {%if key == 'commit' %}
104 <td>{{ poky_link(item.value) }}</td>
105 <td>{{ poky_link(item.value_old) }}</td>
106 {% else %}
107 <td>{{ item.value }}</td>
108 <td>{{ item.value_old }}</td>
109 {% endif %}
110 </tr>
111 {% endfor %}
112 </table>
113
114 {# Test result summary #}
115 <h2>Test result summary</h2>
116 <hr>
117 <table class="summary" style="width: 100%">
118 {% for test in test_data %}
119 {% if loop.index is even %}
120 {% set row_style = 'style="background-color: #f2f2f2"' %}
121 {% else %}
122 {% set row_style = 'style="background-color: #ffffff"' %}
123 {% endif %}
124 <tr {{ row_style }}><td>{{ test.name }}: {{ test.description }}</td>
125 {% if test.status == 'SUCCESS' %}
126 {% for measurement in test.measurements %}
127 {# add empty cell in place of the test name#}
128 {% if loop.index > 1 %}<td></td>{% endif %}
129 {% if measurement.absdiff > 0 %}
130 {% set result_style = "color: red" %}
131 {% elif measurement.absdiff == measurement.absdiff %}
132 {% set result_style = "color: green" %}
133 {% else %}
134 {% set result_style = "color: orange" %}
135 {%endif %}
136 <td>{{ measurement.description }}</td>
137 <td style="font-weight: bold">{{ measurement.value.mean }}</td>
138 <td style="{{ result_style }}">{{ measurement.absdiff_str }}</td>
139 <td style="{{ result_style }}">{{ measurement.reldiff }}</td>
140 </tr><tr {{ row_style }}>
141 {% endfor %}
142 {% else %}
143 <td style="font-weight: bold; color: red;">{{test.status }}</td>
144 <td></td> <td></td> <td></td> <td></td>
145 {% endif %}
146 </tr>
147 {% endfor %}
148 </table>
149
150 {# Detailed test results #}
151 {% for test in test_data %}
152 <h2>{{ test.name }}: {{ test.description }}</h2>
153 <hr>
154 {% if test.status == 'SUCCESS' %}
155 {% for measurement in test.measurements %}
156 <div class="measurement">
157 <h3>{{ measurement.description }}</h3>
158 <div style="font-weight:bold;">
159 <span style="font-size: 23px;">{{ measurement.value.mean }}</span>
160 <span style="font-size: 20px; margin-left: 12px">
161 {% if measurement.absdiff > 0 %}
162 <span style="color: red">
163 {% elif measurement.absdiff == measurement.absdiff %}
164 <span style="color: green">
165 {% else %}
166 <span style="color: orange">
167 {% endif %}
168 {{ measurement.absdiff_str }} ({{measurement.reldiff}})
169 </span></span>
170 </div>
171 <table style="width: 100%">
172 <tr>
173 <td style="width: 75%">
174 {# Linechart #}
175 <div id="{{ test.name }}_{{ measurement.name }}_chart"></div>
176 </td>
177 <td>
178 {# Measurement statistics #}
179 <table class="details">
180 <tr>
181 <th>Test runs</th><td>{{ measurement.value.sample_cnt }}</td>
182 </tr><tr>
183 <th>-/+</th><td>-{{ measurement.value.minus }} / +{{ measurement.value.plus }}</td>
184 </tr><tr>
185 <th>Min</th><td>{{ measurement.value.min }}</td>
186 </tr><tr>
187 <th>Max</th><td>{{ measurement.value.max }}</td>
188 </tr><tr>
189 <th>Stdev</th><td>{{ measurement.value.stdev }}</td>
190 </tr><tr>
191 <th><div id="{{ test.name }}_{{ measurement.name }}_chart_png"></div></th>
192 </tr>
193 </table>
194 </td>
195 </tr>
196 </table>
197 </div>
198 {% endfor %}
199 {# Unsuccessful test #}
200 {% else %}
201 <span style="font-size: 150%; font-weight: bold; color: red;">{{ test.status }}
202 {% if test.err_type %}<span style="font-size: 75%; font-weight: normal">({{ test.err_type }})</span>{% endif %}
203 </span>
204 <div class="preformatted">{{ test.message }}</div>
205 {% endif %}
206 {% endfor %}
207</div></body>
208</html>
209