This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 861cced IGNITE-9833 Use 24-hour clock format for X axis tick, refacot
code - Fixes #34.
861cced is described below
commit 861cced16477b2b24d590be80016eeca364a1229
Author: Nikolai Kulagin <[email protected]>
AuthorDate: Thu Oct 11 16:12:48 2018 +0300
IGNITE-9833 Use 24-hour clock format for X axis tick, refacot code - Fixes
#34.
Signed-off-by: Dmitriy Pavlov <[email protected]>
---
.../web/model/current/BuildStatisticsSummary.java | 11 +-
.../src/main/webapp/comparison.html | 194 ++++++++++++++-------
.../src/main/webapp/css/style-1.5.css | 8 +-
3 files changed, 138 insertions(+), 75 deletions(-)
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/BuildStatisticsSummary.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/BuildStatisticsSummary.java
index 8a428a5..d4a7bf6 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/BuildStatisticsSummary.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/BuildStatisticsSummary.java
@@ -64,8 +64,8 @@ public class BuildStatisticsSummary extends UpdateInfo
implements IBackgroundUpd
/** List of problem occurrences. */
private List<ProblemOccurrence> problemOccurrenceList;
- /** Duration printable. */
- public String durationPrintable;
+ /** Duration (seconds). */
+ public long duration;
/** Short build run result (without snapshot-dependencies printable
result). */
public Map<String, Long> totalProblems;
@@ -95,8 +95,7 @@ public class BuildStatisticsSummary extends UpdateInfo
implements IBackgroundUpd
testOccurrences = build.testOccurrences;
- durationPrintable = TimeUtil
- .millisToDurationPrintable(build.getFinishDate().getTime() -
build.getStartDate().getTime());
+ duration = (build.getFinishDate().getTime() -
build.getStartDate().getTime()) / 1000;
List<BuildRef> snapshotDependencies =
getSnapshotDependencies(teamcity, build);
@@ -228,13 +227,13 @@ public class BuildStatisticsSummary extends UpdateInfo
implements IBackgroundUpd
Objects.equals(startDate, that.startDate) &&
Objects.equals(testOccurrences, that.testOccurrences) &&
Objects.equals(problemOccurrenceList, that.problemOccurrenceList)
&&
- Objects.equals(durationPrintable, that.durationPrintable) &&
+ Objects.equals(duration, that.duration) &&
Objects.equals(totalProblems, that.totalProblems);
}
/** {@inheritDoc} */
@Override public int hashCode() {
return Objects.hash(buildId, startDate, testOccurrences,
problemOccurrenceList,
- durationPrintable, totalProblems, isFakeStub);
+ duration, totalProblems, isFakeStub);
}
}
diff --git a/ignite-tc-helper-web/src/main/webapp/comparison.html
b/ignite-tc-helper-web/src/main/webapp/comparison.html
index bc24084..fd62a47 100644
--- a/ignite-tc-helper-web/src/main/webapp/comparison.html
+++ b/ignite-tc-helper-web/src/main/webapp/comparison.html
@@ -23,18 +23,27 @@
<th width="5%"></th>
<th style="text-align: center;" width="40%"><input type='text'
name='daterange1'/></th>
<th style="text-align: center;" width="40%"><input type='text'
name='daterange2'/></th>
+ </tr><tr><td></td><td></td><td></td></tr>
+ <tr><td class="field">DURATION</td>
+ <td><img id="clickGraphDuration" src='/img/browser.png'></td>
+ <td class="mmm1 data1" id="Duration1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="Duration2" data-allow-highlight="true"></td>
+ </tr>
+ <tr id="showGraphDuration" style="display: none;"><td></td>
+ <td></td>
+ <td style="text-align: center;"><svg id="graphDuration1" width="500"
height="200"></svg></td>
+ <td style="text-align: center;"><svg id="graphDuration2" width="500"
height="200"></svg></td>
</tr>
- <tr style="display: none;"></tr><tr style="display: none;"></tr><tr
style="display: none;"></tr>
<tr id="showInfo" style="display: none;">
<td class="section">FEATURES</td><td></td>
<td style="text-align: center;" id="info1"></td>
<td style="text-align: center;" id="info2"></td>
</tr>
- <tr><td class="section">TESTS</td><td></td><td class="title1"></td><td
class="title2"></td></tr>
+ <tr><td class="section">TESTS</td><td></td><td class="title mmm1"></td><td
class="title mmm2"></td></tr>
<tr><td class="field">COUNT</td>
<td><img id="clickGraphCount" src='/img/browser.png'></td>
- <td class="data1" id="Count1" title="min - median - max"
data-allow-highlight="false"></td>
- <td class="data2" id="Count2" title="min - median - max"
data-allow-highlight="false"></td>
+ <td class="mmm1 data1" id="Count1" data-allow-highlight="false"></td>
+ <td class="mmm2 data2" id="Count2" data-allow-highlight="false"></td>
</tr>
<tr id="showGraphCount" style="display: none;"><td></td>
<td></td>
@@ -43,8 +52,8 @@
</tr>
<tr><td class="field">PASSED</td>
<td><img id="clickGraphPassed" src='/img/browser.png'></td>
- <td class="data1" id="Passed1" title="min - median - max"
data-allow-highlight="false"></td>
- <td class="data2" id="Passed2" title="min - median - max"
data-allow-highlight="false"></td>
+ <td class="mmm1 data1" id="Passed1" data-allow-highlight="false"></td>
+ <td class="mmm2 data2" id="Passed2" data-allow-highlight="false"></td>
</tr>
<tr id="showGraphPassed" style="display: none;"><td></td>
<td></td>
@@ -53,8 +62,8 @@
</tr>
<tr><td class="field">FAILED</td>
<td><img id="clickGraphFailed" src='/img/browser.png'></td>
- <td class="data1" id="Failed1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="Failed2" title="min - median - max"
data-allow-highlight="true"></td>
+ <td class="mmm1 data1" id="Failed1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="Failed2" data-allow-highlight="true"></td>
</tr>
<tr id="showGraphFailed" style="display: none;"><td></td>
<td></td>
@@ -63,8 +72,8 @@
</tr>
<tr><td class="field">IGNORED</td>
<td><img id="clickGraphIgnored" src='/img/browser.png'></td>
- <td class="data1" id="Ignored1" title="min - median - max"
data-allow-highlight="false"></td>
- <td class="data2" id="Ignored2" title="min - median - max"
data-allow-highlight="false"></td>
+ <td class="mmm1 data1" id="Ignored1" data-allow-highlight="false"></td>
+ <td class="mmm2 data2" id="Ignored2" data-allow-highlight="false"></td>
</tr>
<tr id="showGraphIgnored" style="display: none;"><td></td>
<td></td>
@@ -73,19 +82,19 @@
</tr>
<tr><td class="field">MUTED</td>
<td><img id="clickGraphMuted" src='/img/browser.png'></td>
- <td class="data1" id="Muted1" title="min - median - max"
data-allow-highlight="false"></td>
- <td class="data2" id="Muted2" title="min - median - max"
data-allow-highlight="false"></td></tr>
+ <td class="mmm1 data1" id="Muted1" data-allow-highlight="false"></td>
+ <td class="mmm2 data2" id="Muted2"
data-allow-highlight="false"></td></tr>
<tr id="showGraphMuted" style="display: none;"><td></td>
<td></td>
<td style="text-align: center;"><svg id="graphMuted1" width="500"
height="200"></svg></td>
<td style="text-align: center;"><svg id="graphMuted2" width="500"
height="200"></svg></td>
</tr>
- <tr><td class="section">PROBLEMS</td><td></td><td class="title1"></td><td
class="title2"></td></tr>
+ <tr><td class="section">PROBLEMS</td><td></td><td class="title
mmm1"></td><td class="title mmm2"></td></tr>
<tr style="display: none;"><td></td><td></td><td></td></tr>
<tr><td class="field">TOTAL</td>
<td><img id="clickGraphTT" src='/img/browser.png'></td>
- <td class="data1" id="TT1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="TT2" title="min - median - max"
data-allow-highlight="true"></td></tr>
+ <td class="mmm1 data1" id="TT1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="TT2" data-allow-highlight="true"></td></tr>
<tr id="showGraphTT" style="display: none;"><td></td>
<td></td>
<td style="text-align: center;"><svg id="graphTT1" width="500"
height="200"></svg></td>
@@ -93,8 +102,8 @@
</tr>
<tr><td class="field">EXECUTION TIMEOUT</td>
<td><img id="clickGraphET" src='/img/browser.png'></td>
- <td class="data1" id="ET1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="ET2" title="min - median - max"
data-allow-highlight="true"></td>
+ <td class="mmm1 data1" id="ET1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="ET2" data-allow-highlight="true"></td>
</tr>
<tr id="showGraphET" style="display: none;"><td></td>
<td></td>
@@ -103,8 +112,8 @@
</tr>
<tr><td class="field">JVM CRASH</td>
<td><img id="clickGraphJC" src='/img/browser.png'></td>
- <td class="data1" id="JC1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="JC2" title="min - median - max"
data-allow-highlight="true"></td>
+ <td class="mmm1 data1" id="JC1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="JC2" data-allow-highlight="true"></td>
</tr>
<tr id="showGraphJC" style="display: none;"><td></td>
<td></td>
@@ -113,8 +122,8 @@
</tr>
<tr><td class="field">OOME</td>
<td><img id="clickGraphOO" src='/img/browser.png'></td>
- <td class="data1" id="OO1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="OO2" title="min - median - max"
data-allow-highlight="true"></td>
+ <td class="mmm1 data1" id="OO1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="OO2" data-allow-highlight="true"></td>
</tr>
<tr id="showGraphOO" style="display: none;"><td></td>
<td></td>
@@ -123,26 +132,62 @@
</tr>
<tr><td class="field">EXIT CODE</td>
<td><img id="clickGraphEC" src='/img/browser.png'></td>
- <td class="data1" id="EC1" title="min - median - max"
data-allow-highlight="true"></td>
- <td class="data2" id="EC2" title="min - median - max"
data-allow-highlight="true"></td>
+ <td class="mmm1 data1" id="EC1" data-allow-highlight="true"></td>
+ <td class="mmm2 data2" id="EC2" data-allow-highlight="true"></td>
</tr>
<tr id="showGraphEC" style="display: none;"><td></td>
<td></td>
<td style="text-align: center;"><svg id="graphEC1" width="500"
height="200"></svg></td>
<td style="text-align: center;"><svg id="graphEC2" width="500"
height="200"></svg></td>
</tr>
+ <tr><td class="section">OTHER METRICS</td><td></td><td class="title
t1"></td><td class="title t2"></td></tr>
+ <tr style="display: none;"><td></td><td></td><td></td></tr>
+ <tr><td class="field">RUNS COUNT</td>
+ <td></td>
+ <td class="t1 data1" id="RunsCount1"></td>
+ <td class="t2 data2" id="RunsCount2"></td>
+ </tr>
</table><br>
<div id="version"></div>
<script>
- let oneWeekAgo = new Date();
- let twoWeekAgo = new Date();
- let g_updTimer = null;
+ let oneWeekAgo = new Date(),
+ twoWeekAgo = new Date(),
+ g_updTimer = null;
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
twoWeekAgo.setDate(twoWeekAgo.getDate() - 14);
+ const parseTime = d3.timeParse("%d-%m-%YT%H:%M:%S"),
+ formatTime = d3.timeFormat("%d-%m-%Y %H:%M:%S"),
+ formatMillisecond = d3.timeFormat(".%L"),
+ formatSecond = d3.timeFormat(":%S"),
+ formatMinute = d3.timeFormat("%H:%M"),
+ formatHour = d3.timeFormat("%H:%M"),
+ formatDay = d3.timeFormat("%a %e"),
+ formatWeek = d3.timeFormat("%b %e"),
+ formatMonth = d3.timeFormat("%B"),
+ formatYear = d3.timeFormat("%Y"),
+ parseDuration = d3.utcParse("%s");
+
+ const tOcc = ["Count", "Passed", "Failed", "Ignored", "Muted"],
+ prOcc = ["TT", "ET", "JC", "OO", "EC"],
+ mmmTitle = "min - median - max",
+ tTitle = "total",
+ duration = "Duration";
+
+ function multiFormat(date) {
+ return (d3.timeSecond(date) < date ? formatMillisecond
+ : d3.timeMinute(date) < date ? formatSecond
+ : d3.timeHour(date) < date ? formatMinute
+ : d3.timeDay(date) < date ? formatHour
+ : d3.timeMonth(date) < date ? (d3.timeWeek(date) <
date ? formatDay : formatWeek)
+ : d3.timeYear(date) < date ? formatMonth
+ : formatYear)(date);
+ }
+
function dateRangePickerParam(data1, data2) {
return {
+ "opens" : 'left',
"maxSpan": { "days": 7 },
"locale": {
"format": "DD/MM/YYYY", "separator": " - ", "applyLabel":
"Apply", "cancelLabel": "Cancel",
@@ -156,22 +201,27 @@
}
}
- const prOcc = ["TT", "ET", "JC", "OO", "EC"];
- const tOcc = ["Count", "Passed", "Failed", "Ignored", "Muted"];
-
function getMinMaxMedian(arr) {
let newArr = arr.slice();
newArr = newArr.sort(function(a, b){ return a - b; });
+
let i = newArr.length / 2;
+
let result = {};
- result.median = i % 1 == 0 ? (newArr[i - 1] + newArr[i]) / 2 :
newArr[Math.floor(i)];
+ result.median = i % 1 === 0 ? (newArr[i - 1] + newArr[i]) / 2 :
newArr[Math.floor(i)];
result.min = newArr[0];
result.max = newArr[newArr.length - 1];
+
return result;
}
function parseMedian(string) {
- return parseFloat(string.substring(string.indexOf("-") + 2,
string.lastIndexOf("-") - 1));
+ let stringMedian = string.substring(string.indexOf("-") + 2,
string.lastIndexOf("-") - 1);
+
+ if (stringMedian.indexOf(":") !== -1)
+ return (parseInt(stringMedian.split(":")[0]) * 60 +
parseInt(stringMedian.split(":")[1])) * 60;
+ else
+ return parseFloat(stringMedian);
}
function printStatistics(num, map, sinceDate, untilDate) {
@@ -179,11 +229,12 @@
clearGraphs(num);
const anotherNum = (num === 1) ? 2 : 1;
- const parseTime = d3.timeParse("%d-%m-%YT%H:%M:%S");
- let statistics = {};
- let dates = [];
- let buildIds = [];
+ let statistics = {},
+ dates = [],
+ buildIds = [];
+
+ statistics[duration] = [];
for (let i = 0; i < prOcc.length; i++) {
statistics[prOcc[i]] = [];
@@ -193,6 +244,7 @@
for (let j = 0; j < map.length; j++) {
dates[j] = parseTime(map[j].startDate);
buildIds[j] = map[j].buildId;
+ statistics[duration][j] = map[j].duration;
for (let i = 0; i < prOcc.length; i++) {
statistics[prOcc[i]][j] = map[j].totalProblems[prOcc[i]];
@@ -221,29 +273,42 @@
}
}
- $('.title' + num).html('min - median - max');
+ $('.title.mmm' + num).html(mmmTitle);
+ $('.mmm' + num).prop('title', mmmTitle);
+ $('.title.t' + num).html(tTitle);
+ $('.t' + num).prop('title', tTitle);
+
+ fillCellWithStatistics(duration, num, statistics, dates, buildIds);
for (let i = 0; i < prOcc.length; i++) {
fillCellWithStatistics(prOcc[i], num, statistics, dates, buildIds);
fillCellWithStatistics(tOcc[i], num, statistics, dates, buildIds);
}
+
+ $('#RunsCount' + num).html(map.length);
}
function fillCellWithStatistics(prefix, num, statistics, dates, buildIds) {
let result = getMinMaxMedian(statistics[prefix]);
- $('#' + prefix + num).html(result.min + " - " + result.median + " - "
+ result.max);
+ if (prefix === duration)
+ $('#' + prefix + num).html(time(result.min) + " - " +
time(result.median) + " - " + time(result.max));
+ else
+ $('#' + prefix + num).html(result.min + " - " + result.median + "
- " + result.max);
compareAndHighlight(prefix, num, result.median);
drawGraph(prefix, num, dates, statistics[prefix], buildIds);
+
+ function time(ms){
+ return moment(ms * 1000).utcOffset(0).format("H:mm");
+ }
}
function compareAndHighlight(prefix, thisNum, thisMedian){
- let anotherNum = (thisNum === 1) ? 2 : 1;
-
- let thisElement = $('#' + prefix + thisNum);
- let anotherElement = $('#' + prefix + anotherNum);
+ let anotherNum = (thisNum === 1) ? 2 : 1,
+ thisElement = $('#' + prefix + thisNum),
+ anotherElement = $('#' + prefix + anotherNum);
if (thisElement.data('allowHighlight').toString() === "true") {
let anotherMedian = parseMedian(anotherElement.text());
@@ -291,6 +356,7 @@
}
function clearGraphs(num) {
+ $("#graph" + duration + num).empty();
for (let i = 0; i < prOcc.length; i++) {
$("#graph" + prOcc[i] + num).empty();
$("#graph" + tOcc[i] + num).empty();
@@ -337,6 +403,8 @@
});
});
+ graphSpoiler(duration);
+
for (let i = 0; i < prOcc.length; i++) {
graphSpoiler(prOcc[i]);
graphSpoiler(tOcc[i]);
@@ -350,46 +418,39 @@
}
function drawGraph(prefix, num, dates, counts, buildIds) {
- let data = [];
+ let data = [],
+ isDuration = prefix === duration;
for (let i = 0; i < dates.length; i++) {
data[i] = {};
data[i].date = dates[i];
- data[i].value = counts[i];
+ data[i].value = (isDuration ? parseDuration(parseInt(counts[i])) :
counts[i]);
data[i].buildId = buildIds[i];
}
- let svg = d3.select("#graph" + prefix + num).append("svg:svg");
- let margin = {top: 20, right: 20, bottom: 30, left: 50};
- let width = +500 - margin.left - margin.right;
- let height = +200 - margin.top - margin.bottom;
- let g = svg.append("g").attr("transform", "translate(" + margin.left +
"," + margin.top + ")");
+ let svg = d3.select("#graph" + prefix + num).append("svg:svg"),
+ margin = {top: 20, right: 20, bottom: 30, left: 50},
+ width = 500 - margin.left - margin.right,
+ height = 200 - margin.top - margin.bottom,
+ g = svg.append("g").attr("transform", "translate(" + margin.left +
"," + margin.top + ")");
let div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
- let formatTime = d3.timeFormat("%d-%m-%Y %H:%M:%S");
- let max = d3.max(data, function(d){return parseInt(d.value)});
- let y = d3.scaleLinear()
- .domain([0, max])
- .range([height, 0]);
-
- let x = d3.scaleTime()
- .rangeRound([0, width]);
-
- x.domain(d3.extent(data, function(d) { return d.date; }));
+ let y = (isDuration ? d3.scaleTime() :
d3.scaleLinear()).range([height, 0]),
+ x = d3.scaleTime().rangeRound([0, width]);
let line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
- g.append("g")
- .attr("transform", "translate(0," + (height) + ")")
- .call(d3.axisBottom(x));
+ x.domain(d3.extent(data, function(d) { return d.date; }));
+ y.domain(d3.extent(data, function(d) { return d.value; }));
- g.append("g")
- .call(d3.axisLeft(y));
+ g.append("svg:g").attr("transform", "translate(0," + (height) + ")")
+ .call(d3.axisBottom(x).tickFormat(multiFormat));
+ g.append("svg:g").call(isDuration ?
d3.axisLeft(y).tickFormat(d3.utcFormat("%H:%M")) : d3.axisLeft(y));
let svg_aline = g.append("line")
.attr("class", "line")
@@ -426,8 +487,8 @@
.duration(200)
.style("opacity", .8);
- let graphTd = document.getElementById("graph" + prefix +
num).getBoundingClientRect();
- let scrollTop = window.pageYOffset ||
document.documentElement.scrollTop;
+ let graphTd = document.getElementById("graph" + prefix +
num).getBoundingClientRect(),
+ scrollTop = window.pageYOffset ||
document.documentElement.scrollTop;
div .html(formatTime(d.date))
.style("left", graphTd.left + x(d.date) + (x(d.date) >
(500 - 150) ? -150 : 0) + "px")
@@ -453,12 +514,13 @@
function getBuildLink(buildId) { return
"https://ci.ignite.apache.org/viewLog.html?buildId=" + buildId
+ "&tab=buildResultsDiv&buildTypeId=IgniteTests24Java8_RunAll"; }
-
+
function checkAvailable(buildId, date) {
let dateDiff = moment().diff(moment(date), 'days');
if (dateDiff <= 14) {
window.open(getBuildLink(buildId), '_blank');
+
return;
}
diff --git a/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css
b/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css
index d1065bd..ca6d537 100644
--- a/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css
+++ b/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css
@@ -209,9 +209,11 @@ form li:after
margin-top:10px;
}
-.compare{
- width: 80%;
+.compare {
+ width: 96%;
border-collapse: collapse;
+ margin-left: 2%;
+ margin-right: 2%;
}
.compare td, .compare th {
padding: 10px 5px 10px 5px;
@@ -237,7 +239,7 @@ form li:after
color: #000000;
}
-.compare .title1, .compare .title2 {
+.compare .title {
text-align: center;
font-size: 10px;
color: gray;