| <!-- |
| - Licensed to the Apache Software Foundation (ASF) under one |
| - or more contributor license agreements. See the NOTICE file |
| - distributed with this work for additional information |
| - regarding copyright ownership. The ASF licenses this file |
| - to you under the Apache License, Version 2.0 (the |
| - "License"); you may not use this file except in compliance |
| - with the License. You may obtain a copy of the License at |
| - |
| - http://www.apache.org/licenses/LICENSE-2.0 |
| - |
| - Unless required by applicable law or agreed to in writing, software |
| - distributed under the License is distributed on an "AS IS" BASIS, |
| - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| - See the License for the specific language governing permissions and |
| - limitations under the License. |
| --> |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Apache HBase Flaky Dashboard</title> |
| <style type="text/css"> |
| table { |
| table-layout: fixed; |
| } |
| th { |
| font-size: 15px; |
| } |
| td { |
| font-size: 18px; |
| vertical-align: text-top; |
| overflow: hidden; |
| white-space: nowrap; |
| } |
| .show_hide_button { |
| font-size: 100%; |
| padding: .5em 1em; |
| border: 0 rgba(0,0,0,0); |
| border-radius: 10px; |
| } |
| </style> |
| </head> |
| <body> |
| <script src="https://d3js.org/d3.v3.min.js"></script> |
| <script> |
| var width = 300; |
| var height = 25; |
| var x = d3.scale.linear().range([0, width]); |
| |
| function csvToArray(csv) { |
| if (csv.length == 0) |
| return []; |
| splits = csv.split(","); |
| ret = []; |
| for (i = 0; i < splits.length; i++) { |
| ret.push(parseInt(splits[i])); |
| } |
| return ret; |
| } |
| |
| function sortNumber(a,b) { |
| return a - b; |
| } |
| |
| function sparkline(elemId, failed, timeout, hanging, success, domain_min, domain_max) { |
| failed = csvToArray(failed); |
| timeout = csvToArray(timeout); |
| hanging = csvToArray(hanging); |
| success = csvToArray(success); |
| all = failed.concat(timeout).concat(hanging).concat(success); |
| all.sort(sortNumber); |
| x.domain([domain_min, domain_max + 1]); |
| rect_width = x(domain_min + 1) - x(domain_min) - 1; |
| svg = d3.select("#" + elemId).append('svg').attr('width', width).attr('height', height); |
| svg.selectAll("dot") |
| .data(all) |
| .enter() |
| .append("svg:rect") |
| .attr("x", function(d) { return x(d); }) |
| .attr("y", 3) |
| .attr("height", height- 6) |
| .attr("width", rect_width) |
| .attr("fill", function(d) { |
| if (success.includes(d)) return "green"; |
| else if (timeout.includes(d)) return "gold"; |
| else if (hanging.includes(d)) return "blue"; |
| else if (failed.includes(d)) return "red"; |
| else return "black"; |
| }) |
| .append('svg:title') |
| .text(function(d) { return d; }); |
| } |
| </script> |
| <p> |
| <img style="vertical-align:middle; display:inline-block;" height="80px" |
| src="https://hbase.apache.org/images/hbase_logo_with_orca_large.png"> |
| |
| <span style="font-size:50px; vertical-align:middle; display:inline-block;"> |
| Apache HBase Flaky Tests Dashboard |
| </span> |
| </p> |
| <span>Last updated: <b>{{datetime}}</b></span><br> |
| <span>Count of flaky tests (cumulated from all jobs): |
| <b>{{bad_tests_count}}</b></span><br> |
| <br><br> |
| <span style="font-size:20px;"><b>List of Jobs</b></span><br> |
| <br> |
| {% for url in results %} |
| <a href="#job_{{ loop.index }}">{{ url |e }}</a> |
| <br> |
| {% endfor %} |
| <br> |
| <br> |
| <span style="font-size:20px;"><b>Results</b></span><br> |
| <br> |
| {% for url in results %} |
| {% set result = results[url] %} |
| {% set url_counter = loop.index %} |
| {# Dedup ids since test names may duplicate across urls #} |
| <span id="job_{{ url_counter }}" style="font-weight:bold;"> |
| {{ url |e }}<br> |
| <a href="{{ url |e }}"> |
| Go to <img height="16px" src="https://jenkins.io/sites/default/files/jenkins_favicon.ico"> |
| </a> |
| |
| <a href="#">Go to top</a> |
| </span> |
| <br/><br/> |
| Legend : green: success, red: failed, yellow: timeout, blue: hanging |
| <table> |
| <tr> |
| <th width="400px">Test Name</th> |
| <th width="150px">Flakyness</th> |
| <th width="200px">Failed/Timeout/Hanging</th> |
| <th width="300px">Trends</th> |
| <th>Run Ids</th> |
| </tr> |
| {% for test in result %} |
| {% set all = result[test]['all'] %} |
| {% set failed = result[test]['failed'] %} |
| {% set timeout = result[test]['timeout'] %} |
| {% set hanging = result[test]['hanging'] %} |
| {% set success = result[test]['success'] %} |
| <tr> |
| <td>{{ test |e }}</td> |
| {% set flakyness = |
| (failed|length + hanging|length) * 100 / all|length %} |
| {% if flakyness == 100 %} |
| <td align="middle" style="background-color:#FF9999;"> |
| {% else %} |
| <td align="middle"> |
| {% endif %} |
| {{ "{:.1f}% ({} / {})".format( |
| flakyness, failed|length + hanging|length, all|length) }} |
| </td> |
| <td align="middle"> |
| {{ failed|length }} / {{ timeout|length }} / {{ hanging|length }} |
| </td> |
| {# Replace '.' in test names with '_' because dots are part of css selectors. #} |
| {% set sparkline_id = "sparkline_" ~ test|replace(".","_") ~ "_" ~ url_counter %} |
| <td id="{{ sparkline_id }}" align="middle"> |
| </td> |
| <script>sparkline("{{ sparkline_id }}", "{{ failed|join(',') }}", "{{ timeout|join(',') }}", |
| "{{ hanging|join(',') }}", "{{ success|join(',') }}", {{ build_ids[url][0] }}, |
| {{ build_ids[url][-1] }});</script> |
| <td> |
| {% set id = "details_" ~ test ~ "_" ~ url_counter %} |
| <button class="show_hide_button" onclick="toggle('{{ id }}')"> |
| show/hide</button> |
| <br/> |
| <div id="{{ id }}" |
| style="display: none; width:300px; white-space: normal"> |
| {% macro print_run_ids(url, run_ids) -%} |
| {% for i in run_ids %} |
| <a href="{{ url }}/{{ i }}">{{ i }}</a> |
| {% endfor %} |
| {%- endmacro %} |
| Failed : {{ print_run_ids(url, failed) }}<br/> |
| Timed Out : {{ print_run_ids(url, timeout) }}<br/> |
| Hanging : {{ print_run_ids(url, hanging) }}<br/> |
| Succeeded : {{ print_run_ids(url, success) }} |
| </div> |
| </td> |
| </tr> |
| {% endfor %} |
| </table> |
| <br><br><br> |
| {% endfor %} |
| <script type="text/javascript"> |
| function toggle(id) { |
| if (document.getElementById(id).style["display"] == "none") { |
| document.getElementById(id).style["display"] = "block"; |
| } else { |
| document.getElementById(id).style["display"] = "none"; |
| } |
| } |
| </script> |
| </body> |
| </html> |