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']});
9var chartsDrawing = 0;
10</script>
11
12{# Render measurement result charts #}
13{% for test in test_data %}
14  {% if test.status == 'SUCCESS' %}
15    {% for measurement in test.measurements %}
16      {% set chart_elem_id = test.name + '_' + measurement.name + '_chart' %}
17      {% include 'measurement_chart.html' %}
18    {% endfor %}
19  {% endif %}
20{% endfor %}
21
22<!--END-OF-SCRIPTS-->
23
24{# Styles #}
25<style>
26.meta-table {
27  font-size: 14px;
28  text-align: left;
29  border-collapse: collapse;
30}
31.meta-table tr:nth-child(even){background-color: #f2f2f2}
32meta-table th, .meta-table td {
33  padding: 4px;
34}
35.summary {
36  margin: 0;
37  font-size: 14px;
38  text-align: left;
39  border-collapse: collapse;
40}
41summary th, .meta-table td {
42  padding: 4px;
43}
44.measurement {
45  padding: 8px 0px 8px 8px;
46  border: 2px solid #f0f0f0;
47  margin-bottom: 10px;
48}
49.details {
50  margin: 0;
51  font-size: 12px;
52  text-align: left;
53  border-collapse: collapse;
54}
55.details th {
56  padding-right: 8px;
57}
58.details.plain th {
59  font-weight: normal;
60}
61.preformatted {
62  font-family: monospace;
63  white-space: pre-wrap;
64  background-color: #f0f0f0;
65  margin-left: 10px;
66}
67hr {
68  color: #f0f0f0;
69}
70h2 {
71  font-size: 20px;
72  margin-bottom: 0px;
73  color: #707070;
74}
75h3 {
76  font-size: 16px;
77  margin: 0px;
78  color: #707070;
79}
80</style>
81
82<title>{{ title }}</title>
83</head>
84
85{% macro poky_link(commit) -%}
86    <a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?id={{ commit }}">{{ commit[0:11] }}</a>
87{%- endmacro %}
88
89<body><div style="width: 700px">
90  {# Test metadata #}
91  <h2>General</h2>
92  <hr>
93  <table class="meta-table" style="width: 100%">
94    <tr>
95      <th></th>
96      <th>Current commit</th>
97      <th>Comparing with</th>
98    </tr>
99    {% for key, item in metadata.items() %}
100    <tr>
101      <th>{{ item.title }}</th>
102      {%if key == 'commit' %}
103        <td>{{ poky_link(item.value) }}</td>
104        <td>{{ poky_link(item.value_old) }}</td>
105      {% else %}
106        <td>{{ item.value }}</td>
107        <td>{{ item.value_old }}</td>
108      {% endif %}
109    </tr>
110    {% endfor %}
111  </table>
112
113  {# Test result summary #}
114  <h2>Test result summary</h2>
115  <hr>
116  <table class="summary" style="width: 100%">
117    {% for test in test_data %}
118      {% if loop.index is even %}
119        {% set row_style = 'style="background-color: #f2f2f2"' %}
120      {% else %}
121        {% set row_style = 'style="background-color: #ffffff"' %}
122      {% endif %}
123      {% if test.status == 'SUCCESS' %}
124        {% for measurement in test.measurements %}
125          <tr {{ row_style }}>
126            {% if loop.index == 1 %}
127              <td>{{ test.name }}: {{ test.description }}</td>
128            {% else %}
129              {# add empty cell in place of the test name#}
130              <td></td>
131            {% endif %}
132            {% if measurement.absdiff > 0 %}
133              {% set result_style = "color: red" %}
134            {% elif measurement.absdiff == measurement.absdiff %}
135              {% set result_style = "color: green" %}
136            {% else %}
137              {% set result_style = "color: orange" %}
138            {%endif %}
139            {% if measurement.reldiff|abs > 2 %}
140              {% set result_style = result_style + "; font-weight: bold" %}
141            {% endif %}
142            <td>{{ measurement.description }}</td>
143            <td style="font-weight: bold">{{ measurement.value.mean }}</td>
144            <td style="{{ result_style }}">{{ measurement.absdiff_str }}</td>
145            <td style="{{ result_style }}">{{ measurement.reldiff_str }}</td>
146          </tr>
147        {% endfor %}
148      {% else %}
149        <td style="font-weight: bold; color: red;">{{test.status }}</td>
150        <td></td> <td></td> <td></td> <td></td>
151      {% endif %}
152    {% endfor %}
153  </table>
154
155  {# Detailed test results #}
156  {% for test in test_data %}
157  <h2>{{ test.name }}: {{ test.description }}</h2>
158  <hr>
159    {% if test.status == 'SUCCESS' %}
160      {% for measurement in test.measurements %}
161        <div class="measurement">
162          <h3>{{ measurement.description }}</h3>
163          <div style="font-weight:bold;">
164            <span style="font-size: 23px;">{{ measurement.value.mean }}</span>
165            <span style="font-size: 20px; margin-left: 12px">
166            {% if measurement.absdiff > 0 %}
167            <span style="color: red">
168            {% elif measurement.absdiff == measurement.absdiff %}
169            <span style="color: green">
170            {% else %}
171            <span style="color: orange">
172            {% endif %}
173            {{ measurement.absdiff_str }} ({{measurement.reldiff_str}})
174            </span></span>
175          </div>
176          {# Table for trendchart and the statistics #}
177          <table style="width: 100%">
178            <tr>
179              <td style="width: 75%">
180                {# Linechart #}
181                <div id="{{ test.name }}_{{ measurement.name }}_chart"></div>
182              </td>
183              <td>
184                {# Measurement statistics #}
185                <table class="details plain">
186                  <tr>
187                    <th>Test runs</th><td>{{ measurement.value.sample_cnt }}</td>
188                  </tr><tr>
189                    <th>-/+</th><td>-{{ measurement.value.minus }} / +{{ measurement.value.plus }}</td>
190                  </tr><tr>
191                    <th>Min</th><td>{{ measurement.value.min }}</td>
192                  </tr><tr>
193                    <th>Max</th><td>{{ measurement.value.max }}</td>
194                  </tr><tr>
195                    <th>Stdev</th><td>{{ measurement.value.stdev }}</td>
196                  </tr><tr>
197                    <th><div id="{{ test.name }}_{{ measurement.name }}_chart_png"></div></th>
198                    <td></td>
199                  </tr>
200                </table>
201              </td>
202            </tr>
203          </table>
204
205          {# Task and recipe summary from buildstats #}
206          {% if 'buildstats' in measurement %}
207            Task resource usage
208            <table class="details" style="width:100%">
209              <tr>
210                <th>Number of tasks</th>
211                <th>Top consumers of cputime</th>
212              </tr>
213              <tr>
214                <td style="vertical-align: top">{{ measurement.buildstats.tasks.count }} ({{ measurement.buildstats.tasks.change }})</td>
215                {# Table of most resource-hungry tasks #}
216                <td>
217                  <table class="details plain">
218                    {% for diff in measurement.buildstats.top_consumer|reverse %}
219                    <tr>
220                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
221                      <td>{{ '%0.0f' % diff.value2 }} s</td>
222                    </tr>
223                    {% endfor %}
224                  </table>
225                </td>
226              </tr>
227              <tr>
228                <th>Biggest increase in cputime</th>
229                <th>Biggest decrease in cputime</th>
230              </tr>
231              <tr>
232                {# Table biggest increase in resource usage #}
233                <td>
234                  <table class="details plain">
235                    {% for diff in measurement.buildstats.top_increase|reverse %}
236                    <tr>
237                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
238                      <td>{{ '%+0.0f' % diff.absdiff }} s</td>
239                    </tr>
240                    {% endfor %}
241                  </table>
242                </td>
243                {# Table biggest decrease in resource usage #}
244                <td>
245                  <table class="details plain">
246                    {% for diff in measurement.buildstats.top_decrease %}
247                    <tr>
248                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
249                      <td>{{ '%+0.0f' % diff.absdiff }} s</td>
250                    </tr>
251                    {% endfor %}
252                  </table>
253                </td>
254              </tr>
255            </table>
256
257            {# Recipe version differences #}
258            {% if measurement.buildstats.ver_diff %}
259              <div style="margin-top: 16px">Recipe version changes</div>
260              <table class="details">
261                {% for head, recipes in measurement.buildstats.ver_diff.items() %}
262                  <tr>
263                    <th colspan="2">{{ head }}</th>
264                  </tr>
265                  {% for name, info in recipes|sort %}
266                    <tr>
267                      <td>{{ name }}</td>
268                      <td>{{ info }}</td>
269                    </tr>
270                  {% endfor %}
271                {% endfor %}
272              </table>
273            {% else %}
274              <div style="margin-top: 16px">No recipe version changes detected</div>
275            {% endif %}
276          {% endif %}
277        </div>
278      {% endfor %}
279    {# Unsuccessful test #}
280    {% else %}
281      <span style="font-size: 150%; font-weight: bold; color: red;">{{ test.status }}
282      {% if test.err_type %}<span style="font-size: 75%; font-weight: normal">({{ test.err_type }})</span>{% endif %}
283      </span>
284      <div class="preformatted">{{ test.message }}</div>
285    {% endif %}
286  {% endfor %}
287</div></body>
288</html>
289
290