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