HBASE-20387 turn flaky test tracking infra into per-branch pipeline.
[hbase.git] / dev-support / flaky-tests / flaky-dashboard-template.html
blobf37c7d5f53d7c650b0c30fac5bc6005443f8cc6f
1 <!--
2 - Licensed to the Apache Software Foundation (ASF) under one
3 - or more contributor license agreements. See the NOTICE file
4 - distributed with this work for additional information
5 - regarding copyright ownership. The ASF licenses this file
6 - to you under the Apache License, Version 2.0 (the
7 - "License"); you may not use this file except in compliance
8 - with the License. You may obtain a copy of the License at
10 - http://www.apache.org/licenses/LICENSE-2.0
12 - Unless required by applicable law or agreed to in writing, software
13 - distributed under the License is distributed on an "AS IS" BASIS,
14 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 - See the License for the specific language governing permissions and
16 - limitations under the License.
17 -->
18 <!DOCTYPE html>
19 <html>
20 <head>
21 <title>Apache HBase Flaky Dashboard</title>
22 <style type="text/css">
23 table {
24 table-layout: fixed;
26 th {
27 font-size: 15px;
29 td {
30 font-size: 18px;
31 vertical-align: text-top;
32 overflow: hidden;
33 white-space: nowrap;
35 .show_hide_button {
36 font-size: 100%;
37 padding: .5em 1em;
38 border: 0 rgba(0,0,0,0);
39 border-radius: 10px;
41 </style>
42 </head>
43 <body>
44 <script src="https://d3js.org/d3.v3.min.js"></script>
45 <script>
46 var width = 300;
47 var height = 25;
48 var x = d3.scale.linear().range([0, width]);
50 function csvToArray(csv) {
51 if (csv.length == 0)
52 return [];
53 splits = csv.split(",");
54 ret = [];
55 for (i = 0; i < splits.length; i++) {
56 ret.push(parseInt(splits[i]));
58 return ret;
61 function sortNumber(a,b) {
62 return a - b;
65 function sparkline(elemId, failed, timeout, hanging, success, domain_min, domain_max) {
66 failed = csvToArray(failed);
67 timeout = csvToArray(timeout);
68 hanging = csvToArray(hanging);
69 success = csvToArray(success);
70 all = failed.concat(timeout).concat(hanging).concat(success);
71 all.sort(sortNumber);
72 x.domain([domain_min, domain_max + 1]);
73 rect_width = x(domain_min + 1) - x(domain_min) - 1;
74 svg = d3.select("#" + elemId).append('svg').attr('width', width).attr('height', height);
75 svg.selectAll("dot")
76 .data(all)
77 .enter()
78 .append("svg:rect")
79 .attr("x", function(d) { return x(d); })
80 .attr("y", 3)
81 .attr("height", height- 6)
82 .attr("width", rect_width)
83 .attr("fill", function(d) {
84 if (success.includes(d)) return "green";
85 else if (timeout.includes(d)) return "gold";
86 else if (hanging.includes(d)) return "blue";
87 else if (failed.includes(d)) return "red";
88 else return "black";
90 .append('svg:title')
91 .text(function(d) { return d; });
93 </script>
94 <p>
95 <img style="vertical-align:middle; display:inline-block;" height="80px"
96 src="https://hbase.apache.org/images/hbase_logo_with_orca_large.png">
97 &nbsp;&nbsp;&nbsp;&nbsp;
98 <span style="font-size:50px; vertical-align:middle; display:inline-block;">
99 Apache HBase Flaky Tests Dashboard
100 </span>
101 </p>
102 <span>Last updated: <b>{{datetime}}</b></span><br>
103 <span>Count of flaky tests (cumulated from all jobs):
104 <b>{{bad_tests_count}}</b></span><br>
105 <br><br>
106 <span style="font-size:20px;"><b>List of Jobs</b></span><br>
107 <br>
108 {% for url in results %}
109 <a href="#job_{{ loop.index }}">{{ url |e }}</a>
110 <br>
111 {% endfor %}
112 <br>
113 <br>
114 <span style="font-size:20px;"><b>Results</b></span><br>
115 <br>
116 {% for url in results %}
117 {% set result = results[url] %}
118 {% set url_counter = loop.index %}
119 {# Dedup ids since test names may duplicate across urls #}
120 <span id="job_{{ url_counter }}" style="font-weight:bold;">
121 {{ url |e }}<br>
122 <a href="{{ url |e }}">
123 Go to <img height="16px" src="https://jenkins.io/sites/default/files/jenkins_favicon.ico">
124 </a>
125 &nbsp;&nbsp;&nbsp;&nbsp;
126 <a href="#">Go to top</a>
127 </span>
128 <br/><br/>
129 Legend : green: success, red: failed, yellow: timeout, blue: hanging
130 <table>
131 <tr>
132 <th width="400px">Test Name</th>
133 <th width="150px">Flakyness</th>
134 <th width="200px">Failed/Timeout/Hanging</th>
135 <th width="300px">Trends</th>
136 <th>Run Ids</th>
137 </tr>
138 {% for test in result %}
139 {% set all = result[test]['all'] %}
140 {% set failed = result[test]['failed'] %}
141 {% set timeout = result[test]['timeout'] %}
142 {% set hanging = result[test]['hanging'] %}
143 {% set success = result[test]['success'] %}
144 <tr>
145 <td>{{ test |e }}</td>
146 {% set flakyness =
147 (failed|length + hanging|length) * 100 / all|length %}
148 {% if flakyness == 100 %}
149 <td align="middle" style="background-color:#FF9999;">
150 {% else %}
151 <td align="middle">
152 {% endif %}
153 {{ "{:.1f}% ({} / {})".format(
154 flakyness, failed|length + hanging|length, all|length) }}
155 </td>
156 <td align="middle">
157 {{ failed|length }} / {{ timeout|length }} / {{ hanging|length }}
158 </td>
159 {# Replace '.' in test names with '_' because dots are part of css selectors. #}
160 {% set sparkline_id = "sparkline_" ~ test|replace(".","_") ~ "_" ~ url_counter %}
161 <td id="{{ sparkline_id }}" align="middle">
162 </td>
163 <script>sparkline("{{ sparkline_id }}", "{{ failed|join(',') }}", "{{ timeout|join(',') }}",
164 "{{ hanging|join(',') }}", "{{ success|join(',') }}", {{ build_ids[url][0] }},
165 {{ build_ids[url][-1] }});</script>
166 <td>
167 {% set id = "details_" ~ test ~ "_" ~ url_counter %}
168 <button class="show_hide_button" onclick="toggle('{{ id }}')">
169 show/hide</button>
170 <br/>
171 <div id="{{ id }}"
172 style="display: none; width:300px; white-space: normal">
173 {% macro print_run_ids(url, run_ids) -%}
174 {% for i in run_ids %}
175 <a href="{{ url }}/{{ i }}">{{ i }}</a>&nbsp;
176 {% endfor %}
177 {%- endmacro %}
178 Failed : {{ print_run_ids(url, failed) }}<br/>
179 Timed Out : {{ print_run_ids(url, timeout) }}<br/>
180 Hanging : {{ print_run_ids(url, hanging) }}<br/>
181 Succeeded : {{ print_run_ids(url, success) }}
182 </div>
183 </td>
184 </tr>
185 {% endfor %}
186 </table>
187 <br><br><br>
188 {% endfor %}
189 <script type="text/javascript">
190 function toggle(id) {
191 if (document.getElementById(id).style["display"] == "none") {
192 document.getElementById(id).style["display"] = "block";
193 } else {
194 document.getElementById(id).style["display"] = "none";
197 </script>
198 </body>
199 </html>