Diff
Modified: trunk/Tools/ChangeLog (91195 => 91196)
--- trunk/Tools/ChangeLog 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/ChangeLog 2011-07-18 18:18:48 UTC (rev 91196)
@@ -1,3 +1,33 @@
+2011-07-18 Adam Barth <[email protected]>
+
+ garden-o-matic should be able to determine when compile breaks
+ https://bugs.webkit.org/show_bug.cgi?id=64190
+
+ Reviewed by Dimitri Glazkov.
+
+ This patch adds a red-ish box to the top of the page whenever there is
+ a compile error on the bots. The box automatically opens and closes as
+ appropriate and links to the waterfall display. In the future, we
+ might want to compute a regression range.
+
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/config.js:
+ - Add the build-only bots to the config. We use these to check
+ whether the build failed, which is faster than waiting for the
+ tester bots to cycle.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/index.html:
+ - Add DOM for the alert bar.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/main.css:
+ - CSS to support the alert bar.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/main.js:
+ - Wiring up events to poll the buildbot to see whether compile has
+ failed.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/results.js:
+ - Infrastructure for fetching and parsing the buildbot status JSON
+ blob. This code could be better factored for testability. :(
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js:
+ - UI for displaying compile errors.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js:
+
2011-07-18 Sheriff Bot <[email protected]>
Unreviewed, rolling out r91132 and r91135.
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/config.js (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/config.js 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/config.js 2011-07-18 18:18:48 UTC (rev 91196)
@@ -2,26 +2,40 @@
(function() {
-config.builders = [
- 'Webkit Win',
- 'Webkit Vista',
- // 'Webkit Win7',
- 'Webkit Win (dbg)(1)',
- 'Webkit Win (dbg)(2)',
- 'Webkit Linux',
- 'Webkit Linux 32',
- 'Webkit Linux (dbg)(1)',
- 'Webkit Linux (dbg)(2)',
- 'Webkit Mac10.5',
- 'Webkit Mac10.5 (dbg)(1)',
- 'Webkit Mac10.5 (dbg)(2)',
- 'Webkit Mac10.6',
- 'Webkit Mac10.6 (dbg)',
+config.kBuilders = [
+ 'Webkit Win',
+ 'Webkit Vista',
+ // 'Webkit Win7',
+ 'Webkit Win (dbg)(1)',
+ 'Webkit Win (dbg)(2)',
+ 'Webkit Linux',
+ 'Webkit Linux 32',
+ 'Webkit Linux (dbg)(1)',
+ 'Webkit Linux (dbg)(2)',
+ 'Webkit Mac10.5',
+ 'Webkit Mac10.5 (dbg)(1)',
+ 'Webkit Mac10.5 (dbg)(2)',
+ 'Webkit Mac10.6',
+ 'Webkit Mac10.6 (dbg)',
];
+config.kBuildersThatOnlyCompile = [
+ 'Webkit Win Builder',
+ 'Webkit Win Builder (dbg)',
+ // FIXME: Where is the Linux Builder?
+ 'Webkit Mac Builder',
+ 'Webkit Mac Builder (dbg)',
+ 'Win Builder',
+ 'Mac Clang Builder (dbg)',
+];
+
config.kTestNameAttr = 'data-test-name';
config.kBuilderNameAttr = 'data-builder-name';
config.kFailureCountAttr = 'data-failure-count';
config.kFailureTypesAttr = 'data-failure-types';
+config.kAlertTypeAttr = 'data-alert-type';
+var kTenMinutesInMilliseconds = 10 * 60 * 1000;
+config.kUpdateFrequency = kTenMinutesInMilliseconds;
+
})();
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html 2011-07-18 18:18:48 UTC (rev 91196)
@@ -11,6 +11,7 @@
</head>
<body>
<div class="butterbar"><span class="status">Loading...</span></div>
+<div class="alert"><span class="status"></span></div>
<div class="results"></div>
<div class="results-detail">
<div class="toolbar">
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css 2011-07-18 18:18:48 UTC (rev 91196)
@@ -38,6 +38,34 @@
margin-left: 20px;
}
+.alert {
+ display: none;
+ background-color: Cornsilk;
+ border: 5px solid Tomato;
+ padding: 10px;
+ margin: 5px auto;
+ font-size: 15px;
+ width: 75%;
+ text-align: center;
+}
+
+.alert .status a {
+ font-weight: normal;
+}
+
+.alert .status ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ display: inline-block;
+ padding: 0 0 0 10px;
+}
+
+.alert .status li {
+ display: inline-block;
+ margin: 0px 5px;
+}
+
/* If we've only seen a given test failure once, we dim it so as not to distract the gardener. */
.test[data-failure-count="1"][data-new-test="false"] {
-webkit-transition: 1s opacity;
@@ -64,6 +92,8 @@
}
.regression li {
+ display: inline-block;
+ margin: 0px 5px;
}
.regression a {
@@ -198,6 +228,7 @@
.results-detail .failure-details .missing-data {
font-style: italic;
text-align: center;
+ color: #555;
}
.results-detail .failure-details {
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js 2011-07-18 18:18:48 UTC (rev 91196)
@@ -1,5 +1,9 @@
(function() {
+var g_updateTimerId = 0;
+
+var kBuildFailedAlertType = 'build-failed';
+
function dismissButterbar()
{
$('.butterbar').fadeOut('fast');
@@ -11,6 +15,32 @@
$('.butterbar').fadeIn();
}
+function hideAlert()
+{
+ $('.alert').animate({
+ opacity: 'toggle',
+ height: 'toggle',
+ });
+}
+
+function hideAlertIfOfType(type)
+{
+ if (!$('.alert .status').is(':visible'))
+ return;
+ if ($('.alert .status').attr(config.kAlertTypeAttr) != type)
+ return;
+ hideAlert();
+}
+
+function displayAlert(message, type)
+{
+ $('.alert .status').empty().attr(config.kAlertTypeAttr, type).append(message);
+ $('.alert').animate({
+ opacity: 'toggle',
+ height: 'toggle',
+ });
+}
+
function setIconState(hasFailures)
{
var faviconURL = 'favicon-' + (hasFailures ? 'red' : 'green') + '.png';
@@ -19,7 +49,7 @@
function showResults(onsuccess)
{
- results.fetchResultsByBuilder(config.builders, function(resultsByBuilder) {
+ results.fetchResultsByBuilder(config.kBuilders, function(resultsByBuilder) {
var unexpectedFailures = results.unexpectedFailuresByTest(resultsByBuilder);
var hasFailures = !$.isEmptyObject(unexpectedFailures)
if (!hasFailures) {
@@ -122,6 +152,22 @@
checkout.rebaseline(builderName, testName, failureTypeList, dismissButterbar);
}
+function checkBuilderStatuses()
+{
+ results.fetchBuildersWithCompileErrors(function(builderNameList) {
+ if (!builderNameList.length) {
+ hideAlertIfOfType(kBuildFailedAlertType);
+ return;
+ }
+ displayAlert(ui.alertMessageForCompileErrors(builderNameList), kBuildFailedAlertType);
+ });
+}
+
+function update()
+{
+ checkBuilderStatuses();
+}
+
$('.regression .where a').live('click', showResultsDetail);
$('.results-detail .actions .dismiss').live('click', hideResultsDetail);
$('.results-detail .actions .rebaseline').live('click', rebaselineResults);
@@ -130,6 +176,8 @@
showResults(function() {
$('.butterbar').fadeOut();
});
+ g_updateTimerId = window.setInterval(update, config.kUpdateFrequency);
+ update();
});
})();
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js 2011-07-18 18:18:48 UTC (rev 91196)
@@ -482,14 +482,38 @@
});
};
-results.fetchResultsForBuilder = function(builderName, onsuccess)
+function isBuilderThatOnlyCompiles(builderName)
{
+ return config.kBuildersThatOnlyCompile.indexOf(builderName) != -1;
+}
+
+// FIXME: This method isn't tested because we don't have a good strategy for
+// mocking out the network. Maybe all network requests should go through a
+// "net" module?
+results.fetchBuildersWithCompileErrors = function(callback) {
+ $.get('/buildbot', function(builderStatuses) {
+ var brokenBuilders = [];
+
+ $.each(builderStatuses, function(index, builderStatus) {
+ if (builderStatus['is_green'])
+ return;
+ var builderName = builderStatus['name'];
+ if (isBuilderThatOnlyCompiles(builderName))
+ brokenBuilders.push(builderName);
+ });
+
+ callback(brokenBuilders);
+ });
+};
+
+results.fetchResultsForBuilder = function(builderName, callback)
+{
base.jsonp(resultsSummaryURL(builderName, kResultsName), function(resultsTree) {
- onsuccess(new results.BuilderResults(resultsTree));
+ callback(new results.BuilderResults(resultsTree));
});
};
-results.fetchResultsByBuilder = function(builderNameList, onsuccess)
+results.fetchResultsByBuilder = function(builderNameList, callback)
{
var resultsByBuilder = {}
var requestsInFlight = builderNameList.length;
@@ -498,7 +522,7 @@
resultsByBuilder[builderName] = resultsTree;
--requestsInFlight;
if (!requestsInFlight)
- onsuccess(resultsByBuilder);
+ callback(resultsByBuilder);
});
});
};
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js 2011-07-18 18:18:48 UTC (rev 91196)
@@ -2,6 +2,13 @@
(function () {
+function displayURLForBuilder(builderName)
+{
+ return 'http://build.chromium.org/p/chromium.webkit/waterfall?' + $.param({
+ 'builder': builderName
+ });
+}
+
function displayNameForBuilder(builderName)
{
return builderName.replace(/Webkit /, '');
@@ -42,7 +49,9 @@
var where = $('.where', block);
$.each(resultNodesByBuilder, function(builderName, resultNode) {
- where.append($('a', '<li><a href="" builderName).text(displayNameForBuilder(builderName)));
+ var listElement = $('<li><a href=""
+ where.append(listElement);
+ $('a', listElement).attr(config.kBuilderNameAttr, builderName).text(displayNameForBuilder(builderName));
});
return block;
@@ -65,6 +74,20 @@
return block;
};
+ui.alertMessageForCompileErrors = function(builderNameList)
+{
+ var block = $('<div class="compile-errors">Build Failed:<ul></ul></div>');
+
+ var list = $('ul', block);
+ $.each(builderNameList, function(index, builderName) {
+ var listElement = $('<li><a target="_blank"></a></li>');
+ list.append(listElement);
+ $('a', listElement).attr('href', displayURLForBuilder(builderName)).text(displayNameForBuilder(builderName));
+ });
+
+ return block;
+};
+
ui.failureCount = function(failureCount)
{
if (failureCount < 1)
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js (91195 => 91196)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js 2011-07-18 18:11:01 UTC (rev 91195)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js 2011-07-18 18:18:48 UTC (rev 91196)
@@ -51,6 +51,16 @@
equal(ui.failureCount(3), '(Seen 3 times.)');
});
+test("alertMessageForCompileErrors", 1, function() {
+ var message = ui.alertMessageForCompileErrors(['Mock Builder', 'Another Builder']);
+ message.wrap('<wrapper></wrapper>');
+ equal(message.parent().html(),
+ '<div class="compile-errors">Build Failed:<ul>' +
+ '<li><a target="_blank" href="" Builder</a></li>' +
+ '<li><a target="_blank" href="" Builder</a></li>' +
+ '</ul></div>');
+});
+
test("failureDetails", 1, function() {
var testResults = ui.failureDetails([
'http://example.com/layout-test-results/foo-bar-diff.txt',