Implemented stats for external CIs
All CI votes are collected in new records with type 'ci_vote'. All standard statistics are available for these records. Also added a new "CI Status" report that shows summary of CI tests execution on merged patch sets, overall summary and results per merged change requests. List of CIs is taken from DriverLog's repo. Change-Id: Ic7a830dc5b331ba4c099be458ad2bab4c2072607
This commit is contained in:
272
stackalytics/dashboard/templates/reports/external_ci.html
Normal file
272
stackalytics/dashboard/templates/reports/external_ci.html
Normal file
@@ -0,0 +1,272 @@
|
||||
{% extends "reports/base_report.html" %}
|
||||
|
||||
{% block title %}
|
||||
External CI status for {{ module }} for the last {{ days }} days
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
|
||||
"ratio-pre": function (a) {
|
||||
if (a == "∞" || a == "-")
|
||||
return -1.0;
|
||||
a = a.substr(0, a.length - 1);
|
||||
return parseFloat(a);
|
||||
},
|
||||
|
||||
"ratio-asc": function (a, b) {
|
||||
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
|
||||
},
|
||||
|
||||
"ratio-desc": function (a, b) {
|
||||
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
|
||||
}
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
var table_column_names = ["name", "merge_run_count", "merge_success_rate", "merge_date_str", "merge_result",
|
||||
"total_run_count", "total_success_rate", "total_date_str"];
|
||||
var table_id = "summary_stats_table";
|
||||
|
||||
$.ajax({
|
||||
url: makeURI("/api/1.0/activity?project_type=all&metric=ci&module={{ module }}&release=all&start_date={{ start_date }}&page_size=-1"),
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
var activity = data["activity"];
|
||||
|
||||
var tableColumns = [];
|
||||
for (var i = 0; i < table_column_names.length; i++) {
|
||||
tableColumns.push({"mData": table_column_names[i]});
|
||||
}
|
||||
|
||||
var ci_map = {}; // ci_id -> statistics
|
||||
var res_map = {}; // ci_id -> map: review_id -> res
|
||||
var ci_id_to_name = {}; // ci_id -> name
|
||||
var review_ids = [];
|
||||
var review_ids_set = {};
|
||||
|
||||
for (i = 0; i < activity.length; i++) {
|
||||
var ai = activity[i];
|
||||
|
||||
if (ai.branch != "master") {
|
||||
continue;
|
||||
}
|
||||
|
||||
var ci_id = ai.user_id;
|
||||
|
||||
var ci = ci_map[ci_id];
|
||||
if (!ci) {
|
||||
ci = {total_run_count: 0, total_success: 0, merge_run_count: 0, merge_success: 0,
|
||||
merge_date: 0, total_date: 0, merge_result: "N/A",
|
||||
merge_date_str: "N/A", "total_date_str": "N/A"};
|
||||
}
|
||||
ci.id = ai.user_id;
|
||||
ci.name = "<a href=\"https://review.openstack.org/#/q/reviewer:" + ai.user_id +
|
||||
"+project:openstack/{{ module }},n,z\" target=\"_blank\">" + ai.user_id + "</a>";
|
||||
ci_id_to_name[ci_id] = ci.name;
|
||||
|
||||
ci.total_run_count ++;
|
||||
if (ai.ci_result) {
|
||||
ci.total_success ++;
|
||||
}
|
||||
if (ai.is_merged) {
|
||||
var review_id = ai.review_number;
|
||||
if (!review_ids_set[review_id]) {
|
||||
review_ids_set[review_id] = review_id;
|
||||
review_ids.push({review_id: review_id, date_str: ai.date_str});
|
||||
}
|
||||
|
||||
if (!res_map[ci_id]) {
|
||||
res_map[ci_id] = {};
|
||||
}
|
||||
res_map[ci_id][review_id] = ai.ci_result;
|
||||
|
||||
ci.merge_run_count ++;
|
||||
if (ai.ci_result) {
|
||||
ci.merge_success ++;
|
||||
}
|
||||
if (ai.date > ci.merge_date) {
|
||||
ci.merge_date = ai.date;
|
||||
ci.merge_date_str = ai.date_str;
|
||||
ci.merge_result = (ai.ci_result)? "<span style=\"color: green\">✔</span>":
|
||||
"<span style=\"color: red\">✖</span>";
|
||||
}
|
||||
}
|
||||
|
||||
if (ai.date > ci.total_date) {
|
||||
ci.total_date = ai.date;
|
||||
ci.total_date_str = ai.date_str;
|
||||
}
|
||||
ci_map[ci_id] = ci;
|
||||
}
|
||||
|
||||
var tableData = [];
|
||||
for (ci_id in ci_map) {
|
||||
var c = ci_map[ci_id];
|
||||
|
||||
if (c.merge_run_count > 0) {
|
||||
c.merge_success_rate = Math.round(c.merge_success / c.merge_run_count * 100) + "%";
|
||||
} else {
|
||||
c.merge_success_rate = "-";
|
||||
}
|
||||
|
||||
if (c.total_run_count > 0) {
|
||||
c.total_success_rate = Math.round(c.total_success / c.total_run_count * 100) + "%";
|
||||
} else {
|
||||
c.total_success_rate = "-";
|
||||
}
|
||||
tableData.push(c);
|
||||
}
|
||||
|
||||
$("#" + table_id).dataTable({
|
||||
"aaSorting": [
|
||||
[ 0, "asc"]
|
||||
],
|
||||
"bFilter": true,
|
||||
"bInfo": false,
|
||||
"bAutoWidth": false,
|
||||
"bPaginate": false,
|
||||
"iDisplayLength": -1,
|
||||
"aaData": tableData,
|
||||
"aoColumns": tableColumns,
|
||||
"aoColumnDefs": [
|
||||
{ "sClass": "center", "aTargets": [1, 2, 3, 4, 5, 6, 7] },
|
||||
{ "sType": "ratio", "aTargets": [2, 6]}
|
||||
]
|
||||
}).show();
|
||||
$("#" + table_id + "_loading").hide();
|
||||
|
||||
// make table with per-change-request status
|
||||
|
||||
var table = $("<table id='table_status'></table>");
|
||||
var table_head = $('<thead></thead>');
|
||||
table.append(table_head);
|
||||
var table_head_row = $("<tr></tr>");
|
||||
table_head.append(table_head_row);
|
||||
table_head_row.append($("<th rowspan='2'>CI</th>"));
|
||||
var table_second_head_row = $("<tr></tr>");
|
||||
table_head.append(table_second_head_row);
|
||||
var table_body = $("<tbody></tbody>");
|
||||
table.append(table_body);
|
||||
|
||||
var prev_date = null;
|
||||
var count = 0;
|
||||
|
||||
for (i = review_ids.length - 1; i >=0; i--) {
|
||||
var date_str = review_ids[i].date_str;
|
||||
var dp = date_str.split(" ");
|
||||
var date = dp[0] + " " + dp[1];
|
||||
|
||||
if (date != prev_date && count > 0) {
|
||||
table_head_row.append($("<th colspan='" + count + "'>" + prev_date + "</th>"));
|
||||
prev_date = date;
|
||||
count = 0;
|
||||
}
|
||||
prev_date = date;
|
||||
count++;
|
||||
table_second_head_row.append($("<th title='" + review_ids[i].review_id + "'></th>"));
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
table_head_row.append($("<th colspan='" + count + "'>" + prev_date + "</th>"));
|
||||
}
|
||||
|
||||
for (ci_id in ci_id_to_name) {
|
||||
var table_row = $("<tr></tr>");
|
||||
table_row.append($("<td>" + ci_id_to_name[ci_id] + "</td>"));
|
||||
|
||||
for (i = review_ids.length - 1; i >=0; i--) {
|
||||
var review_id = review_ids[i].review_id;
|
||||
|
||||
var color = "#cfcfcf";
|
||||
if (res_map[ci_id]) {
|
||||
var res = res_map[ci_id][review_id];
|
||||
if (res == true) {
|
||||
color = "#40bf00";
|
||||
} else if (res == false) {
|
||||
color = "#bf4000";
|
||||
}
|
||||
}
|
||||
const url = "https://review.openstack.org/#/c/" + review_id;
|
||||
var cell = $("<td></td>");
|
||||
cell.css("background-color", color).css("cursor", "pointer").prop("title", url);
|
||||
cell.click(function(evt) {
|
||||
window.open($(this).prop("title"));
|
||||
});
|
||||
table_row.append(cell);
|
||||
}
|
||||
table_body.append(table_row);
|
||||
}
|
||||
|
||||
$("#table_status_container").append(table);
|
||||
$("#table_status_container_loading").hide();
|
||||
|
||||
table.dataTable({
|
||||
"bPaginate": false,
|
||||
"iDisplayLength": -1
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
table.dataTable tr.even {
|
||||
background-color: #EEF1F4;
|
||||
}
|
||||
|
||||
table.dataTable tr.even:hover, table.dataTable tr.odd:hover {
|
||||
background-color: #F8FFEC;
|
||||
}
|
||||
|
||||
table.dataTable tr.even td.sorting_1 {
|
||||
background-color: #E0E8E8;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>External CI status for {{ module }} for the last {{ days }} days</h1>
|
||||
|
||||
<h2>Summary</h2>
|
||||
|
||||
<p>Overall stats for external CIs. <i>Merged patch sets</i> - results of test execution on the last patch set in the
|
||||
merged change request (assuming that it is almost the same as to run tests against master). <i>All patch sets</i> -
|
||||
results of test execution on all patch sets.</p>
|
||||
<p>List of CIs is taken from <a href="http://localhost:5000/report/driverlog">DriverLog</a> and can be updated by commit into its
|
||||
<a href="https://git.openstack.org/cgit/stackforge/driverlog/tree/etc/default_data.json">default_data.json</a></p>
|
||||
|
||||
<table id="summary_stats_table" style="display: none;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">CI</th>
|
||||
<th colspan="4" title="Stats for the last patch set in the merged change request">Merged patch sets</th>
|
||||
<th colspan="3">All patch sets</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Total runs</th>
|
||||
<th>Success, %</th>
|
||||
<th>Last run</th>
|
||||
<th>Last result</th>
|
||||
<th>Total runs</th>
|
||||
<th>Success, %</th>
|
||||
<th>Last run</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="summary_stats_table_loading" class="select2-loading" style="width: 7em;">Loading...</div>
|
||||
|
||||
<h2>Status for merged changed requests</h2>
|
||||
|
||||
<p>Status of CI test execution for every merged patch set grouped by days. Green cell - tests ran successfully,
|
||||
red cell - tests failed, grey cell - tests results not found.</p>
|
||||
|
||||
<div id="table_status_container"></div>
|
||||
<div id="table_status_container_loading" class="select2-loading" style="width: 7em;">Loading...</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user