Index: Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
diff --git a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
index 3120ed478b34b09b27b5176c8aab6b6983606783..035c50885013b7228c0612117ebddbe7b2697bac 100644 |
--- a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
+++ b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
@@ -537,12 +537,18 @@ function showPopupForBuild(e, builder, index, opt_testName) |
ui.popup.show(e.target, html); |
} |
+function showPopupForInterpolatedResult(e, revision) |
+{ |
+ var html = 'This bot did not run the test for r' + revision + '.'; |
+ ui.popup.show(e.target, html); |
+} |
+ |
function classNameForFailureString(failure) |
{ |
return failure.replace(/(\+|\ )/, ''); |
} |
-function htmlForTestResults(test) |
+function htmlForTestResults(test, revisions) |
{ |
var html = ''; |
var testResults = test.rawResults.concat(); |
@@ -551,10 +557,18 @@ function htmlForTestResults(test) |
var master = builders.master(builder); |
var buildNumbers = g_resultsByBuilder[builder].buildNumbers; |
+ // FIXME: Support other revision types instead of just chrome/blink. |
+ var revisionType = g_history.isBlinkGroup() ? |
+ results.BLINK_REVISIONS : results.CHROME_REVISIONS; |
+ |
+ var cells = []; |
+ for (var index = 0; index < revisions.length; index++) |
+ cells.push({revision: revisions[index]}); |
+ |
var indexToReplaceCurrentResult = -1; |
var indexToReplaceCurrentTime = -1; |
for (var i = 0; i < buildNumbers.length; i++) { |
- var currentResultArray, currentTimeArray, innerHTML, resultString; |
+ var currentResultArray, currentTimeArray, currentTime, resultString; |
if (i > indexToReplaceCurrentResult) { |
currentResultArray = testResults.shift(); |
@@ -569,22 +583,76 @@ function htmlForTestResults(test) |
if (i > indexToReplaceCurrentTime) { |
currentTimeArray = times.shift(); |
- var currentTime = 0; |
+ currentTime = 0; |
if (currentResultArray) { |
currentTime = currentTimeArray[results.RLE.VALUE]; |
indexToReplaceCurrentTime += currentTimeArray[results.RLE.LENGTH]; |
} else |
indexToReplaceCurrentTime += buildNumbers.length; |
+ } |
+ |
+ var revision = parseInt( |
+ g_resultsByBuilder[builder][revisionType][i], 10); |
- innerHTML = currentTime || ' '; |
+ // Locate the empty cell corresponding to this blink revision. |
+ var cell = undefined; |
+ for (var index = 0; index < cells.length; index++) { |
+ if (cells[index].revision == revision && !cells[index].html) { |
+ cell = cells[index]; |
+ break; |
+ } |
} |
- html += '<td title="' + resultString + '. Click for more info." class="results ' + classNameForFailureString(resultString) + |
- '" onclick=\'showPopupForBuild(event, "' + builder + '",' + i + ',"' + test.test + '")\'>' + innerHTML; |
+ cell.className = classNameForFailureString(resultString); |
+ cell.hasResult = |
+ resultString !== results.NO_DATA && resultString !== results.NOTRUN; |
+ cell.html = '<td' |
+ + ' title="' + resultString + '. Click for more info."' |
+ + ' class="results ' + cell.className + '"' |
+ + ' onclick=\'showPopupForBuild(event,' |
+ + ' "' + builder + '",' + i + ',"' + test.test + '")\'>' |
+ + (currentTime || (cell.hasResult ? '' : '?')) + '</td>'; |
} |
+ |
+ populateEmptyCells(cells); |
+ |
+ for (var index = 0; index < cells.length; index++) |
+ html += cells[index].html; |
+ |
return html; |
} |
+// Fill in cells where no test data is available with a question mark. |
+// If the next and previous runs were equal, an "interpolated" result is shown. |
+function populateEmptyCells(cells) |
+{ |
+ for (var index = 1; index < cells.length; index++) { |
+ var prevCell = cells[index - 1]; |
+ cells[index].nextClassName = |
+ prevCell.hasResult ? prevCell.className : prevCell.nextClassName; |
+ } |
+ |
+ for (var index = cells.length - 2; index >= 0; --index) { |
+ var nextCell = cells[index + 1]; |
+ cells[index].prevClassName = |
+ nextCell.hasResult ? nextCell.className : nextCell.prevClassName; |
+ } |
+ |
+ cells.forEach(function(cell) { |
+ if (!cell.html) { |
+ var interpolateResult = |
+ cell.nextClassName && cell.nextClassName == cell.prevClassName; |
+ cell.className = interpolateResult ? cell.nextClassName : "NODATA"; |
+ cell.html = '<td' |
+ + ' title="Unknown result. Did not run tests."' |
+ + ' onclick=\'showPopupForInterpolatedResult(event,' |
+ + ' ' + cell.revision + ')\'' |
+ + ' class="results interpolatedResult ' + cell.className + '"' |
+ + ' >?</td>'; |
+ } |
+ }); |
+} |
+ |
function shouldShowTest(testResult) |
{ |
if (!g_history.isLayoutTestResults()) |
@@ -649,7 +717,7 @@ function linkifyBugs(bugs) |
return html; |
} |
-function htmlForSingleTestRow(test, showBuilderNames) |
+function htmlForSingleTestRow(test, showBuilderNames, revisions) |
{ |
var headers = tableHeaders(); |
var html = ''; |
@@ -667,7 +735,7 @@ function htmlForSingleTestRow(test, showBuilderNames) |
else if (string.startsWith(header, 'slowest')) |
html += '<td>' + (test.slowestTime ? test.slowestTime + 's' : ''); |
else if (string.startsWith(header, 'flakiness')) |
- html += htmlForTestResults(test); |
+ html += htmlForTestResults(test, revisions); |
} |
return html; |
} |
@@ -783,6 +851,47 @@ function sortTests(tests, column, order) |
tests.sort(sortFunctionGetter(resultsProperty, order == BACKWARD)); |
} |
+// Return an array of revisions across all builders such that all of a builder's |
+// builds have a unique entry in the list. The currently selected group |
+// (e.g., @ToT Chromium) determines which revision type is not collapsed. |
+// Note that revisions may not be unique: a single builder can have two runs at |
+// the same blink revision but different chrome revisions which will result in |
+// multiple entries of the same blink revision. |
+function collapsedRevisionList(testResults) |
+{ |
+ // FIXME: Support other revision types instead of just chrome/blink. |
+ var revisionType = g_history.isBlinkGroup() ? |
+ results.BLINK_REVISIONS : results.CHROME_REVISIONS; |
+ |
+ var revisionsCountedSet = {}; |
+ for (var resultIndex = 0; resultIndex < testResults.length; resultIndex++) { |
+ var builder = testResults[resultIndex].builder; |
+ var build = g_resultsByBuilder[builder]; |
+ var buildNumbers = build.buildNumbers; |
+ var builderRevisionsCountedSet = {}; |
+ for (var i = 0; i < buildNumbers.length; i++) { |
+ var revision = build[revisionType][i]; |
+ builderRevisionsCountedSet[revision] = |
+ (builderRevisionsCountedSet[revision] || 0) + 1; |
+ } |
+ |
+ // Join builder's revisions with the total revisions for all builders. |
+ for (var revision in builderRevisionsCountedSet) |
+ revisionsCountedSet[revision] = Math.max(revisionsCountedSet[revision] || 0, builderRevisionsCountedSet[revision]); |
+ } |
+ |
+ var revisionsArray = []; |
+ for (var revision in revisionsCountedSet) { |
+ for (var i = revisionsCountedSet[revision] - 1; i >= 0; --i) |
+ revisionsArray.push(revision); |
+ } |
+ |
+ revisionsArray.sort(function(a, b) { |
+ return (b - a); |
+ }); |
+ return revisionsArray; |
+} |
+ |
function htmlForIndividualTestOnAllBuilders(test) |
{ |
processTestRunsForAllBuilders(); |
@@ -793,10 +902,11 @@ function htmlForIndividualTestOnAllBuilders(test) |
var html = ''; |
var shownBuilders = []; |
+ var revisions = collapsedRevisionList(testResults); |
for (var j = 0; j < testResults.length; j++) { |
shownBuilders.push(testResults[j].builder); |
var showBuilderNames = true; |
- html += htmlForSingleTestRow(testResults[j], showBuilderNames); |
+ html += htmlForSingleTestRow(testResults[j], showBuilderNames, revisions); |
} |
var skippedBuilders = [] |
@@ -1261,8 +1371,9 @@ function generatePageForBuilder(builderName) |
if (filteredResults.length) { |
var tableRowsHTML = ''; |
var showBuilderNames = false; |
+ var revisions = collapsedRevisionList(filteredResults); |
for (var i = 0; i < filteredResults.length; i++) |
- tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames) |
+ tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames, revisions); |
testsHTML = htmlForTestTable(tableRowsHTML); |
} else { |
if (g_history.isLayoutTestResults()) |