<!--
 - 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">
    &nbsp;&nbsp;&nbsp;&nbsp;
              <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>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <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>&nbsp;
                {% 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>
