HBASE-18076 Flaky dashboard improvement: Add status markers to show trends of failure/success.
This commit is contained in:
parent
958cd2d1b7
commit
c51c36fd1f
|
@ -41,6 +41,56 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script src="http://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>
|
<p>
|
||||||
<img style="vertical-align:middle; display:inline-block;" height="80px"
|
<img style="vertical-align:middle; display:inline-block;" height="80px"
|
||||||
src="https://hbase.apache.org/images/hbase_logo_with_orca_large.png">
|
src="https://hbase.apache.org/images/hbase_logo_with_orca_large.png">
|
||||||
|
@ -76,11 +126,13 @@
|
||||||
<a href="#">Go to top</a>
|
<a href="#">Go to top</a>
|
||||||
</span>
|
</span>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
|
Legend : green: success, red: failed, yellow: timeout, blue: hanging
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="400px">Test Name</th>
|
<th width="400px">Test Name</th>
|
||||||
<th width="150px">Flakyness</th>
|
<th width="150px">Flakyness</th>
|
||||||
<th width="200px">Failed/Timeout/Hanging</th>
|
<th width="200px">Failed/Timeout/Hanging</th>
|
||||||
|
<th width="300px">Trends</th>
|
||||||
<th>Run Ids</th>
|
<th>Run Ids</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for test in result %}
|
{% for test in result %}
|
||||||
|
@ -104,13 +156,19 @@
|
||||||
<td align="middle">
|
<td align="middle">
|
||||||
{{ failed|length }} / {{ timeout|length }} / {{ hanging|length }}
|
{{ failed|length }} / {{ timeout|length }} / {{ hanging|length }}
|
||||||
</td>
|
</td>
|
||||||
|
{% set sparkline_id = "sparkline_" ~ test ~ "_" ~ 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>
|
<td>
|
||||||
{% set id = "details_" ~ test ~ "_" ~ url_counter %}
|
{% set id = "details_" ~ test ~ "_" ~ url_counter %}
|
||||||
<button class="show_hide_button" onclick="toggle('{{ id }}')">
|
<button class="show_hide_button" onclick="toggle('{{ id }}')">
|
||||||
show/hide</button>
|
show/hide</button>
|
||||||
<br/>
|
<br/>
|
||||||
<div id="{{ id }}"
|
<div id="{{ id }}"
|
||||||
style="display: none; width:500px; white-space: normal">
|
style="display: none; width:300px; white-space: normal">
|
||||||
{% macro print_run_ids(url, run_ids) -%}
|
{% macro print_run_ids(url, run_ids) -%}
|
||||||
{% for i in run_ids %}
|
{% for i in run_ids %}
|
||||||
<a href="{{ url }}/{{ i }}">{{ i }}</a>
|
<a href="{{ url }}/{{ i }}">{{ i }}</a>
|
||||||
|
|
|
@ -125,6 +125,9 @@ all_hanging_tests = set()
|
||||||
# Contains { <url> : { <bad_test> : { 'all': [<build ids>], 'failed': [<build ids>],
|
# Contains { <url> : { <bad_test> : { 'all': [<build ids>], 'failed': [<build ids>],
|
||||||
# 'timeout': [<build ids>], 'hanging': [<builds ids>] } } }
|
# 'timeout': [<build ids>], 'hanging': [<builds ids>] } } }
|
||||||
url_to_bad_test_results = OrderedDict()
|
url_to_bad_test_results = OrderedDict()
|
||||||
|
# Contains { <url> : [run_ids] }
|
||||||
|
# Used for common min/max build ids when generating sparklines.
|
||||||
|
url_to_build_ids = OrderedDict()
|
||||||
|
|
||||||
# Iterates over each url, gets test results and prints flaky tests.
|
# Iterates over each url, gets test results and prints flaky tests.
|
||||||
expanded_urls = expand_multi_config_projects(args)
|
expanded_urls = expand_multi_config_projects(args)
|
||||||
|
@ -140,7 +143,7 @@ for url_max_build in expanded_urls:
|
||||||
logger.info("Analyzing build : %s", url)
|
logger.info("Analyzing build : %s", url)
|
||||||
build_id_to_results = {}
|
build_id_to_results = {}
|
||||||
num_builds = 0
|
num_builds = 0
|
||||||
build_ids = []
|
url_to_build_ids[url] = []
|
||||||
build_ids_without_tests_run = []
|
build_ids_without_tests_run = []
|
||||||
for build in builds:
|
for build in builds:
|
||||||
build_id = build["number"]
|
build_id = build["number"]
|
||||||
|
@ -154,9 +157,10 @@ for url_max_build in expanded_urls:
|
||||||
else:
|
else:
|
||||||
build_ids_without_tests_run.append(build_id)
|
build_ids_without_tests_run.append(build_id)
|
||||||
num_builds += 1
|
num_builds += 1
|
||||||
build_ids.append(build_id)
|
url_to_build_ids[url].append(build_id)
|
||||||
if num_builds == url_max_build["max_builds"]:
|
if num_builds == url_max_build["max_builds"]:
|
||||||
break
|
break
|
||||||
|
url_to_build_ids[url].sort()
|
||||||
|
|
||||||
# Collect list of bad tests.
|
# Collect list of bad tests.
|
||||||
bad_tests = set()
|
bad_tests = set()
|
||||||
|
@ -217,10 +221,10 @@ for url_max_build in expanded_urls:
|
||||||
len(test_status['hanging']), test_status['flakyness'])
|
len(test_status['hanging']), test_status['flakyness'])
|
||||||
else:
|
else:
|
||||||
print "No flaky tests founds."
|
print "No flaky tests founds."
|
||||||
if len(build_ids) == len(build_ids_without_tests_run):
|
if len(url_to_build_ids[url]) == len(build_ids_without_tests_run):
|
||||||
print "None of the analyzed builds have test result."
|
print "None of the analyzed builds have test result."
|
||||||
|
|
||||||
print "Builds analyzed: {}".format(build_ids)
|
print "Builds analyzed: {}".format(url_to_build_ids[url])
|
||||||
print "Builds without any test runs: {}".format(build_ids_without_tests_run)
|
print "Builds without any test runs: {}".format(build_ids_without_tests_run)
|
||||||
print ""
|
print ""
|
||||||
|
|
||||||
|
@ -248,4 +252,4 @@ with open(os.path.join(dev_support_dir, "flaky-dashboard-template.html"), "r") a
|
||||||
with open("dashboard.html", "w") as f:
|
with open("dashboard.html", "w") as f:
|
||||||
datetime = time.strftime("%m/%d/%Y %H:%M:%S")
|
datetime = time.strftime("%m/%d/%Y %H:%M:%S")
|
||||||
f.write(template.render(datetime=datetime, bad_tests_count=len(all_bad_tests),
|
f.write(template.render(datetime=datetime, bad_tests_count=len(all_bad_tests),
|
||||||
results=url_to_bad_test_results))
|
results=url_to_bad_test_results, build_ids=url_to_build_ids))
|
||||||
|
|
Loading…
Reference in New Issue