Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1887)

Unified Diff: webkit/tools/layout_tests/flakiness_dashboard.html

Issue 195081: Flakiness dashboard changes:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/tools/layout_tests/flakiness_dashboard.html
===================================================================
--- webkit/tools/layout_tests/flakiness_dashboard.html (revision 26165)
+++ webkit/tools/layout_tests/flakiness_dashboard.html (working copy)
@@ -15,6 +15,10 @@
font-size: 16px;
margin-bottom: .25em;
}
+ h3 {
+ font-size: 13px;
+ margin: 0;
+ }
#max-results-form {
display: inline;
}
@@ -124,6 +128,12 @@
.O {
background-color: #69f;
}
+ .merge {
+ background-color: green;
+ }
+ :not(#legend) > .merge {
+ width: 1px;
+ }
.separator {
border: 1px solid lightgray;
height: 0px;
@@ -136,10 +146,10 @@
font-weight: bold;
}
#passing-tests {
- -webkit-column-count: 2;
+ -webkit-column-count: 3;
-webkit-column-gap: 25px;
-webkit-column-rule: 1px dashed black;
- -moz-column-count: 2;
+ -moz-column-count: 3;
-moz-column-gap: 25px;
-moz-column-rule: 1px dashed black;
}
@@ -157,6 +167,26 @@
text-align: center;
font-weight: bold;
}
+ #popup {
+ background-color: white;
+ overflow: hidden;
+ width: 250px;
+ z-index: 1;
+ position: absolute;
+ border: 3px solid grey;
+ padding: 3px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ }
+ #popup > * {
+ width: 100%;
+ }
+ #popup > ul {
+ margin: 0;
+ padding-left: 20px;
+ }
</style>
<script>
@@ -177,39 +207,44 @@
* -add the builder name to the list of builders below.
*/
- // CONSTANTS
- var FORWARD = 'forward';
- var BACKWARD = 'backward';
- var TEST_URL_BASE_PATH =
- 'http://trac.webkit.org/projects/webkit/browser/trunk/';
- var BUILDERS_BASE_PATH =
- 'http://build.chromium.org/buildbot/waterfall/builders/';
- var EXPECTATIONS_MAP = {
- 'T': 'TIMEOUT',
- 'C': 'CRASH',
- 'P': 'PASS',
- 'F': 'TEXT FAIL',
- 'S': 'SIMPLIFIED',
- 'I': 'IMAGE',
- 'O': 'OTHER',
- 'N': 'NO DATA'
- };
- var PLATFORMS = {'MAC': 'MAC', 'LINUX': 'LINUX', 'WIN': 'WIN'};
- var BUILD_TYPES = {'DEBUG': 'DBG', 'RELEASE': 'RELEASE'};
+ // CONSTANTS
+ var FORWARD = 'forward';
+ var BACKWARD = 'backward';
+ var TEST_URL_BASE_PATH =
+ 'http://trac.webkit.org/projects/webkit/browser/trunk/';
+ var BUILDERS_BASE_PATH =
+ 'http://build.chromium.org/buildbot/waterfall/builders/';
+ var TEST_RESULTS_BASE_PATH =
+ 'http://build.chromium.org/buildbot/layout_test_results/';
+ var EXPECTATIONS_MAP = {
+ 'T': 'TIMEOUT',
+ 'C': 'CRASH',
+ 'P': 'PASS',
+ 'F': 'TEXT FAIL',
+ 'S': 'SIMPLIFIED',
+ 'I': 'IMAGE',
+ 'O': 'OTHER',
+ 'N': 'NO DATA'
+ };
+ var PLATFORMS = {'MAC': 'MAC', 'LINUX': 'LINUX', 'WIN': 'WIN'};
+ var BUILD_TYPES = {'DEBUG': 'DBG', 'RELEASE': 'RELEASE'};
- // GLOBALS
- // The DUMMYVALUE gets shifted off the array in the first call to
- // generatePage.
- var tableHeaders = ['DUMMYVALUE', 'bugs', 'modifiers', 'expectations',
- 'missing', 'extra', 'slowest run',
- 'flakiness (numbers are runtimes in seconds)'];
- var perBuilderPlatformAndBuildType = {};
- var perBuilderFailures = {};
- // Map of builder to arrays of tests that are listed in the expectations file
- // but have for that builder.
- var perBuilderWithExpectationsButNoFailures = {};
+ // GLOBALS
+ // The DUMMYVALUE gets shifted off the array in the first call to
+ // generatePage.
+ var tableHeaders = ['DUMMYVALUE', 'bugs', 'modifiers', 'expectations',
+ 'missing', 'extra', 'slowest run',
+ 'flakiness (numbers are runtimes in seconds)'];
+ var perBuilderPlatformAndBuildType = {};
+ var perBuilderFailures = {};
+ // Map of builder to arrays of tests that are listed in the expectations file
+ // but have for that builder.
+ var perBuilderWithExpectationsButNoFailures = {};
+ // Map of builder to arrays of paths that are skipped. This shows the raw
+ // path used in test_expectations.txt rather than the test path since we
+ // don't actually have any data here for skipped tests.
+ var perBuilderSkippedPaths = {};
-
// Generic utility functions.
function $(id) {
return document.getElementById(id);
@@ -306,24 +341,23 @@
showWontFix: false,
showCorrectExpectations: false,
showFlaky: true,
+ showSkipped: false,
maxResults: 200,
testType: 'layout_test_results'
};
- for (var builder in builders) {
- defaultStateValues.builder = builder;
- break;
- }
-
function fillDefaultStateValues() {
- // tests has no states with default values.
- if (currentState.tests)
- return;
-
for (var state in defaultStateValues) {
if (!(state in currentState))
currentState[state] = defaultStateValues[state];
}
+
+ if (!currentState.tests && !('builder' in currentState)) {
+ for (var builder in builders) {
+ currentState.builder = builder;
+ break;
+ }
+ }
}
function handleValidHashParameter(key, value) {
@@ -602,15 +636,21 @@
* whether the modifiers match the builders platform and buildType.
*/
function addTestAndExpectations(test, prefixPath, builder, expectationsMap,
- expectations, testPrefixes) {
+ expectations, testPrefixes, skippedPaths) {
var modifiersForBuilder =
getModifierThatHasPlatformAndBuildType(builder, expectations);
- if (modifiersForBuilder) {
- if (getAllTestsWithSamePlatformAndBuildType(builder)[test]) {
- expectationsMap[test] = expectations;
- testPrefixes[test] = prefixPath;
- } else if (!stringContains(modifiersForBuilder.modifiers, 'SKIP') &&
- !modifiersForBuilder.expectations.match(/^\s*PASS\s*$/)) {
+
+ if (!modifiersForBuilder)
+ return false;
+
+ if (getAllTestsWithSamePlatformAndBuildType(builder)[test]) {
+ expectationsMap[test] = expectations;
+ testPrefixes[test] = prefixPath;
+ } else if (!stringContains(modifiersForBuilder.modifiers, 'WONTFIX')) {
+
+ if (stringContains(modifiersForBuilder.modifiers, 'SKIP')) {
+ skippedPaths[prefixPath] = true;
+ } else if (!modifiersForBuilder.expectations.match(/^\s*PASS\s*$/)) {
// Don't include skip tests here as they'll look the same as a test
// that passes on all builders.
// Also don't include tests that are only expected to pass, e.g.
@@ -618,9 +658,9 @@
// TODO(ojan): Should we also exclude WONTFIX tests here?
perBuilderWithExpectationsButNoFailures[builder].push(test);
}
- return true;
}
- return false;
+
+ return true;
}
/**
@@ -665,11 +705,12 @@
var testPrefixes = {};
perBuilderWithExpectationsButNoFailures[builderName] = [];
+ var skippedPaths = {};
for (var path in expectationsByTest) {
var expectations = expectationsByTest[path];
if (!isDirectory(path) &&
addTestAndExpectations(path, path, builderName, expectationsMap,
- expectations, testPrefixes)) {
+ expectations, testPrefixes, skippedPaths)) {
continue;
}
// Test path doesn't match a specific test, see if it prefix matches
@@ -679,10 +720,16 @@
(!testPrefixes[test] ||
!stringContains(testPrefixes[test], path))) {
addTestAndExpectations(test, path, builderName, expectationsMap,
- expectations, testPrefixes);
+ expectations, testPrefixes, skippedPaths);
}
}
}
+
+ perBuilderSkippedPaths[builderName] = [];
+ for (var path in skippedPaths) {
+ perBuilderSkippedPaths[builderName].push(path);
+ }
+ perBuilderSkippedPaths[builderName].sort();
perBuilderWithExpectationsButNoFailures[builderName].sort();
var allTestsForThisBuilder = resultsByBuilder[builderName].tests;
@@ -776,7 +823,7 @@
times[i][1]);
}
- if (resultsForTest.slowestTime &&
+ if (resultsForTest.slowestTime && !resultsMap['TIMEOUT'] &&
(!resultsForTest.expectations ||
!stringContains(resultsForTest.expectations, 'TIMEOUT')) &&
(!resultsForTest.modifiers ||
@@ -829,10 +876,56 @@
return bugs;
}
- function loadBuilderPageForBuildNumber(builderName, buildNumber) {
- window.open(BUILDERS_BASE_PATH + builderName + '/builds/' + buildNumber);
+ function getLinkHTMLToOpenWindow(url, text) {
+ return '<li class=link onclick="window.open(\'' + url + '\')">' + text +
+ '</li>';
}
+ function showPopupForBuild(e, builder, index) {
+ var html = '';
+
+ var time = resultsByBuilder[builder].secondsSinceEpoch[index];
+ if (time) {
+ var date = new Date(time * 1000);
+ html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
+ }
+
+ html += '<ul>';
+
+ var webkitRevision = resultsByBuilder[builder].webkitRevision;
+ var thisWebkitRevision = webkitRevision[index];
+ if (thisWebkitRevision) {
+ var previousWebkitRevision = webkitRevision[index + 1] ||
+ thisWebkitRevision;
+ html += getLinkHTMLToOpenWindow('http://trac.webkit.org/log/?rev=' +
+ thisWebkitRevision + '&stop_rev=' + previousWebkitRevision,
+ 'WebKit blamelist r' + previousWebkitRevision + ':r' +
+ thisWebkitRevision);
+ }
+
+ var chromeRevision = resultsByBuilder[builder].chromeRevision;
+ var thisChromeRevision = chromeRevision[index];
+ if (thisChromeRevision) {
+ var previousChromeRevision = chromeRevision[index + 1] ||
+ thisChromeRevision;
+ html += getLinkHTMLToOpenWindow(
+ 'http://build.chromium.org/buildbot/perf/dashboard/ui/' +
+ 'changelog.html?url=/trunk/src&mode=html&range=' +
+ previousChromeRevision + ':' + thisChromeRevision,
+ 'Chrome blamelist r' + previousChromeRevision + ':r' +
+ thisChromeRevision) +
+ getLinkHTMLToOpenWindow(TEST_RESULTS_BASE_PATH + builders[builder] +
+ '/' + thisChromeRevision + '/layout-test-results.zip',
+ 'layout-test-results.zip');
+ }
+
+ var buildNumbers = resultsByBuilder[builder].buildNumbers;
+ html += getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' +
+ buildNumbers[index], 'Build log and blamelist') + '</ul>';
+
+ showPopup(e, html);
+ }
+
function getHtmlForTestResults(test, builder) {
var html = '';
var results = test.rawResults.concat();
@@ -842,9 +935,8 @@
var indexToReplaceCurrentResult = -1;
var indexToReplaceCurrentTime = -1;
var currentResultArray, currentTimeArray, currentResult, innerHTML;
- for (var i = 0;
- i < buildNumbers.length && i < currentState.maxResults;
- i++) {
+ var maxIndex = Math.min(buildNumbers.length, currentState.maxResults);
+ for (var i = 0; i < maxIndex; i++) {
if (i > indexToReplaceCurrentResult) {
currentResultArray = results.shift();
if (currentResultArray) {
@@ -868,25 +960,49 @@
innerHTML = currentTime || '&nbsp;';
}
- var buildNumber = buildNumbers[i];
- html += '<td title="Build:' + buildNumber + '" class="results ' +
- currentResult + '" onclick=\'loadBuilderPageForBuildNumber("' +
- builder + '","' + buildNumber + '")\'>' + innerHTML + '</td>';
+ html += '<td title="Click results for handy links." class="results ' +
+ currentResult + '" onclick=\'showPopupForBuild(event, "' + builder +
+ '",' + i + ')\'>' + innerHTML + '</td>';
+
+ var webkitRevision = resultsByBuilder[builder].webkitRevision;
+ var isWebkitMerge = webkitRevision[i + 1] &&
+ webkitRevision[i] != webkitRevision[i + 1];
+ if (isWebkitMerge)
+ html += '<td class=merge></td>';
}
return html;
}
function getHTMLForTestsWithExpectationsButNoFailures(builder) {
var tests = perBuilderWithExpectationsButNoFailures[builder];
- if (!tests.length)
- return '';
+ var skippedPaths = perBuilderSkippedPaths[builder];
- var buildInfo = getPlatFormAndBuildType(builder);
- return '<h2>Have expectations for ' + buildInfo.platform + '-' +
- buildInfo.buildType + ' but have not failed in last ' +
+ var html = '';
+ if (tests.length || skippedPaths.length) {
+ var buildInfo = getPlatFormAndBuildType(builder);
+ html += '<h2>Expectations for ' + buildInfo.platform + '-' +
+ buildInfo.buildType + ':</h2>';
+ }
+
+ if (tests.length) {
+ html += '<h3>Have not failed in last ' +
resultsByBuilder[builderName].buildNumbers.length +
- ' runs.</h2><div id="passing-tests"><div>' +
+ ' runs.</h3><div id="passing-tests"><div>' +
tests.join('</div><div>') + '</div></div>';
+ }
+
+ if (skippedPaths.length) {
+ html += '<h3>' +
+ getLinkHTMLToToggleState('showSkipped',
+ 'Skipped tests in text_expectations.txt') +
+ '</h3>';
+
+ if (currentState.showSkipped) {
+ html += '<div id="passing-tests"><div>' +
+ skippedPaths.join('</div><div>') + '</div></div>';
+ }
+ }
+ return html;
}
/**
@@ -1145,13 +1261,13 @@
EXPECTATIONS_MAP[expectation] + '</div>';
}
return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' +
- '</div>';
+ '<div class=merge>WEBKIT MERGE</div></div>';
}
function getLinkHTMLToToggleState(key, linkText) {
var isTrue = currentState[key];
return '<span class=link onclick="setState(\'' + key + '\', ' + !isTrue +
- ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span> | ';
+ ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span>';
}
function generatePageForBuilder(builderName) {
@@ -1170,13 +1286,13 @@
var html = getHTMLForNavBar(builderName) +
getHTMLForTestsWithExpectationsButNoFailures(builderName) +
'<h2>Failing tests</h2><div>' +
- getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') +
+ getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') + ' | ' +
getLinkHTMLToToggleState('showCorrectExpectations',
- 'tests with correct expectations') +
- getLinkHTMLToToggleState('showFlaky', 'flaky tests') +
+ 'tests with correct expectations') + ' | ' +
+ getLinkHTMLToToggleState('showFlaky', 'flaky tests') + ' | ' +
'<form id=max-results-form ' +
'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' +
- '><span>Max results to show: </span>' +
+ '><span>Number of results to show: </span>' +
'<input name=maxResults id=max-results-input></form> | ' +
'<b>All columns are sortable. | Skipped tests are not listed. | ' +
'Flakiness reader order is newer --> older runs.</b></div>' +
@@ -1193,9 +1309,6 @@
$('max-results-input').value = currentState.maxResults;
}
- var singleBuilderViewParameters = ['sortOrder', 'sortColumn', 'showWontFix',
- 'showCorrectExpectations', 'showFlaky: true', 'maxResults'];
-
/**
* Sets the page state and regenerates the page. Takes varargs of key, value
* pairs.
@@ -1203,11 +1316,7 @@
function setState(key, value) {
for (var i = 0; i < arguments.length; i = i + 2) {
var key = arguments[i];
- if (key == 'tests') {
- for (var state in singleBuilderViewParameters) {
- delete currentState[state];
- }
- } else {
+ if (key != 'tests') {
delete currentState.tests;
}
@@ -1241,6 +1350,44 @@
console.log(msg + ': ' + (Date.now() - startTime));
}
+ function hidePopup() {
+ var popup = $('popup');
+ popup.parentNode.removeChild(popup);
+ }
+
+ function showPopup(e, html) {
+ var popup = $('popup');
+ if (!popup) {
+ popup = document.createElement('div');
+ popup.id = 'popup';
+ document.body.appendChild(popup);
+ }
+
+ // Set html first so that we can get accurate size metrics on the popup.
+ popup.innerHTML = html;
+
+ var targetRect = e.target.getBoundingClientRect();
+
+ var x = Math.min(targetRect.left - 10,
+ document.documentElement.clientWidth - popup.offsetWidth);
+ popup.style.left = x + document.body.scrollLeft + 'px';
+
+ var y = targetRect.top + targetRect.height;
+ if (y + popup.offsetHeight > document.documentElement.clientHeight) {
+ y = targetRect.top - popup.offsetHeight;
+ }
+ popup.style.top = y + document.body.scrollTop + 'px';
+ }
+
+ document.onmousedown = function(e) {
+ // Clear the open popup, unless the click was inside the popup.
+ var popup = $('popup');
+ if (popup && e.target != popup &&
+ !(popup.compareDocumentPosition(e.target) & 16)) {
+ hidePopup();
+ }
+ };
+
window.onload = function() {
// This doesn't seem totally accurate as there is a race between
// onload firing and the last script tag being executed.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698