diff --git a/stackalytics/dashboard/decorators.py b/stackalytics/dashboard/decorators.py
index 9235440b3..fe0cf5529 100644
--- a/stackalytics/dashboard/decorators.py
+++ b/stackalytics/dashboard/decorators.py
@@ -292,6 +292,28 @@ def mark_finalize(record):
return new_record
+def ci_filter(result, record, param_id, context):
+ result_by_param = result[getattr(record, param_id)]
+
+ result_by_param['metric'] += 1
+
+ key = 'success' if record.value else 'failure'
+ result_by_param[key] = result_by_param.get(key, 0) + 1
+
+
+def ci_finalize(record):
+ new_record = record.copy()
+
+ metric = record.get('metric')
+ if metric:
+ new_record['success_ratio'] = '%.1f%%' % (
+ (record.get('success', 0) * 100.0) / metric)
+ else:
+ new_record['success_rate'] = helpers.INFINITY_HTML
+
+ return new_record
+
+
def person_day_filter(result, record, param_id, context):
day = utils.timestamp_to_day(record.date)
# fact that record-days are grouped by days in some order is used
@@ -338,7 +360,7 @@ def aggregate_filter():
'resolved-bugs': (incremental_filter, None),
'members': (incremental_filter, None),
'person-day': (person_day_filter, None),
- 'ci': (None, None),
+ 'ci': (ci_filter, ci_finalize),
'patches': (None, None),
}
if metric not in metric_to_filters_map:
diff --git a/stackalytics/dashboard/reports.py b/stackalytics/dashboard/reports.py
index fe1b0f12b..94d7031fd 100644
--- a/stackalytics/dashboard/reports.py
+++ b/stackalytics/dashboard/reports.py
@@ -152,8 +152,8 @@ def contribution(module, days):
@decorators.templated()
@decorators.exception_handler()
def external_ci(module, days):
- if int(days) > 30:
- days = 30
+ if int(days) > 100:
+ days = 100
return {
'module': module,
diff --git a/stackalytics/dashboard/templates/_macros/activity_log.html b/stackalytics/dashboard/templates/_macros/activity_log.html
index fa5e8fda6..f82626da9 100644
--- a/stackalytics/dashboard/templates/_macros/activity_log.html
+++ b/stackalytics/dashboard/templates/_macros/activity_log.html
@@ -80,7 +80,7 @@ show_record_type=True, show_user_gravatar=True, gravatar_size=32, show_all=True)
{%/if%}
@@ -162,8 +162,8 @@ show_record_type=True, show_user_gravatar=True, gravatar_size=32, show_all=True)
- Parsed result: {%if value == true %}Success{%else%}Failure{%/if%}
- Message: ${message}
+ {%if value == true %}Success{%else%}Failure{%/if%}
+ ${message}
{%elif record_type == "member" %}
diff --git a/stackalytics/dashboard/templates/overview.html b/stackalytics/dashboard/templates/overview.html
index 9b4954486..08298417f 100644
--- a/stackalytics/dashboard/templates/overview.html
+++ b/stackalytics/dashboard/templates/overview.html
@@ -16,14 +16,15 @@
{% set show_user_profile = (user_id) %}
{% set show_module_details = (module) %}
{% set show_review_ratio = (metric in ['marks']) %}
+{% set show_ci = (metric in ['ci']) %}
{% macro show_report_links(module=None, company=None, user_id=None) -%}
{% if module %}
- {% if module_inst.ci %}
-
+ {% if module_inst.has_drivers %}
+
{% endif %}
{% endif %}
{% if company %}
@@ -46,6 +47,9 @@
{% if show_review_ratio %}
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id",
["index", "link", "mark_ratio", "metric"]);
+ {% elif show_ci %}
+ renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id",
+ ["index", "link", "metric", "success_ratio"]);
{% else %}
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id");
{% endif %}
@@ -95,11 +99,14 @@
# |
- Contributor |
+ {% if show_ci %}Driver{% else %}Contributor{% endif %} |
{% if show_review_ratio %}
-2|-1|+1|+2|A (+ ratio) |
{% endif %}
{{ metric_label }} |
+ {% if show_ci %}
+ Success |
+ {% endif %}
diff --git a/stackalytics/dashboard/templates/reports/external_ci.html b/stackalytics/dashboard/templates/reports/external_ci.html
index 636a5b01e..4eb77cf37 100644
--- a/stackalytics/dashboard/templates/reports/external_ci.html
+++ b/stackalytics/dashboard/templates/reports/external_ci.html
@@ -25,8 +25,7 @@ External CI status for {{ module }} for the last {{ days }} days
});
$(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_column_names = ["name", "merge_run_count", "merge_success_rate", "merge_date_str", "merge_result"];
var table_id = "summary_stats_table";
$.ajax({
@@ -49,55 +48,41 @@ External CI status for {{ module }} for the last {{ days }} days
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",
+ ci = {merge_run_count: 0, merge_success: 0,
+ merge_date: 0, merge_result: "N/A",
merge_date_str: "N/A", "total_date_str": "N/A"};
}
ci.id = ai.user_id;
- ci.name = "" + ai.user_id + "";
+ ci.name = "" + ai.driver_name + "";
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)? "✔":
- "✖";
- }
+ 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 (ai.date > ci.total_date) {
- ci.total_date = ai.date;
- ci.total_date_str = ai.date_str;
+ if (!res_map[ci_id]) {
+ res_map[ci_id] = {};
}
+ res_map[ci_id][review_id] = ai.value;
+
+ ci.merge_run_count ++;
+ if (ai.value) {
+ 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.value)? "✔":
+ "✖";
+ }
+
ci_map[ci_id] = ci;
}
@@ -106,16 +91,11 @@ External CI status for {{ module }} for the last {{ days }} days
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) + "%";
+ c.merge_success_rate = Math.round(100 * c.merge_success / c.merge_run_count) + "%";
} 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);
}
@@ -131,8 +111,8 @@ External CI status for {{ module }} for the last {{ days }} days
"aaData": tableData,
"aoColumns": tableColumns,
"aoColumnDefs": [
- { "sClass": "center", "aTargets": [1, 2, 3, 4, 5, 6, 7] },
- { "sType": "ratio", "aTargets": [2, 6]}
+ { "sClass": "center", "aTargets": [1, 2, 3, 4] },
+ { "sType": "ratio", "aTargets": [2]}
]
}).show();
$("#" + table_id + "_loading").hide();
@@ -144,7 +124,7 @@ External CI status for {{ module }} for the last {{ days }} days
table.append(table_head);
var table_head_row = $("
");
table_head.append(table_head_row);
- table_head_row.append($("CI | "));
+ table_head_row.append($("Driver | "));
var table_second_head_row = $("
");
table_head.append(table_second_head_row);
var table_body = $("");
@@ -165,7 +145,8 @@ External CI status for {{ module }} for the last {{ days }} days
}
prev_date = date;
count++;
- table_second_head_row.append($(" | "));
+ table_second_head_row.append($("" + review_ids[i].review_id + " | "));
}
if (count > 0) {
@@ -180,19 +161,23 @@ External CI status for {{ module }} for the last {{ days }} days
var review_id = review_ids[i].review_id;
var color = "#cfcfcf";
+ var title = "N/A";
+
if (res_map[ci_id]) {
var res = res_map[ci_id][review_id];
if (res == true) {
color = "#40bf00";
+ title = "SUCCESS";
} else if (res == false) {
color = "#bf4000";
+ title = "FAILURE";
}
}
const url = "https://review.openstack.org/#/c/" + review_id;
var cell = $(" | ");
- cell.css("background-color", color).css("cursor", "pointer").prop("title", url);
+ cell.css("background-color", color).css("cursor", "pointer").prop("url", url).prop("title", title + " - " + url);
cell.click(function(evt) {
- window.open($(this).prop("title"));
+ window.open($(this).prop("url"));
});
table_row.append(cell);
}
@@ -228,31 +213,24 @@ External CI status for {{ module }} for the last {{ days }} days
{% endblock %}
{% block content %}
-External CI status for {{ module }} for the last {{ days }} days
+Status of drivers testing in {{ module|title }} during recent {{ days }} days
-Summary
+List of drivers is taken from DriverLog.
+ The status is based on job results from the latest patch in merged change requests (thus assuming that the job is executed on code close to the master).
+ Missing or misconfigured drivers can be updated by commit into DriverLog's
+ default_data.json.
+
- Overall stats for external CIs. Merged patch sets - 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). All patch sets -
- results of test execution on all patch sets.
- List of CIs is taken from DriverLog and can be updated by commit into its
- default_data.json
+Drivers summary
- CI |
- Merged patch sets |
- All patch sets |
-
-
- Total runs |
+ Driver |
+ CI votes |
Success, % |
- Last run |
- Last result |
- Total runs |
- Success, % |
- Last run |
+ Latest run |
+ Latest result |
@@ -261,10 +239,7 @@ External CI status for {{ module }} for the last {{ days }} days
Loading...
-Status for merged changed requests
-
- 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.
+Status per change requests
Loading...
diff --git a/stackalytics/dashboard/web.py b/stackalytics/dashboard/web.py
index 2d0b2be58..c1a1d7afe 100644
--- a/stackalytics/dashboard/web.py
+++ b/stackalytics/dashboard/web.py
@@ -587,6 +587,8 @@ def timeline(records, **kwargs):
if ('commits' in metric) or ('loc' in metric):
handler = lambda record: record.loc
+ elif 'ci' in metric:
+ handler = lambda record: 0 if record.value else 1
else:
handler = lambda record: 0