Merge from Chromium at DEPS revision r199464
This commit was generated by merge_to_master.py.
Change-Id: I19655f81f4534807b2fa07bc72b5208501b02896
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/WebPreferences.cpp b/Tools/DumpRenderTree/chromium/TestRunner/src/WebPreferences.cpp
index eb3b384..b11e0a5 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/WebPreferences.cpp
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/WebPreferences.cpp
@@ -206,7 +206,6 @@
settings->setTextDirectionSubmenuInclusionBehaviorNeverIncluded();
settings->setUsesEncodingDetector(false);
settings->setImagesEnabled(true);
- settings->setInteractiveFormValidationEnabled(true);
// Enable fullscreen so the fullscreen layout tests can run.
settings->setFullScreenEnabled(true);
settings->setValidationMessageTimerMagnification(-1);
diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.cpp b/Tools/DumpRenderTree/chromium/WebViewHost.cpp
index f2068e3..5fc7ea0 100644
--- a/Tools/DumpRenderTree/chromium/WebViewHost.cpp
+++ b/Tools/DumpRenderTree/chromium/WebViewHost.cpp
@@ -289,8 +289,21 @@
void WebViewHost::scheduleAnimation()
{
- if (webView()->settings()->scrollAnimatorEnabled())
+ if (m_finished) {
+ return;
+ }
+ if (!m_animateScheduled) {
+ m_animateScheduled = true;
+ postDelayedTask(new HostMethodTask(this, &WebViewHost::animateNow), 1);
+ }
+}
+
+void WebViewHost::animateNow()
+{
+ if (m_animateScheduled) {
+ m_animateScheduled = false;
webView()->animate(0.0);
+ }
}
void WebViewHost::didFocus()
@@ -659,6 +672,7 @@
void WebViewHost::testFinished()
{
+ m_finished = true;
m_shell->testFinished(this);
}
@@ -805,6 +819,8 @@
m_lastPageIdUpdated = -1;
m_hasWindow = false;
m_inModalLoop = false;
+ m_animateScheduled = false;
+ m_finished = false;
m_navigationController = adoptPtr(new TestNavigationController(this));
diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.h b/Tools/DumpRenderTree/chromium/WebViewHost.h
index 4be88fb..985468b 100644
--- a/Tools/DumpRenderTree/chromium/WebViewHost.h
+++ b/Tools/DumpRenderTree/chromium/WebViewHost.h
@@ -224,6 +224,7 @@
// Can be used to update the title of the window.
void setPageTitle(const WebKit::WebString&);
+ void animateNow();
void enterFullScreenNow();
void exitFullScreenNow();
@@ -261,6 +262,8 @@
bool m_inModalLoop;
bool m_shutdownWasInvoked;
+ bool m_animateScheduled;
+ bool m_finished;
WebKit::WebRect m_windowRect;
diff --git a/Tools/GardeningServer/rebaseline.html b/Tools/GardeningServer/rebaseline.html
deleted file mode 100644
index 5119a4b..0000000
--- a/Tools/GardeningServer/rebaseline.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright (C) 2011 Google Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGE.
--->
-<html>
-<head>
-<title>Garden-O-Matic Rebaseline</title>
-<link rel="stylesheet" href="styles/main.css">
-<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/themes/base/jquery-ui.css">
-</head>
-<body>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
-<script src="scripts/config.js"></script>
-<script src="scripts/base.js"></script>
-<script src="scripts/net.js"></script>
-<script src="scripts/checkout.js"></script>
-<script src="scripts/results.js"></script>
-<script src="scripts/ui.js"></script>
-<script src="scripts/ui/results.js"></script>
-<script src="scripts/model.js"></script>
-<script src="scripts/controllers.js"></script>
-<script src="scripts/controllers/rebaseline.js"></script>
-</body>
-</html>
diff --git a/Tools/GardeningServer/scripts/builders.js b/Tools/GardeningServer/scripts/builders.js
index 7f5b36c..fd2373d 100644
--- a/Tools/GardeningServer/scripts/builders.js
+++ b/Tools/GardeningServer/scripts/builders.js
@@ -39,11 +39,6 @@
return config.kPlatforms[platform].buildConsoleURL;
}
-function urlForBuilderInfo(platform, builderName)
-{
- return buildBotURL(platform) + '/json/builders/' + encodeURIComponent(builderName) + '/';
-}
-
function urlForBuildInfo(platform, builderName, buildNumber)
{
return buildBotURL(platform) + '/json/builders/' + encodeURIComponent(builderName) + '/builds/' + encodeURIComponent(buildNumber);
@@ -117,39 +112,6 @@
});
}
-builders.builderInfo = function(platform, builderName, callback)
-{
- var builderInfoURL = urlForBuilderInfo(platform, builderName);
- net.get(builderInfoURL, callback);
-};
-
-builders.cachedBuildInfos = function(platform, builderName, callback)
-{
- var builderInfoURL = urlForBuilderInfo(platform, builderName);
- net.get(builderInfoURL, function(builderInfo) {
- var selectURL = urlForBuilderInfo(platform, builderName) + 'builds';
- var start = Math.max(0, builderInfo.cachedBuilds.length - config.kBuildNumberLimit);
- var selectParams = { select : builderInfo.cachedBuilds.slice(start) };
- var traditionalEncoding = true;
- selectURL += '?' + $.param(selectParams, traditionalEncoding);
- net.get(selectURL, callback);
- });
-}
-
-builders.recentBuildInfos = function(callback)
-{
- fetchMostRecentBuildInfoByBuilder(config.currentPlatform, function(buildInfoByBuilder) {
- var buildInfo = {};
- $.each(buildInfoByBuilder, function(builderName, thisBuildInfo) {
- if (!buildInfo)
- return;
-
- buildInfo[builderName] = thisBuildInfo;
- });
- callback(buildInfo);
- });
-};
-
builders.buildersFailingNonLayoutTests = function(callback)
{
fetchMostRecentBuildInfoByBuilder(config.currentPlatform, function(buildInfoByBuilder) {
diff --git a/Tools/GardeningServer/scripts/config.js b/Tools/GardeningServer/scripts/config.js
index ddfb1c6..8e5e5c1 100644
--- a/Tools/GardeningServer/scripts/config.js
+++ b/Tools/GardeningServer/scripts/config.js
@@ -49,9 +49,6 @@
'WebKit Mac10.7 (dbg)': {version: 'lion', debug: true},
'WebKit Mac10.8': {version: 'mountainlion'},
},
- haveBuilderAccumulatedResults : true,
- useDirectoryListingForOldBuilds: true,
- useFlakinessDashboard: true,
resultsDirectoryNameFromBuilderName: function(builderName) {
return base.underscoredBuilderName(builderName);
},
diff --git a/Tools/GardeningServer/scripts/controllers/rebaseline.js b/Tools/GardeningServer/scripts/controllers/rebaseline.js
deleted file mode 100644
index dffcc9a..0000000
--- a/Tools/GardeningServer/scripts/controllers/rebaseline.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-(function() {
-
-$(function() {
- model.updateResultsByBuilder(function() {
- var resultsView = new ui.results.View({
- fetchResultsURLs: results.fetchResultsURLs
- });
-
- var failuresByTest = results.expectedFailuresByTest(model.state.resultsByBuilder);
- var controller = new controllers.ResultsDetails(resultsView, failuresByTest);
- document.body.appendChild(resultsView);
- });
-});
-
-})();
diff --git a/Tools/GardeningServer/scripts/controllers_unittests.js b/Tools/GardeningServer/scripts/controllers_unittests.js
index 89f4c93..00f676b 100644
--- a/Tools/GardeningServer/scripts/controllers_unittests.js
+++ b/Tools/GardeningServer/scripts/controllers_unittests.js
@@ -87,7 +87,7 @@
ok(failingBuilders.hasFailures());
equal(view.outerHTML, '<div>' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"><time class="relative"></time></div>' +
'<div class="what">' +
'<div class="problem">dummy message:' +
diff --git a/Tools/GardeningServer/scripts/model_unittests.js b/Tools/GardeningServer/scripts/model_unittests.js
index ab040d7..15818d9 100644
--- a/Tools/GardeningServer/scripts/model_unittests.js
+++ b/Tools/GardeningServer/scripts/model_unittests.js
@@ -28,91 +28,55 @@
module("model");
var kExampleCommitDataXML =
- '<?xml version="1.0"?>\n\n' +
- '<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">\n\n' +
- ' \n\n' +
- '\n\n' +
- ' <channel>\n\n' +
- ' <title>Revisions of /trunk</title>\n\n' +
- ' <link>http://trac.webkit.org/log/trunk?rev=92362</link>\n\n' +
- ' <description>Trac Log - Revisions of /trunk</description>\n\n' +
- ' <language>en-US</language>\n\n' +
- ' <generator>Trac 0.11.7</generator>\n\n' +
- ' <image>\n\n' +
- ' <title>WebKit</title>\n\n' +
- ' <url>http://trac.webkit.org/chrome/site/icon.png</url>\n\n' +
- ' <link>http://trac.webkit.org/log/trunk?rev=92362</link>\n\n' +
- ' </image>\n\n' +
- ' <item>\n' +
- ' <author>commit-queue@webkit.org</author>\n' +
- ' <pubDate>Wed, 03 Aug 2011 04:26:52 GMT</pubDate>\n' +
- ' <title>Revision 92259: Unreviewed, rolling out r92256.\n' +
- 'http://trac.webkit.org/changeset/92256 ...</title>\n' +
- ' <link>http://trac.webkit.org/changeset/92259/trunk</link>\n' +
- ' <guid isPermaLink="false">http://trac.webkit.org/changeset/92259/trunk</guid>\n' +
- ' <description><p>\n' +
- 'Unreviewed, rolling out <a class="changeset" href="http://trac.webkit.org/changeset/92256" title="Make EventDispatchMediator RefCounted. ...">r92256</a>.\n' +
- '<a class="ext-link" href="http://trac.webkit.org/changeset/92256"><span class="icon"> </span>http://trac.webkit.org/changeset/92256</a>\n' +
- '<a class="ext-link" href="https://bugs.webkit.org/show_bug.cgi?id=65593"><span class="icon"> </span>https://bugs.webkit.org/show_bug.cgi?id=65593</a>\n' +
- '</p>\n' +
- '<p>\n' +
- 'Causing tons of crashes on the chromium win bots (Requested by\n' +
- 'jamesr on #webkit).\n' +
- '</p>\n' +
- '<p>\n' +
- 'Patch by Sheriff Bot &lt;<a class="mail-link" href="mailto:webkit.review.bot@gmail.com"><span class="icon"> </span>webkit.review.bot@gmail.com</a>&gt; on 2011-08-02\n' +
- '</p>\n' +
- '<p>\n' +
- '* dom/Event.cpp:\n' +
- '* dom/Event.h:\n' +
- '* dom/EventDispatcher.cpp:\n' +
- '(WebCore::EventDispatcher::dispatchEvent):\n' +
- '* dom/EventDispatcher.h:\n' +
- '* dom/KeyboardEvent.cpp:\n' +
- '* dom/KeyboardEvent.h:\n' +
- '* dom/MouseEvent.cpp:\n' +
- '* dom/MouseEvent.h:\n' +
- '* dom/Node.cpp:\n' +
- '(WebCore::Node::dispatchEvent):\n' +
- '(WebCore::Node::dispatchKeyEvent):\n' +
- '(WebCore::Node::dispatchMouseEvent):\n' +
- '(WebCore::Node::dispatchWheelEvent):\n' +
- '* dom/WheelEvent.cpp:\n' +
- '* dom/WheelEvent.h:\n' +
- '</p>\n' +
- '</description>\n' +
- ' <category>Log</category>\n' +
- ' </item><item>\n' +
- ' <author>macpherson@chromium.org</author>\n\n' +
- ' <pubDate>Thu, 04 Aug 2011 02:09:19 GMT</pubDate>\n\n' +
- ' <title>Revision 92256: Support cast between CSSPrimitiveValue and EBoxSizing, use in ...</title>\n\n' +
- ' <link>http://trac.webkit.org/changeset/92256/trunk</link>\n\n' +
- ' <guid isPermaLink="false">http://trac.webkit.org/changeset/92256/trunk</guid>\n\n' +
- ' <description><p>\n\n' +
- 'Support cast between CSSPrimitiveValue and EBoxSizing, use in CSSStyleSelector.\n\n' +
- '<a class="ext-link" href="https://bugs.webkit.org/show_bug.cgi?id=65657"><span class="icon"> </span>https://bugs.webkit.org/show_bug.cgi?id=65657</a>\n\n' +
- '</p>\n\n' +
- '<p>\n\n' +
- 'Reviewed by Simon Fraser.\n\n' +
- '</p>\n\n' +
- '<p>\n\n' +
- 'No new tests / refactoring only.\n\n' +
- '</p>\n\n' +
- '<p>\n\n' +
- '* css/CSSPrimitiveValueMappings.h:\n\n' +
- '(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):\n\n' +
- 'Implement cast from EBoxSizing.\n' +
- '(WebCore::CSSPrimitiveValue::operator EBoxSizing):\n' +
- 'Implement cast to EBoxSizing.\n' +
- '* css/CSSStyleSelector.cpp:\n' +
- '(WebCore::CSSStyleSelector::applyProperty):\n' +
- 'Use appropriate macro to simplify code using cast.\n' +
- '</p>\n' +
- '</description>\n' +
- ' <category>Log</category>\n' +
- ' </item>\n' +
- ' </channel>\n' +
- '</rss>\n'
+ '<?xml version="1.0"?>\n' +
+ '<log>\n' +
+ '<logentry\n' +
+ ' revision="147744">\n' +
+ '<author>tkent@chromium.org</author>\n' +
+ '<date>2013-04-06T13:00:08.314281Z</date>\n' +
+ '<msg>Revert 147740 "Remove the ENABLE_QUOTA compile-time flag."\n' +
+ '\n' +
+ '> Remove the ENABLE_QUOTA compile-time flag.\n' +
+ '> \n' +
+ '> This patch drops the ~20 occurances of \'#IFDEF ENABLE(QUOTA)\' from the\n' +
+ '> codebase. It shouldn\'t effect any web-visible behavior, as the interesting\n' +
+ '> bits are still hidden away behind the runtime flag, whose behavior\n' +
+ '> is untouched by this patch.\n' +
+ '> \n' +
+ '> R=eseidel@chromium.org,kinuko@chromium.org\n' +
+ '> \n' +
+ '> Review URL: https://codereview.chromium.org/13529033\n' +
+ '\n' +
+ 'TBR=mkwst@chromium.org\n' +
+ 'Review URL: https://codereview.chromium.org/13462004</msg>\n' +
+ '</logentry>\n' +
+ '<logentry\n' +
+ ' revision="147743">\n' +
+ '<author>tkent@chromium.org</author>\n' +
+ '<date>2013-04-06T12:48:59.078499Z</date>\n' +
+ '<msg>Update test expectations.\n' +
+ '\n' +
+ 'BUG=227354,227357</msg>\n' +
+ '</logentry>\n' +
+ '<logentry\n' +
+ ' revision="147742">\n' +
+ '<author>gavinp@chromium.org</author>\n' +
+ '<date>2013-04-06T12:40:34.111299Z</date>\n' +
+ '<msg>Guard <link> beforeload against recursion.\n' +
+ '\n' +
+ 'The beforeload event on a link element can recurse if it mutates its\n' +
+ 'firing link element. Now guard against this, only allowing the\n' +
+ 'innermost (last!) change to run. This prevents multiple client\n' +
+ 'registration and stops the crash in the bug report (which is\n' +
+ 'reproduced in the test).\n' +
+ '\n' +
+ 'BUG=174920\n' +
+ '\n' +
+ 'Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=147738\n' +
+ '\n' +
+ 'Review URL: https://codereview.chromium.org/13725004</msg>\n' +
+ '</logentry>\n' +
+ '</log>';
test("rebaselineQueue", 3, function() {
var queue = model.takeRebaselineQueue();
@@ -156,24 +120,34 @@
delete commitData.message;
});
deepEqual(recentCommits, [{
- "revision": 92259,
- "title": "Revision 92259: Unreviewed, rolling out r92256.\nhttp://trac.webkit.org/changeset/92256 ...",
- "time": "Wed, 03 Aug 2011 04:26:52 GMT",
- "summary": "Unreviewed, rolling out r92256.",
- "author": "Sheriff Bot",
- "reviewer": null,
- "bugID": 65593,
- "revertedRevision": 92256
- }, {
- "revision": 92256,
- "title": "Revision 92256: Support cast between CSSPrimitiveValue and EBoxSizing, use in ...",
- "time": "Thu, 04 Aug 2011 02:09:19 GMT",
- "summary": "Support cast between CSSPrimitiveValue and EBoxSizing, use in CSSStyleSelector.",
- "author": "macpherson@chromium.org",
- "reviewer": "Simon Fraser",
- "bugID": 65657,
- "revertedRevision": undefined,
- "wasReverted": true
+ 'revision': '147744',
+ 'title': 'Revert 147740 "Remove the ENABLE_QUOTA compile-time flag."',
+ 'time': '2013-04-06T13:00:08.314281Z',
+ 'summary': 'Revert 147740 "Remove the ENABLE_QUOTA compile-time flag."',
+ 'author': 'tkent@chromium.org',
+ 'reviewer': 'eseidel@chromium',
+ 'bugID': 0,
+ 'revertedRevision': undefined
+ },
+ {
+ 'revision': '147743',
+ 'title': 'Update test expectations.',
+ 'time': '2013-04-06T12:48:59.078499Z',
+ 'summary': 'Update test expectations.',
+ 'author': 'tkent@chromium.org',
+ 'reviewer': null,
+ 'bugID': 227354,
+ 'revertedRevision': undefined
+ },
+ {
+ 'revision': '147742',
+ 'title': 'Guard <link> beforeload against recursion.',
+ 'time': '2013-04-06T12:40:34.111299Z',
+ 'summary': 'Guard <link> beforeload against recursion.',
+ 'author': 'gavinp@chromium.org',
+ 'reviewer': null,
+ 'bugID': 174920,
+ 'revertedRevision': undefined
}]);
});
});
@@ -198,11 +172,11 @@
return commitData.bugID;
}
- deepEqual(model.commitDataListForRevisionRange(92259, 92259).map(extractBugIDs), [65593]);
- deepEqual(model.commitDataListForRevisionRange(92256, 92259).map(extractBugIDs), [65657, 65593]);
- deepEqual(model.commitDataListForRevisionRange(92259, 92256).map(extractBugIDs), []);
- deepEqual(model.commitDataListForRevisionRange(0, 92256).map(extractBugIDs), [65657]);
- deepEqual(model.commitDataListForRevisionRange(92256, 0).map(extractBugIDs), []);
+ deepEqual(model.commitDataListForRevisionRange(147742, 147742).map(extractBugIDs), [174920]);
+ deepEqual(model.commitDataListForRevisionRange(147740, 147742).map(extractBugIDs), [174920]);
+ deepEqual(model.commitDataListForRevisionRange(147739, 147740).map(extractBugIDs), []);
+ deepEqual(model.commitDataListForRevisionRange(0, 147742).map(extractBugIDs), [174920]);
+ deepEqual(model.commitDataListForRevisionRange(147743, 0).map(extractBugIDs), []);
delete model.state.recentCommits;
});
});
diff --git a/Tools/GardeningServer/scripts/results.js b/Tools/GardeningServer/scripts/results.js
index 2dd55a8..20864b3 100644
--- a/Tools/GardeningServer/scripts/results.js
+++ b/Tools/GardeningServer/scripts/results.js
@@ -313,8 +313,6 @@
$.each(resultsByBuilder, function(builderName, resultsTree) {
$.each(filter(resultsTree), function(testName, resultNode) {
resultsByTest[testName] = resultsByTest[testName] || {};
- if (!config.kPlatforms[config.currentPlatform].haveBuilderAccumulatedResults)
- resultNode._buildLocation = resultsTree._buildLocation;
resultsByTest[testName][builderName] = resultNode;
});
});
@@ -345,9 +343,6 @@
'failureTypeList': results.failureTypeList(resultsByTest[testName][builderName].actual),
};
- if (!config.kPlatforms[config.currentPlatform].haveBuilderAccumulatedResults)
- failureInfoForTest.buildLocation = resultsByTest[testName][builderName]._buildLocation;
-
return failureInfoForTest;
};
@@ -364,37 +359,21 @@
// Callback data is [{ buildNumber:, revision:, url: }]
function historicalResultsLocations(platform, builderName, callback)
{
- if (config.kPlatforms[platform].useDirectoryListingForOldBuilds) {
- var listingURL = resultsDirectoryListingURL(platform, builderName);
- net.get(listingURL, function(directoryListing) {
- var historicalResultsData = directoryListing.match(kBuildLinkRegexp).map(function(buildLink) {
- var buildNumber = parseInt(buildLink.match(kBuildNumberRegexp)[0]);
- var revision = 0; // unused for Chromium.
- var resultsData = {
- 'buildNumber': buildNumber,
- 'revision': revision,
- 'url': resultsSummaryURLForBuildNumber(platform, builderName, buildNumber, revision)
- };
- return resultsData;
- }).reverse();
-
- callback(historicalResultsData);
- });
- } else {
- var historicalResultsData = [];
- builders.cachedBuildInfos(platform, builderName, function(cachedBuildInfos) {
- $.each(cachedBuildInfos, function(buildNumber, buildInfo) {
- var resultsData = {
- 'buildNumber': buildNumber,
- 'revision': buildInfo.sourceStamp.revision,
- 'url': resultsSummaryURLForBuildNumber(platform, builderName, buildNumber, buildInfo.sourceStamp.revision),
- }
- historicalResultsData.push(resultsData);
- });
-
- callback(historicalResultsData.reverse());
- });
- }
+ var listingURL = resultsDirectoryListingURL(platform, builderName);
+ net.get(listingURL, function(directoryListing) {
+ var historicalResultsData = directoryListing.match(kBuildLinkRegexp).map(function(buildLink) {
+ var buildNumber = parseInt(buildLink.match(kBuildNumberRegexp)[0]);
+ var revision = 0; // unused for Chromium.
+ var resultsData = {
+ 'buildNumber': buildNumber,
+ 'revision': revision,
+ 'url': resultsSummaryURLForBuildNumber(platform, builderName, buildNumber, revision)
+ };
+ return resultsData;
+ }).reverse();
+
+ callback(historicalResultsData);
+ });
}
function walkHistory(platform, builderName, testName, callback)
@@ -581,12 +560,7 @@
results.fetchResultsURLs = function(failureInfo, callback)
{
var testNameStem = base.trimExtension(failureInfo.testName);
- var urlStem;
-
- if (config.kPlatforms[config.currentPlatform].haveBuilderAccumulatedResults)
- urlStem = resultsDirectoryURL(config.currentPlatform, failureInfo.builderName);
- else
- urlStem = failureInfo.buildLocation.url.replace(kResultsName, '');
+ var urlStem = resultsDirectoryURL(config.currentPlatform, failureInfo.builderName);
var suffixList = possibleSuffixListFor(failureInfo.failureTypeList);
var resultURLs = [];
@@ -635,8 +609,6 @@
net.jsonp(buildLocations[currentIndex].url, resultsCallback);
return;
}
- if (!config.kPlatforms[config.currentPlatform].haveBuilderAccumulatedResults)
- buildResults._buildLocation = buildLocations[currentIndex];
callback(buildResults);
};
net.jsonp(buildLocations[currentIndex].url, resultsCallback);
@@ -646,34 +618,15 @@
results.fetchResultsByBuilder = function(builderNameList, callback)
{
var resultsByBuilder = {};
- if (config.kPlatforms[config.currentPlatform].haveBuilderAccumulatedResults) {
- var tracker = new base.RequestTracker(builderNameList.length, function() {
- callback(resultsByBuilder);
+ var tracker = new base.RequestTracker(builderNameList.length, function() {
+ callback(resultsByBuilder);
+ });
+ $.each(builderNameList, function(index, builderName) {
+ results.fetchResultsForBuilder(builderName, function(resultsTree) {
+ resultsByBuilder[builderName] = resultsTree;
+ tracker.requestComplete();
});
- $.each(builderNameList, function(index, builderName) {
- results.fetchResultsForBuilder(builderName, function(resultsTree) {
- resultsByBuilder[builderName] = resultsTree;
- tracker.requestComplete();
- });
- });
- } else {
- builders.recentBuildInfos(function(recentBuildInfos) {
- var requestsInFlight = 0;
- $.each(builderNameList, function(index, builderName) {
- if (recentBuildInfos[builderName]) {
- // FIXME: use RequestTracker
- ++requestsInFlight;
- results.fetchResultsForMostRecentCompletedBuildOnBuilder(builderName, function(resultsTree) {
- if (resultsTree)
- resultsByBuilder[builderName] = resultsTree;
- --requestsInFlight;
- if (!requestsInFlight)
- callback(resultsByBuilder);
- });
- }
- });
- });
- }
+ });
};
})();
diff --git a/Tools/GardeningServer/scripts/results_unittests.js b/Tools/GardeningServer/scripts/results_unittests.js
index e15e739..4e59e6c 100644
--- a/Tools/GardeningServer/scripts/results_unittests.js
+++ b/Tools/GardeningServer/scripts/results_unittests.js
@@ -533,7 +533,7 @@
]);
});
-test("fetchResultsByBuilder", 5, function() {
+test("fetchResultsByBuilder", 3, function() {
var simulator = new NetworkSimulator();
var probedURLs = [];
@@ -541,68 +541,24 @@
{
simulator.scheduleCallback(function() {
probedURLs.push(url);
- if (base.endsWith(url, 'MockBuilder2/r1%20(1)/full_results.json'))
- callback({'MockBuildResults': true});
- else
- callback({});
- });
- };
-
- config.currentPlatform = 'gtk';
-
- var oldCachedBuildInfos = builders.cachedBuildInfos;
- builders.cachedBuildInfos = function(platform, builderName, callback) {
- callback(
- {
- 1: {
- sourceStamp: {
- revision: 1
- }
- },
- 2: {
- sourceStamp: {
- revision: 2
- }
- }
-
- });
- };
-
- var oldRecentBuildInfos = builders.recentBuildInfos;
- builders.recentBuildInfos = function(callback) {
- callback({
- 'MockBuilder1': true,
- 'MockBuilder2': true
+ callback(base.endsWith(url, 'results/layout-test-results/full_results.json'));
});
};
simulator.runTest(function() {
results.fetchResultsByBuilder(['MockBuilder1', 'MockBuilder2'], function(resultsByBuilder) {
deepEqual(resultsByBuilder, {
- "MockBuilder2": {
- "MockBuildResults": true,
- "_buildLocation": {
- "buildNumber": "1",
- "revision": 1,
- "url": "http://build.webkit.org/results/MockBuilder2/r1%20(1)/full_results.json"
- }
- }
+ "MockBuilder1": true,
+ "MockBuilder2": true,
});
});
});
deepEqual(probedURLs, [
- "http://build.webkit.org/results/MockBuilder1/r2%20(2)/full_results.json",
- "http://build.webkit.org/results/MockBuilder2/r2%20(2)/full_results.json",
- "http://build.webkit.org/results/MockBuilder1/r1%20(1)/full_results.json",
- "http://build.webkit.org/results/MockBuilder2/r1%20(1)/full_results.json"
+ "http://build.chromium.org/f/chromium/layout_test_results/MockBuilder1/results/layout-test-results/full_results.json",
+ "http://build.chromium.org/f/chromium/layout_test_results/MockBuilder2/results/layout-test-results/full_results.json"
]);
- builders.cachedBuildInfos = oldCachedBuildInfos;
- equal(builders.cachedBuildInfos, oldCachedBuildInfos, "Failed to restore real base!");
-
- builders.recentBuildInfos = oldRecentBuildInfos;
- equal(builders.recentBuildInfos, oldRecentBuildInfos, "Failed to restore real base!");
});
})();
diff --git a/Tools/GardeningServer/scripts/ui.js b/Tools/GardeningServer/scripts/ui.js
index ef74fd7..5cde93f 100644
--- a/Tools/GardeningServer/scripts/ui.js
+++ b/Tools/GardeningServer/scripts/ui.js
@@ -52,10 +52,7 @@
ui.urlForEmbeddedFlakinessDashboard = function(opt_testNameList)
{
- if (config.kPlatforms[config.currentPlatform].useFlakinessDashboard)
- return ui.urlForFlakinessDashboard(opt_testNameList) + '&showChrome=false';
-
- return 'about:blank';
+ return ui.urlForFlakinessDashboard(opt_testNameList) + '&showChrome=false';
}
ui.rolloutReasonForTestNameList = function(testNameList)
diff --git a/Tools/GardeningServer/scripts/ui/failures_unittests.js b/Tools/GardeningServer/scripts/ui/failures_unittests.js
index 747b3da..1bfbb5c 100644
--- a/Tools/GardeningServer/scripts/ui/failures_unittests.js
+++ b/Tools/GardeningServer/scripts/ui/failures_unittests.js
@@ -29,17 +29,17 @@
test('Builder', 6, function() {
var configuration;
- configuration = new ui.failures.Builder("Webkit Linux", ["update", "webkit_tests"]);
+ configuration = new ui.failures.Builder("WebKit Linux", ["update", "webkit_tests"]);
deepEqual(Object.getOwnPropertyNames(configuration.__proto__).sort(), [
'_addSpan',
'equals',
'init',
]);
- equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> update, webkit_tests</span></a>');
- configuration = new ui.failures.Builder("Webkit Win");
- equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Win"><span class="version">xp</span></a>');
+ equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> update, webkit_tests</span></a>');
+ configuration = new ui.failures.Builder("WebKit XP");
+ equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span></a>');
configuration._addSpan('foo', 'bar');
- equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Win"><span class="version">xp</span><span class="foo">bar</span></a>');
+ equal(configuration.outerHTML, '<a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span><span class="foo">bar</span></a>');
ok(configuration.equals({version: 'xp'}));
ok(!configuration.equals({version: 'lucid', is64bit: true}));
});
@@ -85,7 +85,7 @@
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
- '<tr class="TEXT" style="">' +
+ '<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
@@ -102,7 +102,7 @@
'<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
'<td></td>' +
'</tr>' +
- '<tr class="TEXT" style="">' +
+ '<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
@@ -114,12 +114,12 @@
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
- '<tr class="IMAGE+TEXT" style="">' +
+ '<tr class="IMAGE+TEXT">' +
'<td><span>IMAGE+TEXT</span></td>' +
'<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
'<td></td>' +
'</tr>' +
- '<tr class="TEXT" style="">' +
+ '<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
diff --git a/Tools/GardeningServer/scripts/ui/notifications_unittests.js b/Tools/GardeningServer/scripts/ui/notifications_unittests.js
index f869305..18934cc 100644
--- a/Tools/GardeningServer/scripts/ui/notifications_unittests.js
+++ b/Tools/GardeningServer/scripts/ui/notifications_unittests.js
@@ -87,7 +87,7 @@
equal(suspiciousCommit.tagName, 'LI');
equal(suspiciousCommit.innerHTML,
'<div class="description">' +
- '<a href="http://trac.webkit.org/changeset/1" target="_blank">1</a>' +
+ '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' +
'<span>' +
'<span class="summary">summary</span>' +
'<span class="author">author</span>' +
@@ -104,7 +104,7 @@
'<time class="relative"></time>' +
'<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
- '<tbody><tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
+ '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>' +
'</div>' +
'<div class="what">' +
@@ -124,7 +124,7 @@
'<time class="relative"></time>' +
'<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
- '<tbody><tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
+ '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>' +
'</div>' +
'<div class="what">' +
@@ -147,7 +147,7 @@
'<time class="relative"></time>' +
'<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
- '<tbody><tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
+ '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>' +
'</div>' +
'<div class="what">' +
@@ -172,7 +172,7 @@
'<time class="relative">10 minutes ago</time>' +
'<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
- '<tbody><tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
+ '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>' +
'</div>' +
'<div class="what">' +
@@ -188,7 +188,7 @@
'<ul class="causes">' +
'<li>' +
'<div class="description">' +
- '<a href="http://trac.webkit.org/changeset/1" target="_blank">1</a>' +
+ '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' +
'<span>' +
'<span class="summary">summary</span>' +
'<span class="author">author</span>' +
@@ -199,7 +199,7 @@
'</ul>' +
'</div>');
- testFailures.addFailureAnalysis({testName: 'foo', resultNodesByBuilder: {'Webkit Linux (dbg)': { actual: 'TEXT'}}});
+ testFailures.addFailureAnalysis({testName: 'foo', resultNodesByBuilder: {'WebKit Linux (dbg)': { actual: 'TEXT'}}});
equal(testFailures.innerHTML,
'<div class="how">' +
'<time class="relative">10 minutes ago</time>' +
@@ -209,9 +209,9 @@
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
- '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
+ '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
- '<tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr>' +
+ '<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>' +
'</div>' +
@@ -229,7 +229,7 @@
'<ul class="causes">' +
'<li>' +
'<div class="description">' +
- '<a href="http://trac.webkit.org/changeset/1" target="_blank">1</a>' +
+ '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' +
'<span>' +
'<span class="summary">summary</span>' +
'<span class="author">author</span>' +
@@ -240,7 +240,7 @@
'</ul>' +
'</div>');
- testFailures.updateBuilderResults({'Webkit Mac10.6': { actual: 'BUILDING'}});
+ testFailures.updateBuilderResults({'WebKit Mac10.6': { actual: 'BUILDING'}});
equal(testFailures.innerHTML,
'<div class="how">' +
'<time class="relative">10 minutes ago</time>' +
@@ -250,11 +250,11 @@
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
- '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
+ '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
'<tr class="BUILDING" style="">' +
'<td><span>BUILDING</span></td>' +
- '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
+ '<td><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
'<td></td>' +
'</tr>' +
'</tbody>' +
@@ -274,7 +274,7 @@
'<ul class="causes">' +
'<li>' +
'<div class="description">' +
- '<a href="http://trac.webkit.org/changeset/1" target="_blank">1</a>' +
+ '<a href="http://src.chromium.org/viewvc/blink?view=rev&revision=1" target="_blank">1</a>' +
'<span>' +
'<span class="summary">summary</span>' +
'<span class="author">author</span>' +
@@ -298,7 +298,7 @@
'<time class="relative"></time>' +
'<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
- '<tbody><tr class="BUILDING" style="display: none; "><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
+ '<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>' +
'</div>' +
'<div class="what">' +
@@ -318,7 +318,7 @@
test('BuildersFailing', 1, function() {
var builderFailing = new ui.notifications.BuildersFailing('Disasterifying');
- builderFailing.setFailingBuilders({'Webkit Linux': ['compile'], 'Webkit Win7': ['webkit_tests', 'update']});
+ builderFailing.setFailingBuilders({'WebKit Linux': ['compile'], 'WebKit Win7': ['webkit_tests', 'update']});
equal(builderFailing.innerHTML,
'<div class="how">' +
'<time class="relative"></time>' +
@@ -326,8 +326,8 @@
'<div class="what">' +
'<div class="problem">Disasterifying:' +
'<ul class="effects">' +
- '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> compile</span></a></li>' +
- '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=Webkit+Win7"><span class="version">win7</span><span class="failures"> webkit_tests, update</span></a></li>' +
+ '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> compile</span></a></li>' +
+ '<li class="builder"><a class="failing-builder" target="_blank" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Win7"><span class="version">win7</span><span class="failures"> webkit_tests, update</span></a></li>' +
'</ul>' +
'</div>' +
'<ul class="causes"></ul>' +
diff --git a/Tools/GardeningServer/scripts/ui/perf_unittests.js b/Tools/GardeningServer/scripts/ui/perf_unittests.js
index 8a966ad..73d87fa 100644
--- a/Tools/GardeningServer/scripts/ui/perf_unittests.js
+++ b/Tools/GardeningServer/scripts/ui/perf_unittests.js
@@ -57,7 +57,7 @@
setTimeout(function() {
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -74,7 +74,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -91,7 +91,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -108,7 +108,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -125,7 +125,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -142,7 +142,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
@@ -159,7 +159,7 @@
equal(view.outerHTML, '<div id="perf-view">' +
'<ol class="notifications">' +
- '<li style="opacity: 0; ">' +
+ '<li style="opacity: 0;">' +
'<div class="how"></div><div class="what">Loading list of perf dashboards...</div>' +
'</li>' +
'</ol>' +
diff --git a/Tools/GardeningServer/scripts/ui/results.js b/Tools/GardeningServer/scripts/ui/results.js
index 05e597e..6b62384 100644
--- a/Tools/GardeningServer/scripts/ui/results.js
+++ b/Tools/GardeningServer/scripts/ui/results.js
@@ -204,14 +204,6 @@
if (!this.contentWindow)
return;
- // Check for null event.origin so that the unittests can get past this point.
- // FIXME: Is this safe? In practice, there's no meaningful harm that can come from
- // a malicious page sending us heightChanged commands, so it doesn't really matter.
- if (event.origin !== 'null' && event.origin != 'http://test-results.appspot.com') {
- console.log('Invalid origin: ' + event.origin);
- return;
- }
-
if (event.data.command != 'heightChanged') {
console.log('Unknown postMessage command: ' + event.data);
return;
diff --git a/Tools/GardeningServer/scripts/ui/results_unittests.js b/Tools/GardeningServer/scripts/ui/results_unittests.js
index 2457ac4..4dd546f 100644
--- a/Tools/GardeningServer/scripts/ui/results_unittests.js
+++ b/Tools/GardeningServer/scripts/ui/results_unittests.js
@@ -36,7 +36,7 @@
// setTimeout to be after the postMessage has been handled.
setTimeout(function() {
equals(dashboard.offsetHeight, 15);
- $(dashboard).detach();
+ dashboard.remove();
start();
}, 0);
}, 0);
diff --git a/Tools/GardeningServer/styles/results.css b/Tools/GardeningServer/styles/results.css
index 28cfd09..5143f3a 100644
--- a/Tools/GardeningServer/styles/results.css
+++ b/Tools/GardeningServer/styles/results.css
@@ -146,7 +146,7 @@
}
#results, #perf {
- /* FIXME: We really should use flexbox so we don't have to do this. But that requires restructuring the DOM a bit. */;
+ /* FIXME: We really should use flexbox so we don't have to do this. But that requires restructuring the DOM a bit. */
height: -webkit-calc(100% - 39px);
box-sizing: border-box;
/* Position relative so that nested percentages size to this element. */
diff --git a/Tools/Scripts/new-run-webkit-httpd b/Tools/Scripts/new-run-webkit-httpd
deleted file mode 100755
index 9ace3e1..0000000
--- a/Tools/Scripts/new-run-webkit-httpd
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""A utility script for starting and stopping the HTTP server with the
- same configuration as used in the layout tests."""
-
-#
-# FIXME: currently this code only works with the Chromium ports and LigHTTPd.
-# It should be made to work on all ports.
-#
-# This script is also used by Chromium's ui_tests to run http layout tests
-# in a browser.
-#
-import optparse
-import os
-import sys
-import tempfile
-
-import webkitpy.common.version_check
-
-from webkitpy.common.host import Host
-from webkitpy.layout_tests.servers import http_server
-
-
-def run(options):
- if not options.server:
- print ('Usage: %s --server {start|stop} [--root=root_dir]'
- ' [--port=port_number]' % sys.argv[0])
- else:
- if (options.root is None) and (options.port is not None):
- # specifying root but not port means we want httpd on default
- # set of ports that LayoutTest use, but pointing to a different
- # source of tests. Specifying port but no root does not seem
- # meaningful.
- raise 'Specifying port requires also a root.'
- host = Host()
- # FIXME: Make this work with other ports as well.
- port_obj = host.port_factory.get(port_name='chromium', options=options)
- httpd = http_server.Lighttpd(port_obj,
- tempfile.gettempdir(),
- port=options.port,
- root=options.root,
- run_background=options.run_background,
- layout_tests_dir=options.layout_tests_dir)
- if options.server == 'start':
- httpd.start()
- else:
- httpd.stop()
-
-
-def main():
- option_parser = optparse.OptionParser()
- option_parser.add_option('-k', '--server',
- help='Server action (start|stop)')
- option_parser.add_option('-p', '--port',
- help='Port to listen on (overrides layout test ports)')
- option_parser.add_option('-r', '--root',
- help='Absolute path to DocumentRoot (overrides layout test roots)')
- option_parser.add_option('--register_cygwin', action="store_true",
- dest="register_cygwin", help='Register Cygwin paths (on Win try bots)')
- option_parser.add_option('--run_background', action="store_true",
- dest="run_background",
- help='Run on background (for running as UI test)')
- option_parser.add_option('--layout_tests_dir',
- dest="layout_tests_dir",
- help='Absolute path to LayoutTests root')
- options, args = option_parser.parse_args()
-
- run(options)
-
-
-if '__main__' == __name__:
- main()
diff --git a/Tools/Scripts/webkitpy/bindings/main.py b/Tools/Scripts/webkitpy/bindings/main.py
index 887a861..d3115fb 100644
--- a/Tools/Scripts/webkitpy/bindings/main.py
+++ b/Tools/Scripts/webkitpy/bindings/main.py
@@ -60,7 +60,7 @@
exit_code = e.exit_code
return exit_code
- def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file):
+ def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file, window_constructors_file):
idl_files_list = tempfile.mkstemp()
for input_file in os.listdir(input_directory):
(name, extension) = os.path.splitext(input_file)
@@ -73,7 +73,8 @@
'-Ibindings/scripts',
'bindings/scripts/preprocess-idls.pl',
'--idlFilesList', idl_files_list[1],
- '--supplementalDependencyFile', supplemental_dependency_file]
+ '--supplementalDependencyFile', supplemental_dependency_file,
+ '--windowConstructorsFile', window_constructors_file]
exit_code = 0
try:
@@ -147,7 +148,8 @@
input_directory = os.path.join('bindings', 'tests', 'idls')
supplemental_dependency_file = tempfile.mkstemp()[1]
- if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file):
+ window_constructors_file = tempfile.mkstemp()[1]
+ if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file, window_constructors_file):
print 'Failed to generate a supplemental dependency file.'
os.remove(supplemental_dependency_file)
return -1
diff --git a/Tools/Scripts/webkitpy/common/net/resultsjsonparser.py b/Tools/Scripts/webkitpy/common/net/resultsjsonparser.py
index 1a2a70f..581f967 100644
--- a/Tools/Scripts/webkitpy/common/net/resultsjsonparser.py
+++ b/Tools/Scripts/webkitpy/common/net/resultsjsonparser.py
@@ -77,7 +77,7 @@
if not TestExpectations.has_pixel_failures(actual_results):
expected_results = TestExpectations.remove_pixel_failures(expected_results)
for actual_result in actual_results:
- if not TestExpectations.result_was_expected(actual_result, expected_results, False, False):
+ if not TestExpectations.result_was_expected(actual_result, expected_results, False):
return False
return True
diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
index eaf16f7..fd35b44 100644
--- a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
+++ b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
@@ -800,20 +800,19 @@
return cls.EXPECTATIONS.get(string.lower())
@staticmethod
- def result_was_expected(result, expected_results, test_needs_rebaselining, test_is_skipped):
+ def result_was_expected(result, expected_results, test_needs_rebaselining):
"""Returns whether we got a result we were expecting.
Args:
result: actual result of a test execution
expected_results: set of results listed in test_expectations
- test_needs_rebaselining: whether test was marked as REBASELINE
- test_is_skipped: whether test was marked as SKIP"""
+ test_needs_rebaselining: whether test was marked as REBASELINE"""
if result in expected_results:
return True
if result in (TEXT, IMAGE_PLUS_TEXT, AUDIO) and (FAIL in expected_results):
return True
if result == MISSING and test_needs_rebaselining:
return True
- if result == SKIP and test_is_skipped:
+ if result == SKIP:
return True
return False
@@ -924,10 +923,7 @@
expected_results = self._model.get_expectations(test)
if not pixel_tests_are_enabled:
expected_results = self.remove_pixel_failures(expected_results)
- return self.result_was_expected(result,
- expected_results,
- self.is_rebaselining(test),
- self._model.has_modifier(test, SKIP))
+ return self.result_was_expected(result, expected_results, self.is_rebaselining(test))
def is_rebaselining(self, test):
return self._model.has_modifier(test, REBASELINE)
@@ -967,9 +963,7 @@
modified_expectations = []
for expectation in self._expectations:
- if expectation.name != test or expectation.is_flaky() or not expectation.parsed_expectations:
- continue
- if iter(expectation.parsed_expectations).next() not in (FAIL, IMAGE):
+ if expectation.name != test or not expectation.parsed_expectations:
continue
if test_configuration not in expectation.matching_configurations:
continue
diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py
index a198cce..8e6ffdd 100644
--- a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py
@@ -107,16 +107,15 @@
def test_result_was_expected(self):
# test basics
- self.assertEqual(TestExpectations.result_was_expected(PASS, set([PASS]), test_needs_rebaselining=False, test_is_skipped=False), True)
- self.assertEqual(TestExpectations.result_was_expected(FAIL, set([PASS]), test_needs_rebaselining=False, test_is_skipped=False), False)
+ self.assertEqual(TestExpectations.result_was_expected(PASS, set([PASS]), test_needs_rebaselining=False), True)
+ self.assertEqual(TestExpectations.result_was_expected(FAIL, set([PASS]), test_needs_rebaselining=False), False)
# test handling of SKIPped tests and results
- self.assertEqual(TestExpectations.result_was_expected(SKIP, set([CRASH]), test_needs_rebaselining=False, test_is_skipped=True), True)
- self.assertEqual(TestExpectations.result_was_expected(SKIP, set([CRASH]), test_needs_rebaselining=False, test_is_skipped=False), False)
+ self.assertEqual(TestExpectations.result_was_expected(SKIP, set([CRASH]), test_needs_rebaselining=False), True)
# test handling of MISSING results and the REBASELINE modifier
- self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=True, test_is_skipped=False), True)
- self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=False, test_is_skipped=False), False)
+ self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=True), True)
+ self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=False), False)
def test_remove_pixel_failures(self):
self.assertEqual(TestExpectations.remove_pixel_failures(set([FAIL])), set([FAIL]))
@@ -504,6 +503,26 @@
self.assertEqual("""Bug(y) [ Win Debug ] failures/expected/foo.html [ Crash ]
""", actual_expectations)
+ def test_remove_flaky_line(self):
+ host = MockHost()
+ test_port = host.port_factory.get('test-win-xp', None)
+ test_port.test_exists = lambda test: True
+ test_port.test_isfile = lambda test: True
+
+ test_config = test_port.test_configuration()
+ test_port.expectations_dict = lambda: {'expectations': """Bug(x) [ Win ] failures/expected/foo.html [ Failure Timeout ]
+Bug(y) [ Mac ] failures/expected/foo.html [ Crash ]
+"""}
+ expectations = TestExpectations(test_port)
+
+ actual_expectations = expectations.remove_configuration_from_test('failures/expected/foo.html', test_config)
+ actual_expectations = expectations.remove_configuration_from_test('failures/expected/foo.html', host.port_factory.get('test-win-vista', None).test_configuration())
+ actual_expectations = expectations.remove_configuration_from_test('failures/expected/foo.html', host.port_factory.get('test-win-win7', None).test_configuration())
+
+ self.assertEqual("""Bug(x) [ Win Debug ] failures/expected/foo.html [ Failure Timeout ]
+Bug(y) [ Mac ] failures/expected/foo.html [ Crash ]
+""", actual_expectations)
+
class RebaseliningTest(Base):
"""Test rebaselining-specific functionality."""
diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py b/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py
index 3af1224..b2959d0 100644
--- a/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py
+++ b/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py
@@ -28,6 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging
+import time
from webkitpy.layout_tests.models import test_expectations
from webkitpy.layout_tests.models import test_failures
@@ -135,6 +136,7 @@
tbe = initial_results.tests_by_expectation
tbt = initial_results.tests_by_timeline
results['fixable'] = len(tbt[test_expectations.NOW] - tbe[test_expectations.PASS])
+ # FIXME: Remove this. It is redundant with results['num_failures_by_type'].
results['skipped'] = len(tbt[test_expectations.NOW] & tbe[test_expectations.SKIP])
num_passes = 0
@@ -148,6 +150,12 @@
for modifier_string, modifier_enum in test_expectations.TestExpectations.MODIFIERS.iteritems():
keywords[modifier_enum] = modifier_string.upper()
+ num_failures_by_type = {}
+ for expectation in initial_results.tests_by_expectation:
+ num_failures_by_type[keywords[expectation]] = len(initial_results.tests_by_expectation[expectation] & tbt[test_expectations.NOW])
+ # The number of failures by type.
+ results['num_failures_by_type'] = num_failures_by_type
+
tests = {}
for test_name, result in initial_results.results_by_name.iteritems():
@@ -158,10 +166,9 @@
result_type = result.type
actual = [keywords[result_type]]
- if result_type == test_expectations.SKIP:
- continue
-
test_dict = {}
+ test_dict['time'] = result.total_run_time
+
if result.has_stderr:
test_dict['has_stderr'] = True
@@ -173,16 +180,13 @@
if result_type == test_expectations.PASS:
num_passes += 1
- # FIXME: include passing tests that have stderr output.
- if expected == 'PASS':
- continue
elif result_type == test_expectations.CRASH:
if test_name in initial_results.unexpected_results_by_name:
num_regressions += 1
elif result_type == test_expectations.MISSING:
if test_name in initial_results.unexpected_results_by_name:
num_missing += 1
- elif test_name in initial_results.unexpected_results_by_name:
+ elif result_type != test_expectations.SKIP and test_name in initial_results.unexpected_results_by_name:
if retry_results and test_name not in retry_results.unexpected_results_by_name:
actual.extend(expectations.get_expectations_string(test_name).split(" "))
num_flaky += 1
@@ -202,6 +206,13 @@
test_dict['expected'] = expected
test_dict['actual'] = " ".join(actual)
+ def is_expected(actual_result):
+ return expectations.matches_an_expected_result(test_name, result_type, port_obj.get_option('pixel_tests') or result.reftest_type)
+
+ # To avoid bloating the output results json too much, only add an entry for whether the failure is unexpected.
+ if not all(is_expected(actual_result) for actual_result in actual):
+ test_dict['is_unexpected'] = True
+
test_dict.update(_interpret_test_failures(result.failures))
if retry_results:
@@ -231,30 +242,37 @@
current_map = current_map[part]
results['tests'] = tests
+ # FIXME: Remove this. It is redundant with results['num_failures_by_type'].
results['num_passes'] = num_passes
results['num_flaky'] = num_flaky
+ # FIXME: Remove this. It is redundant with results['num_failures_by_type'].
results['num_missing'] = num_missing
results['num_regressions'] = num_regressions
+ # FIXME: This is always true for Blink. We should remove this and update the code in Layouts/fast/harness/results.html that uses this.
results['uses_expectations_file'] = port_obj.uses_test_expectations_file()
results['interrupted'] = initial_results.interrupted # Does results.html have enough information to compute this itself? (by checking total number of results vs. total number of tests?)
results['layout_tests_dir'] = port_obj.layout_tests_dir()
results['has_wdiff'] = port_obj.wdiff_available()
results['has_pretty_patch'] = port_obj.pretty_patch_available()
results['pixel_tests_enabled'] = port_obj.get_option('pixel_tests')
+ results['seconds_since_epoch'] = int(time.time())
+ results['build_number'] = port_obj.get_option('build_number')
+ results['builder_name'] = port_obj.get_option('builder_name')
try:
- # We only use the svn revision for using trac links in the results.html file,
# Don't do this by default since it takes >100ms.
- # FIXME: Do we really need to populate this both here and in the json_results_generator?
+ # It's only used for uploading data to the flakiness dashboard.
if port_obj.get_option("builder_name"):
port_obj.host.initialize_scm()
- results['revision'] = port_obj.host.scm().head_svn_revision()
+ for (name, path) in port_obj.repository_paths():
+ results[name.lower() + '_revision'] = port_obj.host.scm().svn_revision(path)
except Exception, e:
_log.warn("Failed to determine svn revision for checkout (cwd: %s, webkit_base: %s), leaving 'revision' key blank in full_results.json.\n%s" % (port_obj._filesystem.getcwd(), port_obj.path_from_webkit_base(), e))
# Handle cases where we're running outside of version control.
import traceback
_log.debug('Failed to learn head svn revision:')
_log.debug(traceback.format_exc())
- results['revision'] = ""
+ results['chromium_revision'] = ""
+ results['blink_revision'] = ""
return results
diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_run_results_unittest.py b/Tools/Scripts/webkitpy/layout_tests/models/test_run_results_unittest.py
index c0d9265..5c22306 100644
--- a/Tools/Scripts/webkitpy/layout_tests/models/test_run_results_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/models/test_run_results_unittest.py
@@ -48,7 +48,7 @@
def run_results(port):
tests = ['passes/text.html', 'failures/expected/timeout.html', 'failures/expected/crash.html', 'failures/expected/hang.html',
- 'failures/expected/audio.html']
+ 'failures/expected/audio.html', 'passes/skipped/skip.html']
expectations = test_expectations.TestExpectations(port, tests)
return test_run_results.TestRunResults(expectations, len(tests))
@@ -63,6 +63,9 @@
initial_results.add(get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected, test_is_slow)
initial_results.add(get_result('failures/expected/crash.html', test_expectations.CRASH), expected, test_is_slow)
elif passing:
+ skipped_result = get_result('passes/skipped/skip.html')
+ skipped_result.type = test_expectations.SKIP
+ initial_results.add(skipped_result, expected, test_is_slow)
initial_results.add(get_result('passes/text.html'), expected, test_is_slow)
initial_results.add(get_result('failures/expected/audio.html'), expected, test_is_slow)
initial_results.add(get_result('failures/expected/timeout.html'), expected, test_is_slow)
@@ -124,12 +127,34 @@
summary = summarized_results(self.port, expected=False, passing=False, flaky=False)
self.assertNotIn('revision', summary)
+ def test_num_failures_by_type(self):
+ summary = summarized_results(self.port, expected=False, passing=False, flaky=False)
+ self.assertEquals(summary['num_failures_by_type'], {'CRASH': 1, 'MISSING': 0, 'TEXT': 0, 'IMAGE': 0, 'PASS': 0, 'SKIP': 0, 'TIMEOUT': 2, 'IMAGE+TEXT': 0, 'FAIL': 0, 'AUDIO': 1})
+
+ summary = summarized_results(self.port, expected=True, passing=False, flaky=False)
+ self.assertEquals(summary['num_failures_by_type'], {'CRASH': 1, 'MISSING': 0, 'TEXT': 0, 'IMAGE': 0, 'PASS': 1, 'SKIP': 0, 'TIMEOUT': 1, 'IMAGE+TEXT': 0, 'FAIL': 0, 'AUDIO': 1})
+
+ summary = summarized_results(self.port, expected=False, passing=True, flaky=False)
+ self.assertEquals(summary['num_failures_by_type'], {'CRASH': 0, 'MISSING': 0, 'TEXT': 0, 'IMAGE': 0, 'PASS': 4, 'SKIP': 1, 'TIMEOUT': 0, 'IMAGE+TEXT': 0, 'FAIL': 0, 'AUDIO': 0})
+
def test_svn_revision(self):
self.port._options.builder_name = 'dummy builder'
summary = summarized_results(self.port, expected=False, passing=False, flaky=False)
- self.assertNotEquals(summary['revision'], '')
+ self.assertNotEquals(summary['blink_revision'], '')
def test_summarized_results_wontfix(self):
self.port._options.builder_name = 'dummy builder'
summary = summarized_results(self.port, expected=False, passing=False, flaky=False)
self.assertTrue(summary['tests']['failures']['expected']['hang.html']['wontfix'])
+ self.assertTrue(summary['tests']['passes']['text.html']['is_unexpected'])
+
+ def test_summarized_results_expected_pass(self):
+ self.port._options.builder_name = 'dummy builder'
+ summary = summarized_results(self.port, expected=False, passing=True, flaky=False)
+ self.assertTrue(summary['tests']['passes']['text.html'])
+ self.assertTrue('is_unexpected' not in summary['tests']['passes']['text.html'])
+
+ def test_summarized_results_skipped(self):
+ self.port._options.builder_name = 'dummy builder'
+ summary = summarized_results(self.port, expected=False, passing=True, flaky=False)
+ self.assertTrue(summary['tests']['passes']['skipped']['skip.html'])
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 56f7662..82a18be 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -1079,7 +1079,7 @@
# We use LayoutTest directory here because webkit_base isn't a part of WebKit repository in Chromium port
# where turnk isn't checked out as a whole.
- return [('WebKit', self.layout_tests_dir())]
+ return [('blink', self.layout_tests_dir())]
_WDIFF_DEL = '##WDIFF_DEL##'
_WDIFF_ADD = '##WDIFF_ADD##'
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py
index ce0564d..be8905b 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py
@@ -378,7 +378,7 @@
def repository_paths(self):
repos = super(ChromiumPort, self).repository_paths()
- repos.append(('Chromium', self.path_from_chromium_base('build')))
+ repos.append(('chromium', self.path_from_chromium_base('build')))
return repos
def _get_crash_log(self, name, pid, stdout, stderr, newer_than):
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/test.py b/Tools/Scripts/webkitpy/layout_tests/port/test.py
index b7f633c..dad7396 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/test.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/test.py
@@ -295,6 +295,7 @@
Bug(test) failures/expected/exception.html [ WontFix ]
Bug(test) failures/unexpected/pass.html [ Failure ]
Bug(test) passes/skipped/skip.html [ Skip ]
+Bug(test) passes/text.html [ Pass ]
""")
filesystem.maybe_make_directory(LAYOUT_TEST_DIR + '/reftests/foo')
diff --git a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
index ee9f86f..ff772ca 100644
--- a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
@@ -186,6 +186,11 @@
# properly on cygwin (bug 63846).
self.should_test_processes = not self._platform.is_win()
+ def assertHasTimeAndOtherValuesEqual(self, actual, expected):
+ self.assertTrue(actual['time'])
+ del actual['time']
+ self.assertEqual(actual, expected)
+
def test_basic(self):
options, args = parse_args(tests_included=True)
logging_stream = StringIO.StringIO()
@@ -496,9 +501,9 @@
tests_included=True, host=host)
file_list = host.filesystem.written_files.keys()
self.assertEqual(details.exit_code, 1)
- expected_token = '"unexpected":{"text-image-checksum.html":{"expected":"PASS","actual":"IMAGE+TEXT","image_diff_percent":1},"missing_text.html":{"expected":"PASS","is_missing_text":true,"actual":"MISSING"}'
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
- self.assertTrue(json_string.find(expected_token) != -1)
+ self.assertTrue(json_string.find('"text-image-checksum.html":{"actual":"IMAGE+TEXT","is_unexpected":true,"expected":"PASS"') != -1)
+ self.assertTrue(json_string.find('"missing_text.html":{"expected":"PASS","is_missing_text":true,"is_unexpected":true,"actual":"MISSING"') != -1)
self.assertTrue(json_string.find('"num_regressions":1') != -1)
self.assertTrue(json_string.find('"num_flaky":0') != -1)
self.assertTrue(json_string.find('"num_missing":1') != -1)
@@ -506,14 +511,14 @@
def test_pixel_test_directories(self):
host = MockHost()
- """Both tests have faling checksum. We include only the first in pixel tests so only that should fail."""
+ """Both tests have failing checksum. We include only the first in pixel tests so only that should fail."""
args = ['--pixel-tests', '--pixel-test-directory', 'failures/unexpected/pixeldir',
'failures/unexpected/pixeldir/image_in_pixeldir.html',
'failures/unexpected/image_not_in_pixeldir.html']
details, err, _ = logging_run(extra_args=args, host=host, tests_included=True)
self.assertEqual(details.exit_code, 1)
- expected_token = '"unexpected":{"pixeldir":{"image_in_pixeldir.html":{"expected":"PASS","actual":"IMAGE"'
+ expected_token = 'pixeldir":{"image_in_pixeldir.html":{"actual":"IMAGE","is_unexpected":true,"expected":"PASS",'
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
self.assertTrue(json_string.find(expected_token) != -1)
@@ -537,7 +542,7 @@
def test_crash_with_stderr(self):
host = MockHost()
_, regular_output, _ = logging_run(['failures/unexpected/crash-with-stderr.html'], tests_included=True, host=host)
- self.assertTrue(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json').find('{"crash-with-stderr.html":{"expected":"PASS","actual":"CRASH","has_stderr":true}}') != -1)
+ self.assertTrue(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json').find('{"crash-with-stderr.html":{"expected":"PASS","is_unexpected":true,"actual":"CRASH","has_stderr":true') != -1)
def test_no_image_failure_with_image_diff(self):
host = MockHost()
@@ -666,8 +671,8 @@
self.assertTrue(host.filesystem.exists('/tmp/layout-test-results/retries/failures/unexpected/text-image-checksum-actual.png'))
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
json = parse_full_results(json_string)
- self.assertEqual(json["tests"]["failures"]["unexpected"]["text-image-checksum.html"],
- {"expected": "PASS", "actual": "TEXT IMAGE+TEXT", "image_diff_percent": 1})
+ self.assertHasTimeAndOtherValuesEqual(json["tests"]["failures"]["unexpected"]["text-image-checksum.html"],
+ {"expected": "PASS", "actual": "TEXT IMAGE+TEXT", "image_diff_percent": 1, "is_unexpected": True})
self.assertFalse(json["pixel_tests_enabled"])
self.assertEqual(details.enabled_pixel_tests_in_retry, True)
@@ -749,7 +754,7 @@
host = MockHost()
_, err, _ = logging_run(['--no-show-results', 'reftests/foo/'], tests_included=True, host=host)
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
- self.assertTrue(json_string.find('"unlistedtest.html":{"expected":"PASS","is_missing_text":true,"actual":"MISSING","is_missing_image":true}') != -1)
+ self.assertTrue(json_string.find('"unlistedtest.html":{"actual":"MISSING","is_missing_image":true,"is_unexpected":true,"expected":"PASS","is_missing_text":true') != -1)
self.assertTrue(json_string.find('"num_regressions":4') != -1)
self.assertTrue(json_string.find('"num_flaky":0') != -1)
self.assertTrue(json_string.find('"num_missing":1') != -1)
@@ -847,6 +852,11 @@
class EndToEndTest(unittest.TestCase):
+ def assertHasTimeAndOtherValuesEqual(self, actual, expected):
+ self.assertTrue(actual['time'])
+ del actual['time']
+ self.assertEqual(actual, expected)
+
def test_reftest_with_two_notrefs(self):
# Test that we update expectations in place. If the expectation
# is missing, update the expected generic location.
@@ -856,15 +866,16 @@
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
json = parse_full_results(json_string)
- self.assertTrue("multiple-match-success.html" not in json["tests"]["reftests"]["foo"])
- self.assertTrue("multiple-mismatch-success.html" not in json["tests"]["reftests"]["foo"])
- self.assertTrue("multiple-both-success.html" not in json["tests"]["reftests"]["foo"])
- self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-match-failure.html"],
- {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["=="], "image_diff_percent": 1})
- self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-mismatch-failure.html"],
- {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["!="]})
- self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-both-failure.html"],
- {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["==", "!="]})
+ self.assertTrue("is_unexpected" not in json["tests"]["reftests"]["foo"]["multiple-match-success.html"])
+ self.assertTrue("is_unexpected" not in json["tests"]["reftests"]["foo"]["multiple-mismatch-success.html"])
+ self.assertTrue("is_unexpected" not in json["tests"]["reftests"]["foo"]["multiple-both-success.html"])
+
+ self.assertHasTimeAndOtherValuesEqual(json["tests"]["reftests"]["foo"]["multiple-match-failure.html"],
+ {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["=="], "image_diff_percent": 1, "is_unexpected": True})
+ self.assertHasTimeAndOtherValuesEqual(json["tests"]["reftests"]["foo"]["multiple-mismatch-failure.html"],
+ {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["!="], "is_unexpected": True})
+ self.assertHasTimeAndOtherValuesEqual(json["tests"]["reftests"]["foo"]["multiple-both-failure.html"],
+ {"expected": "PASS", "actual": "IMAGE", "reftest_type": ["==", "!="], "is_unexpected": True})
class RebaselineTest(unittest.TestCase, StreamTestingMixin):
diff --git a/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py b/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py
index 3191b84..e7dabab 100644
--- a/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py
+++ b/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py
@@ -100,10 +100,7 @@
actual = results['actual'].split(" ")
expected = results['expected'].split(" ")
- def is_expected(result):
- return (result in expected) or (result in ('AUDIO', 'TEXT', 'IMAGE+TEXT') and 'FAIL' in expected)
-
- if all(is_expected(actual_result) for actual_result in actual):
+ if 'is_unexpected' not in results or not results['is_unexpected']:
# Don't print anything for tests that ran as expected.
return
diff --git a/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py b/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py
index 5ce15c1..8951a63 100644
--- a/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py
@@ -87,7 +87,9 @@
printer, out = self.get_printer()
summary = test_run_results_unittest.summarized_results(port, expected=False, passing=True, flaky=False)
printer.print_unexpected_results(summary)
- self.assertNotEmpty(out)
+ output = out.getvalue()
+ self.assertTrue(output)
+ self.assertTrue(output.find('Skip') == -1)
def test_print_results(self):
port = MockHost().port_factory.get('test')
diff --git a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
index 8bc2148..67ca54e 100644
--- a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
+++ b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
@@ -353,7 +353,7 @@
self._test_run_with_json_output(runner, port.host.filesystem, upload_succeeds=True)
self.assertEqual(self._load_output_json(runner), [{
"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
filesystem = port.host.filesystem
self.assertTrue(filesystem.isfile(runner._output_json_path()))
@@ -366,7 +366,7 @@
self.assertEqual(self._load_output_json(runner), [{
"buildTime": "2013-02-08T15:19:37.460000", "description": "some description",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
def create_runner_and_setup_results_template(self, args=[]):
runner, port = self.create_runner(args)
@@ -396,7 +396,7 @@
self.assertEqual(self._load_output_json(runner), [{
"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
self.assertTrue(filesystem.isfile(output_json_path))
self.assertTrue(filesystem.isfile(results_page_path))
@@ -412,7 +412,7 @@
self.assertEqual(self._load_output_json(runner), [{"previous": "results"}, {
"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
self.assertTrue(filesystem.isfile(filesystem.splitext(output_json_path)[0] + '.html'))
def test_run_respects_reset_results(self):
@@ -426,7 +426,7 @@
self.assertEqual(self._load_output_json(runner), [{
"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
self.assertTrue(filesystem.isfile(filesystem.splitext(output_json_path)[0] + '.html'))
pass
@@ -438,7 +438,7 @@
self._test_run_with_json_output(runner, filesystem, results_shown=False)
expected_entry = {"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}
self.maxDiff = None
self.assertEqual(runner._output_json_path(), '/mock-checkout/output.json')
@@ -485,7 +485,7 @@
self._test_run_with_json_output(runner, port.host.filesystem, upload_succeeds=True)
self.assertEqual(self._load_output_json(runner), [{
"buildTime": "2013-02-08T15:19:37.460000", "tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}, "builderKey": "value"}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}, "builderKey": "value"}])
def test_run_with_bad_slave_config_json(self):
runner, port = self.create_runner_and_setup_results_template(args=['--output-json-path=/mock-checkout/output.json',
@@ -537,7 +537,7 @@
self.assertEqual(output['buildTime'], '2013-02-08T15:19:37.460000')
self.assertEqual(output['builderName'], 'builder1')
self.assertEqual(output['builderKey'], 'value1')
- self.assertEqual(output['revisions'], {'WebKit': {'revision': '5678', 'timestamp': '2013-02-01 08:48:05 +0000'}})
+ self.assertEqual(output['revisions'], {'blink': {'revision': '5678', 'timestamp': '2013-02-01 08:48:05 +0000'}})
self.assertEqual(output['tests'].keys(), ['Bindings'])
self.assertEqual(sorted(output['tests']['Bindings'].keys()), ['tests', 'url'])
self.assertEqual(output['tests']['Bindings']['url'], 'http://trac.webkit.org/browser/trunk/PerformanceTests/Bindings')
@@ -547,25 +547,26 @@
'metrics': {'Time': {'current': [[1486.0, 1471.0, 1510.0, 1505.0, 1478.0, 1490.0]] * 4}}})
def test_run_with_repeat(self):
+ self.maxDiff = None
runner, port = self.create_runner_and_setup_results_template(args=['--output-json-path=/mock-checkout/output.json',
'--test-results-server=some.host', '--repeat', '5'])
self._test_run_with_json_output(runner, port.host.filesystem, upload_succeeds=True, repeat=5)
self.assertEqual(self._load_output_json(runner), [
{"buildTime": "2013-02-08T15:19:37.460000",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
{"buildTime": "2013-02-08T15:19:37.460000",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
{"buildTime": "2013-02-08T15:19:37.460000",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
{"buildTime": "2013-02-08T15:19:37.460000",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}},
{"buildTime": "2013-02-08T15:19:37.460000",
"tests": self._event_target_wrapper_and_inspector_results,
- "revisions": {"WebKit": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
+ "revisions": {"blink": {"timestamp": "2013-02-01 08:48:05 +0000", "revision": "5678"}}}])
def test_run_with_test_runner_count(self):
runner, port = self.create_runner_and_setup_results_template(args=['--output-json-path=/mock-checkout/output.json',
diff --git a/Tools/Scripts/webkitpy/style/checkers/cpp.py b/Tools/Scripts/webkitpy/style/checkers/cpp.py
index 69df432..5810e9c 100644
--- a/Tools/Scripts/webkitpy/style/checkers/cpp.py
+++ b/Tools/Scripts/webkitpy/style/checkers/cpp.py
@@ -2857,9 +2857,9 @@
'Streams are highly discouraged.')
# Look for specific includes to fix.
- if include.startswith('wtf/') and not is_system:
+ if include.startswith('wtf/') and is_system:
error(line_number, 'build/include', 4,
- 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".')
+ 'wtf includes should be "wtf/file.h" instead of <wtf/file.h>.')
if filename.find('/chromium/') != -1 and include.startswith('cc/CC'):
error(line_number, 'build/include', 4,
diff --git a/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py b/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
index 20a0b79..c0f2da3 100644
--- a/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
+++ b/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
@@ -2831,14 +2831,14 @@
'#include "foo.h"\n'
'\n'
'#include <wtf/Assertions.h>\n',
- '')
+ 'wtf includes should be "wtf/file.h" instead of <wtf/file.h>.'
+ ' [build/include] [4]')
self.assert_language_rules_check('foo.cpp',
'#include "config.h"\n'
'#include "foo.h"\n'
'\n'
'#include "wtf/Assertions.h"\n',
- 'wtf includes should be <wtf/file.h> instead of "wtf/file.h".'
- ' [build/include] [4]')
+ '')
def test_check_cc_includes(self):
self.assert_language_rules_check('bar/chromium/foo.cpp',
diff --git a/Tools/Scripts/webkitpy/tool/commands/__init__.py b/Tools/Scripts/webkitpy/tool/commands/__init__.py
index 24646fc..57bba31 100644
--- a/Tools/Scripts/webkitpy/tool/commands/__init__.py
+++ b/Tools/Scripts/webkitpy/tool/commands/__init__.py
@@ -4,18 +4,13 @@
from webkitpy.tool.commands.analyzechangelog import AnalyzeChangeLog
from webkitpy.tool.commands.applywatchlistlocal import ApplyWatchListLocal
from webkitpy.tool.commands.bugfortest import BugForTest
-from webkitpy.tool.commands.bugsearch import BugSearch
from webkitpy.tool.commands.chromechannels import ChromeChannels
from webkitpy.tool.commands.download import *
-from webkitpy.tool.commands.earlywarningsystem import *
from webkitpy.tool.commands.findusers import FindUsers
from webkitpy.tool.commands.gardenomatic import GardenOMatic
-from webkitpy.tool.commands.openbugs import OpenBugs
from webkitpy.tool.commands.prettydiff import PrettyDiff
from webkitpy.tool.commands.queries import *
-from webkitpy.tool.commands.queues import *
from webkitpy.tool.commands.rebaseline import Rebaseline
from webkitpy.tool.commands.rebaselineserver import RebaselineServer
-from webkitpy.tool.commands.roll import *
from webkitpy.tool.commands.upload import *
from webkitpy.tool.commands.suggestnominations import *
diff --git a/Tools/Scripts/webkitpy/tool/commands/bugsearch.py b/Tools/Scripts/webkitpy/tool/commands/bugsearch.py
deleted file mode 100644
index a1d74c5..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/bugsearch.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (c) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
-
-
-class BugSearch(AbstractDeclarativeCommand):
- name = "bug-search"
- help_text = "List bugs matching a query"
- argument_names = "QUERY"
- long_help = \
-"""Runs the bugzilla quicksearch QUERY on bugs.webkit.org, and lists all bugs
-returned. QUERY can be as simple as a bug number or a comma delimited list of
-bug numbers.
-See https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html for full
-documentation on the query format."""
-
- def execute(self, options, args, tool):
- search_string = args[0]
- bugs = tool.bugs.queries.fetch_bugs_matching_quicksearch(search_string)
- for bug in bugs:
- print "%5s %s" % (bug.id(), bug.title())
- if not bugs:
- print "No bugs found matching '%s'" % search_string
diff --git a/Tools/Scripts/webkitpy/tool/commands/download.py b/Tools/Scripts/webkitpy/tool/commands/download.py
index 395c913..f6c903e 100644
--- a/Tools/Scripts/webkitpy/tool/commands/download.py
+++ b/Tools/Scripts/webkitpy/tool/commands/download.py
@@ -63,420 +63,9 @@
]
-class Build(AbstractSequencedCommand):
- name = "build"
- help_text = "Update working copy and build"
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.Build,
- ]
-
- def _prepare_state(self, options, args, tool):
- options.build = True
-
-
-class BuildAndTest(AbstractSequencedCommand):
- name = "build-and-test"
- help_text = "Update working copy, build, and run the tests"
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.Build,
- steps.RunTests,
- ]
-
-
-class Land(AbstractSequencedCommand):
- name = "land"
- help_text = "Land the current working directory diff and updates the associated bug if any"
- argument_names = "[BUGID]"
- show_in_main_help = True
- steps = [
- steps.AddSvnMimetypeForPng,
- steps.UpdateChangeLogsWithReviewer,
- steps.ValidateReviewer,
- steps.ValidateChangeLogs, # We do this after UpdateChangeLogsWithReviewer to avoid not having to cache the diff twice.
- steps.Build,
- steps.RunTests,
- steps.Commit,
- steps.CloseBugForLandDiff,
- ]
- long_help = """land commits the current working copy diff (just as svn or git commit would).
-land will NOT build and run the tests before committing, but you can use the --build option for that.
-If a bug id is provided, or one can be found in the ChangeLog land will update the bug after committing."""
-
- def _prepare_state(self, options, args, tool):
- changed_files = self._tool.scm().changed_files(options.git_commit)
- return {
- "changed_files": changed_files,
- "bug_id": (args and args[0]) or tool.checkout().bug_id_for_this_commit(options.git_commit, changed_files),
- }
-
-
-class LandCowboy(AbstractSequencedCommand):
- name = "land-cowboy"
- help_text = "Prepares a ChangeLog and lands the current working directory diff."
- steps = [
- steps.PrepareChangeLog,
- steps.EditChangeLog,
- steps.CheckStyle,
- steps.ConfirmDiff,
- steps.Build,
- steps.RunTests,
- steps.Commit,
- steps.CloseBugForLandDiff,
- ]
-
- def _prepare_state(self, options, args, tool):
- options.check_style_filter = "-changelog"
-
-
-class LandCowhand(LandCowboy):
- # Gender-blind term for cowboy, see: http://en.wiktionary.org/wiki/cowhand
- name = "land-cowhand"
-
-
class CheckStyleLocal(AbstractSequencedCommand):
name = "check-style-local"
help_text = "Run check-webkit-style on the current working directory diff"
steps = [
steps.CheckStyle,
]
-
-
-class AbstractPatchProcessingCommand(AbstractDeclarativeCommand):
- # Subclasses must implement the methods below. We don't declare them here
- # because we want to be able to implement them with mix-ins.
- #
- # pylint: disable=E1101
- # def _fetch_list_of_patches_to_process(self, options, args, tool):
- # def _prepare_to_process(self, options, args, tool):
- # def _process_patch(self, options, args, tool):
-
- @staticmethod
- def _collect_patches_by_bug(patches):
- bugs_to_patches = {}
- for patch in patches:
- bugs_to_patches[patch.bug_id()] = bugs_to_patches.get(patch.bug_id(), []) + [patch]
- return bugs_to_patches
-
- def execute(self, options, args, tool):
- self._prepare_to_process(options, args, tool)
- patches = self._fetch_list_of_patches_to_process(options, args, tool)
-
- # It's nice to print out total statistics.
- bugs_to_patches = self._collect_patches_by_bug(patches)
- _log.info("Processing %s from %s." % (pluralize("patch", len(patches)), pluralize("bug", len(bugs_to_patches))))
-
- for patch in patches:
- self._process_patch(patch, options, args, tool)
-
-
-class AbstractPatchSequencingCommand(AbstractPatchProcessingCommand):
- prepare_steps = None
- main_steps = None
-
- def __init__(self):
- options = []
- self._prepare_sequence = StepSequence(self.prepare_steps)
- self._main_sequence = StepSequence(self.main_steps)
- options = sorted(set(self._prepare_sequence.options() + self._main_sequence.options()))
- AbstractPatchProcessingCommand.__init__(self, options)
-
- def _prepare_to_process(self, options, args, tool):
- self._prepare_sequence.run_and_handle_errors(tool, options)
-
- def _process_patch(self, patch, options, args, tool):
- state = { "patch" : patch }
- self._main_sequence.run_and_handle_errors(tool, options, state)
-
-
-class ProcessAttachmentsMixin(object):
- def _fetch_list_of_patches_to_process(self, options, args, tool):
- return map(lambda patch_id: tool.bugs.fetch_attachment(patch_id), args)
-
-
-class ProcessBugsMixin(object):
- def _fetch_list_of_patches_to_process(self, options, args, tool):
- all_patches = []
- for bug_id in args:
- patches = tool.bugs.fetch_bug(bug_id).reviewed_patches()
- _log.info("%s found on bug %s." % (pluralize("reviewed patch", len(patches)), bug_id))
- all_patches += patches
- if not all_patches:
- _log.info("No reviewed patches found, looking for unreviewed patches.")
- for bug_id in args:
- patches = tool.bugs.fetch_bug(bug_id).patches()
- _log.info("%s found on bug %s." % (pluralize("patch", len(patches)), bug_id))
- all_patches += patches
- return all_patches
-
-
-class ProcessURLsMixin(object):
- def _fetch_list_of_patches_to_process(self, options, args, tool):
- all_patches = []
- for url in args:
- bug_id = urls.parse_bug_id(url)
- if bug_id:
- patches = tool.bugs.fetch_bug(bug_id).patches()
- _log.info("%s found on bug %s." % (pluralize("patch", len(patches)), bug_id))
- all_patches += patches
-
- attachment_id = urls.parse_attachment_id(url)
- if attachment_id:
- all_patches += tool.bugs.fetch_attachment(attachment_id)
-
- return all_patches
-
-
-class CheckStyle(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "check-style"
- help_text = "Run check-webkit-style on the specified attachments"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.CheckStyle,
- ]
-
-
-class BuildAttachment(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "build-attachment"
- help_text = "Apply and build patches from bugzilla"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.Build,
- ]
-
-
-class BuildAndTestAttachment(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "build-and-test-attachment"
- help_text = "Apply, build, and test patches from bugzilla"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.Build,
- steps.RunTests,
- ]
-
-
-class AbstractPatchApplyingCommand(AbstractPatchSequencingCommand):
- prepare_steps = [
- steps.EnsureLocalCommitIfNeeded,
- steps.CleanWorkingDirectory,
- steps.Update,
- ]
- main_steps = [
- steps.ApplyPatchWithLocalCommit,
- ]
- long_help = """Updates the working copy.
-Downloads and applies the patches, creating local commits if necessary."""
-
-
-class ApplyAttachment(AbstractPatchApplyingCommand, ProcessAttachmentsMixin):
- name = "apply-attachment"
- help_text = "Apply an attachment to the local working directory"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- show_in_main_help = True
-
-
-class ApplyFromBug(AbstractPatchApplyingCommand, ProcessBugsMixin):
- name = "apply-from-bug"
- help_text = "Apply reviewed patches from provided bugs to the local working directory"
- argument_names = "BUGID [BUGIDS]"
- show_in_main_help = True
-
-
-class ApplyWatchList(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "apply-watchlist"
- help_text = "Applies the watchlist to the specified attachments"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.ApplyWatchList,
- ]
- long_help = """"Applies the watchlist to the specified attachments.
-Downloads the attachment, applies it locally, runs the watchlist against it, and updates the bug with the result."""
-
-
-class AbstractPatchLandingCommand(AbstractPatchSequencingCommand):
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.ValidateChangeLogs,
- steps.ValidateReviewer,
- steps.Build,
- steps.RunTests,
- steps.Commit,
- steps.ClosePatch,
- steps.CloseBug,
- ]
- long_help = """Checks to make sure builders are green.
-Updates the working copy.
-Applies the patch.
-Builds.
-Runs the layout tests.
-Commits the patch.
-Clears the flags on the patch.
-Closes the bug if no patches are marked for review."""
-
-
-class LandAttachment(AbstractPatchLandingCommand, ProcessAttachmentsMixin):
- name = "land-attachment"
- help_text = "Land patches from bugzilla, optionally building and testing them first"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- show_in_main_help = True
-
-
-class LandFromBug(AbstractPatchLandingCommand, ProcessBugsMixin):
- name = "land-from-bug"
- help_text = "Land all patches on the given bugs, optionally building and testing them first"
- argument_names = "BUGID [BUGIDS]"
- show_in_main_help = True
-
-
-class LandFromURL(AbstractPatchLandingCommand, ProcessURLsMixin):
- name = "land-from-url"
- help_text = "Land all patches on the given URLs, optionally building and testing them first"
- argument_names = "URL [URLS]"
-
-
-class ValidateChangelog(AbstractSequencedCommand):
- name = "validate-changelog"
- help_text = "Validate that the ChangeLogs and reviewers look reasonable"
- long_help = """Examines the current diff to see whether the ChangeLogs
-and the reviewers listed in the ChangeLogs look reasonable.
-"""
- steps = [
- steps.ValidateChangeLogs,
- steps.ValidateReviewer,
- ]
-
-
-class AbstractRolloutPrepCommand(AbstractSequencedCommand):
- argument_names = "REVISION [REVISIONS] REASON"
-
- def _commit_info(self, revision):
- commit_info = self._tool.checkout().commit_info_for_revision(revision)
- if commit_info and commit_info.bug_id():
- # Note: Don't print a bug URL here because it will confuse the
- # SheriffBot because the SheriffBot just greps the output
- # of create-rollout for bug URLs. It should do better
- # parsing instead.
- _log.info("Preparing rollout for bug %s." % commit_info.bug_id())
- else:
- _log.info("Unable to parse bug number from diff.")
- return commit_info
-
- def _prepare_state(self, options, args, tool):
- revision_list = []
- for revision in str(args[0]).split():
- if revision.isdigit():
- revision_list.append(int(revision))
- else:
- raise ScriptError(message="Invalid svn revision number: " + revision)
- revision_list.sort()
-
- # We use the earliest revision for the bug info
- earliest_revision = revision_list[0]
- state = {
- "revision": earliest_revision,
- "revision_list": revision_list,
- "reason": args[1],
- }
- commit_info = self._commit_info(earliest_revision)
- if commit_info:
- state["bug_id"] = commit_info.bug_id()
- cc_list = sorted([party.bugzilla_email()
- for party in commit_info.responsible_parties()
- if party.bugzilla_email()])
- # FIXME: We should used the list as the canonical representation.
- state["bug_cc"] = ",".join(cc_list)
- return state
-
-
-class PrepareRollout(AbstractRolloutPrepCommand):
- name = "prepare-rollout"
- help_text = "Revert the given revision(s) in the working copy and prepare ChangeLogs with revert reason"
- long_help = """Updates the working copy.
-Applies the inverse diff for the provided revision(s).
-Creates an appropriate rollout ChangeLog, including a trac link and bug link.
-"""
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.RevertRevision,
- steps.PrepareChangeLogForRevert,
- ]
-
-
-class CreateRollout(AbstractRolloutPrepCommand):
- name = "create-rollout"
- help_text = "Creates a bug to track the broken SVN revision(s) and uploads a rollout patch."
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.RevertRevision,
- steps.CreateBug,
- steps.PrepareChangeLogForRevert,
- steps.PostDiffForRevert,
- ]
-
- def _prepare_state(self, options, args, tool):
- state = AbstractRolloutPrepCommand._prepare_state(self, options, args, tool)
- # Currently, state["bug_id"] points to the bug that caused the
- # regression. We want to create a new bug that blocks the old bug
- # so we move state["bug_id"] to state["bug_blocked"] and delete the
- # old state["bug_id"] so that steps.CreateBug will actually create
- # the new bug that we want (and subsequently store its bug id into
- # state["bug_id"])
- state["bug_blocked"] = state["bug_id"]
- del state["bug_id"]
- state["bug_title"] = "REGRESSION(r%s): %s" % (state["revision"], state["reason"])
- state["bug_description"] = "%s broke the build:\n%s" % (urls.view_revision_url(state["revision"]), state["reason"])
- # FIXME: If we had more context here, we could link to other open bugs
- # that mention the test that regressed.
- if options.parent_command == "sheriff-bot":
- state["bug_description"] += """
-
-This is an automatic bug report generated by the sheriff-bot. If this bug
-report was created because of a flaky test, please file a bug for the flaky
-test (if we don't already have one on file) and dup this bug against that bug
-so that we can track how often these flaky tests case pain.
-
-"Only you can prevent forest fires." -- Smokey the Bear
-"""
- return state
-
-
-class Rollout(AbstractRolloutPrepCommand):
- name = "rollout"
- show_in_main_help = True
- help_text = "Revert the given revision(s) in the working copy and optionally commit the revert and re-open the original bug"
- long_help = """Updates the working copy.
-Applies the inverse diff for the provided revision.
-Creates an appropriate rollout ChangeLog, including a trac link and bug link.
-Opens the generated ChangeLogs in $EDITOR.
-Shows the prepared diff for confirmation.
-Commits the revert and updates the bug (including re-opening the bug if necessary)."""
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.RevertRevision,
- steps.PrepareChangeLogForRevert,
- steps.EditChangeLog,
- steps.ConfirmDiff,
- steps.Build,
- steps.Commit,
- steps.ReopenBugAfterRollout,
- ]
diff --git a/Tools/Scripts/webkitpy/tool/commands/download_unittest.py b/Tools/Scripts/webkitpy/tool/commands/download_unittest.py
index dbbdf2d..1dc5b4a 100644
--- a/Tools/Scripts/webkitpy/tool/commands/download_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/commands/download_unittest.py
@@ -36,42 +36,6 @@
from webkitpy.common.checkout.checkout_mock import MockCheckout
-class AbstractRolloutPrepCommandTest(unittest.TestCase):
- def test_commit_info(self):
- command = AbstractRolloutPrepCommand()
- tool = MockTool()
- command.bind_to_tool(tool)
- output = OutputCapture()
-
- expected_logs = "Preparing rollout for bug 50000.\n"
- commit_info = output.assert_outputs(self, command._commit_info, [1234], expected_logs=expected_logs)
- self.assertTrue(commit_info)
-
- mock_commit_info = Mock()
- mock_commit_info.bug_id = lambda: None
- tool._checkout.commit_info_for_revision = lambda revision: mock_commit_info
- expected_logs = "Unable to parse bug number from diff.\n"
- commit_info = output.assert_outputs(self, command._commit_info, [1234], expected_logs=expected_logs)
- self.assertEqual(commit_info, mock_commit_info)
-
- def test_prepare_state(self):
- command = AbstractRolloutPrepCommand()
- mock_commit_info = MockCheckout().commit_info_for_revision(123)
- command._commit_info = lambda revision: mock_commit_info
-
- state = command._prepare_state(None, ["124 123 125", "Reason"], None)
- self.assertEqual(123, state["revision"])
- self.assertEqual([123, 124, 125], state["revision_list"])
-
- self.assertRaises(ScriptError, command._prepare_state, options=None, args=["125 r122 123", "Reason"], tool=None)
- self.assertRaises(ScriptError, command._prepare_state, options=None, args=["125 foo 123", "Reason"], tool=None)
-
- command._commit_info = lambda revision: None
- state = command._prepare_state(None, ["124 123 125", "Reason"], None)
- self.assertEqual(123, state["revision"])
- self.assertEqual([123, 124, 125], state["revision_list"])
-
-
class DownloadCommandsTest(CommandsTest):
maxDiff = None
@@ -90,267 +54,3 @@
options.test = True
options.update = True
return options
-
- def test_build(self):
- expected_logs = "Updating working directory\nBuilding WebKit\n"
- self.assert_execute_outputs(Build(), [], options=self._default_options(), expected_logs=expected_logs)
-
- def test_build_and_test(self):
- expected_logs = """Updating working directory
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-"""
- self.assert_execute_outputs(BuildAndTest(), [], options=self._default_options(), expected_logs=expected_logs)
-
- def test_apply_attachment(self):
- options = self._default_options()
- options.update = True
- options.local_commit = True
- expected_logs = "Updating working directory\nProcessing 1 patch from 1 bug.\nProcessing patch 10000 from bug 50000.\n"
- self.assert_execute_outputs(ApplyAttachment(), [10000], options=options, expected_logs=expected_logs)
-
- def test_apply_from_bug(self):
- options = self._default_options()
- options.update = True
- options.local_commit = True
-
- expected_logs = "Updating working directory\n0 reviewed patches found on bug 50001.\nNo reviewed patches found, looking for unreviewed patches.\n1 patch found on bug 50001.\nProcessing 1 patch from 1 bug.\nProcessing patch 10002 from bug 50001.\n"
- self.assert_execute_outputs(ApplyFromBug(), [50001], options=options, expected_logs=expected_logs)
-
- expected_logs = "Updating working directory\n2 reviewed patches found on bug 50000.\nProcessing 2 patches from 1 bug.\nProcessing patch 10000 from bug 50000.\nProcessing patch 10001 from bug 50000.\n"
- self.assert_execute_outputs(ApplyFromBug(), [50000], options=options, expected_logs=expected_logs)
-
- def test_apply_watch_list(self):
- expected_logs = """Processing 1 patch from 1 bug.
-Updating working directory
-MOCK run_and_throw_if_fail: ['mock-update-webkit'], cwd=/mock-checkout
-Processing patch 10000 from bug 50000.
-MockWatchList: determine_cc_and_messages
-No bug was updated because no id was given.
-Result of watchlist: cc "abarth@webkit.org, eric@webkit.org, levin@chromium.org" messages "Message1.
-
-Message2."
-"""
- self.assert_execute_outputs(ApplyWatchList(), [10000], options=self._default_options(), expected_logs=expected_logs, tool=MockTool(log_executive=True))
-
- def test_land(self):
- expected_logs = """Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Updating bug 50000
-"""
- mock_tool = MockTool()
- mock_tool.scm().create_patch = Mock(return_value="Patch1\nMockPatch\n")
- mock_tool.checkout().modified_changelogs = Mock(return_value=[])
- self.assert_execute_outputs(Land(), [50000], options=self._default_options(), expected_logs=expected_logs, tool=mock_tool)
- # Make sure we're not calling expensive calls too often.
- self.assertEqual(mock_tool.scm().create_patch.call_count, 0)
- self.assertEqual(mock_tool.checkout().modified_changelogs.call_count, 1)
-
- def test_land_cowboy(self):
- expected_logs = """MOCK run_and_throw_if_fail: ['mock-prepare-ChangeLog', '--email=MOCK email', '--merge-base=None', 'MockFile1'], cwd=/mock-checkout
-MOCK run_and_throw_if_fail: ['mock-check-webkit-style', '--git-commit', 'MOCK git commit', '--diff-files', 'MockFile1', '--filter', '-changelog'], cwd=/mock-checkout
-MOCK run_command: ['ruby', '-I', '/mock-checkout/Tools/Scripts/webkitruby/PrettyPatch', '/mock-checkout/Tools/Scripts/webkitruby/PrettyPatch/prettify.rb'], cwd=None, input=Patch1
-MOCK: user.open_url: file://...
-Was that diff correct?
-Building WebKit
-MOCK run_and_throw_if_fail: ['mock-build-webkit'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}
-Running Python unit tests
-MOCK run_and_throw_if_fail: ['mock-test-webkitpy'], cwd=/mock-checkout
-Running Perl unit tests
-MOCK run_and_throw_if_fail: ['mock-test-webkitperl'], cwd=/mock-checkout
-Running JavaScriptCore tests
-MOCK run_and_throw_if_fail: ['mock-run-javacriptcore-tests'], cwd=/mock-checkout
-Running bindings generation tests
-MOCK run_and_throw_if_fail: ['mock-run-bindings-tests'], cwd=/mock-checkout
-Running WebKit unit tests
-MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests'], cwd=/mock-checkout
-Running run-webkit-tests
-MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--quiet'], cwd=/mock-checkout
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-No bug id provided.
-"""
- mock_tool = MockTool(log_executive=True)
- self.assert_execute_outputs(LandCowboy(), [50000], options=self._default_options(), expected_logs=expected_logs, tool=mock_tool)
-
- def test_land_red_builders(self):
- expected_logs = """Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Updating bug 50000
-"""
- mock_tool = MockTool()
- mock_tool.buildbot.light_tree_on_fire()
- self.assert_execute_outputs(Land(), [50000], options=self._default_options(), expected_logs=expected_logs, tool=mock_tool)
-
- def test_check_style(self):
- expected_logs = """Processing 1 patch from 1 bug.
-Updating working directory
-MOCK run_and_throw_if_fail: ['mock-update-webkit'], cwd=/mock-checkout
-Processing patch 10000 from bug 50000.
-MOCK run_and_throw_if_fail: ['mock-check-webkit-style', '--git-commit', 'MOCK git commit', '--diff-files', 'MockFile1'], cwd=/mock-checkout
-"""
- self.assert_execute_outputs(CheckStyle(), [10000], options=self._default_options(), expected_logs=expected_logs, tool=MockTool(log_executive=True))
-
- def test_build_attachment(self):
- expected_logs = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 10000 from bug 50000.\nBuilding WebKit\n"
- self.assert_execute_outputs(BuildAttachment(), [10000], options=self._default_options(), expected_logs=expected_logs)
-
- def test_land_attachment(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_logs = """Processing 1 patch from 1 bug.
-Updating working directory
-Processing patch 10000 from bug 50000.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-"""
- self.assert_execute_outputs(LandAttachment(), [10000], options=self._default_options(), expected_logs=expected_logs)
-
- def test_land_from_bug(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_logs = """2 reviewed patches found on bug 50000.
-Processing 2 patches from 1 bug.
-Updating working directory
-Processing patch 10000 from bug 50000.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-Updating working directory
-Processing patch 10001 from bug 50000.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-"""
- self.assert_execute_outputs(LandFromBug(), [50000], options=self._default_options(), expected_logs=expected_logs)
-
- def test_land_from_url(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_logs = """2 patches found on bug 50000.
-Processing 2 patches from 1 bug.
-Updating working directory
-Processing patch 10000 from bug 50000.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-Updating working directory
-Processing patch 10001 from bug 50000.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running bindings generation tests
-Running WebKit unit tests
-Running run-webkit-tests
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-"""
- self.assert_execute_outputs(LandFromURL(), ["https://bugs.webkit.org/show_bug.cgi?id=50000"], options=self._default_options(), expected_logs=expected_logs)
-
- def test_prepare_rollout(self):
- expected_logs = "Preparing rollout for bug 50000.\nUpdating working directory\n"
- self.assert_execute_outputs(PrepareRollout(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
- def test_create_rollout(self):
- expected_logs = """Preparing rollout for bug 50000.
-Updating working directory
-MOCK create_bug
-bug_title: REGRESSION(r852): Reason
-bug_description: http://trac.webkit.org/changeset/852 broke the build:
-Reason
-component: MOCK component
-cc: MOCK cc
-blocked: 50000
-MOCK add_patch_to_bug: bug_id=60001, description=ROLLOUT of r852, mark_for_review=False, mark_for_commit_queue=True, mark_for_landing=False
--- Begin comment --
-Any committer can land this patch automatically by marking it commit-queue+. The commit-queue will build and test the patch before landing to ensure that the rollout will be successful. This process takes approximately 15 minutes.
-
-If you would like to land the rollout faster, you can use the following command:
-
- webkit-patch land-attachment ATTACHMENT_ID
-
-where ATTACHMENT_ID is the ID of this attachment.
--- End comment --
-"""
- self.assert_execute_outputs(CreateRollout(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
- self.assert_execute_outputs(CreateRollout(), ["855 852 854", "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
- def test_create_rollout_resolved(self):
- expected_logs = """Preparing rollout for bug 50004.
-Updating working directory
-MOCK create_bug
-bug_title: REGRESSION(r3001): Reason
-bug_description: http://trac.webkit.org/changeset/3001 broke the build:
-Reason
-component: MOCK component
-cc: MOCK cc
-blocked: 50004
-MOCK reopen_bug 50004 with comment 'Re-opened since this is blocked by bug 60001'
-MOCK add_patch_to_bug: bug_id=60001, description=ROLLOUT of r3001, mark_for_review=False, mark_for_commit_queue=True, mark_for_landing=False
--- Begin comment --
-Any committer can land this patch automatically by marking it commit-queue+. The commit-queue will build and test the patch before landing to ensure that the rollout will be successful. This process takes approximately 15 minutes.
-
-If you would like to land the rollout faster, you can use the following command:
-
- webkit-patch land-attachment ATTACHMENT_ID
-
-where ATTACHMENT_ID is the ID of this attachment.
--- End comment --
-"""
- self.assert_execute_outputs(CreateRollout(), [3001, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
- def test_rollout(self):
- expected_logs = """Preparing rollout for bug 50000.
-Updating working directory
-MOCK: user.open_url: file://...
-Was that diff correct?
-Building WebKit
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-MOCK reopen_bug 50000 with comment 'Reverted r852 for reason:
-
-Reason
-
-Committed r49824: <http://trac.webkit.org/changeset/49824>'
-"""
- self.assert_execute_outputs(Rollout(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
diff --git a/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py b/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py
deleted file mode 100644
index 90501fc..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# Copyright (c) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import logging
-from optparse import make_option
-
-from webkitpy.common.config.committers import CommitterList
-from webkitpy.common.config.ports import DeprecatedPort
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.tool.bot.earlywarningsystemtask import EarlyWarningSystemTask, EarlyWarningSystemTaskDelegate
-from webkitpy.tool.bot.expectedfailures import ExpectedFailures
-from webkitpy.tool.bot.layouttestresultsreader import LayoutTestResultsReader
-from webkitpy.tool.bot.patchanalysistask import UnableToApplyPatch
-from webkitpy.tool.bot.queueengine import QueueEngine
-from webkitpy.tool.commands.queues import AbstractReviewQueue
-
-_log = logging.getLogger(__name__)
-
-
-class AbstractEarlyWarningSystem(AbstractReviewQueue, EarlyWarningSystemTaskDelegate):
- _build_style = "release"
- # FIXME: Switch _default_run_tests from opt-in to opt-out once more bots are ready to run tests.
- _default_run_tests = False
-
- def __init__(self):
- options = [make_option("--run-tests", action="store_true", dest="run_tests", default=self._default_run_tests, help="Run the Layout tests for each patch")]
- AbstractReviewQueue.__init__(self, options=options)
-
- def begin_work_queue(self):
- AbstractReviewQueue.begin_work_queue(self)
- self._expected_failures = ExpectedFailures()
- self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory())
-
- def _failing_tests_message(self, task, patch):
- results = task.results_from_patch_test_run(patch)
- unexpected_failures = self._expected_failures.unexpected_failures_observed(results)
- if not unexpected_failures:
- return None
- return "New failing tests:\n%s" % "\n".join(unexpected_failures)
-
- def _post_reject_message_on_bug(self, tool, patch, status_id, extra_message_text=None):
- results_link = tool.status_server.results_url_for_status(status_id)
- message = "Attachment %s did not pass %s (%s):\nOutput: %s" % (patch.id(), self.name, self.port_name, results_link)
- if extra_message_text:
- message += "\n\n%s" % extra_message_text
- # FIXME: We might want to add some text about rejecting from the commit-queue in
- # the case where patch.commit_queue() isn't already set to '-'.
- if self.watchers:
- tool.bugs.add_cc_to_bug(patch.bug_id(), self.watchers)
- tool.bugs.set_flag_on_attachment(patch.id(), "commit-queue", "-", message)
-
- def review_patch(self, patch):
- task = EarlyWarningSystemTask(self, patch, self._options.run_tests)
- if not task.validate():
- self._did_error(patch, "%s did not process patch." % self.name)
- return False
- try:
- return task.run()
- except UnableToApplyPatch, e:
- self._did_error(patch, "%s unable to apply patch." % self.name)
- return False
- except ScriptError, e:
- self._post_reject_message_on_bug(self._tool, patch, task.failure_status_id, self._failing_tests_message(task, patch))
- results_archive = task.results_archive_from_patch_test_run(patch)
- if results_archive:
- self._upload_results_archive_for_patch(patch, results_archive)
- self._did_fail(patch)
- # FIXME: We're supposed to be able to raise e again here and have
- # one of our base classes mark the patch as fail, but there seems
- # to be an issue with the exit_code.
- return False
-
- # EarlyWarningSystemDelegate methods
-
- def parent_command(self):
- return self.name
-
- def run_command(self, command):
- self.run_webkit_patch(command + [self._deprecated_port.flag()])
-
- def command_passed(self, message, patch):
- pass
-
- def command_failed(self, message, script_error, patch):
- failure_log = self._log_from_script_error_for_upload(script_error)
- return self._update_status(message, patch=patch, results_file=failure_log)
-
- def expected_failures(self):
- return self._expected_failures
-
- def test_results(self):
- return self._layout_test_results_reader.results()
-
- def archive_last_test_results(self, patch):
- return self._layout_test_results_reader.archive(patch)
-
- def build_style(self):
- return self._build_style
-
- def refetch_patch(self, patch):
- return self._tool.bugs.fetch_attachment(patch.id())
-
- def report_flaky_tests(self, patch, flaky_test_results, results_archive):
- pass
-
- # StepSequenceErrorHandler methods
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- # FIXME: Why does this not exit(1) like the superclass does?
- _log.error(script_error.message_with_output())
-
-
-class GtkEWS(AbstractEarlyWarningSystem):
- name = "gtk-ews"
- port_name = "gtk"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "xan.lopez@gmail.com",
- ]
-
-
-class EflEWS(AbstractEarlyWarningSystem):
- name = "efl-ews"
- port_name = "efl"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "leandro@profusion.mobi",
- "antognolli@profusion.mobi",
- "lucas.demarchi@profusion.mobi",
- "gyuyoung.kim@samsung.com",
- ]
-
-
-class QtEWS(AbstractEarlyWarningSystem):
- name = "qt-ews"
- port_name = "qt"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "webkit-ews@sed.inf.u-szeged.hu",
- ]
-
-
-class QtWK2EWS(AbstractEarlyWarningSystem):
- name = "qt-wk2-ews"
- port_name = "qt"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "webkit-ews@sed.inf.u-szeged.hu",
- ]
-
-
-class WinEWS(AbstractEarlyWarningSystem):
- name = "win-ews"
- port_name = "win"
- _default_run_tests = True
-
-class AbstractChromiumEWS(AbstractEarlyWarningSystem):
- port_name = "chromium"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "dglazkov@chromium.org",
- ]
-
-
-class ChromiumLinuxEWS(AbstractChromiumEWS):
- # FIXME: We should rename this command to cr-linux-ews, but that requires
- # a database migration. :(
- name = "chromium-ews"
- port_name = "chromium-xvfb"
- _default_run_tests = True
-
-
-class ChromiumLinuxDebugEWS(AbstractChromiumEWS):
- name = "cr-linux-debug-ews"
- port_name = "chromium-xvfb"
- _build_style = "debug"
-
-
-class ChromiumWindowsEWS(AbstractChromiumEWS):
- name = "cr-win-ews"
-
-
-class ChromiumAndroidEWS(AbstractChromiumEWS):
- name = "cr-android-ews"
- port_name = "chromium-android"
- watchers = AbstractChromiumEWS.watchers + [
- "peter+ews@chromium.org",
- ]
-
-
-class MacEWS(AbstractEarlyWarningSystem):
- name = "mac-ews"
- port_name = "mac"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "rniwa@webkit.org",
- ]
-
-
-class MacWK2EWS(AbstractEarlyWarningSystem):
- name = "mac-wk2-ews"
- port_name = "mac-wk2"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "rniwa@webkit.org",
- ]
diff --git a/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py b/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py
deleted file mode 100644
index 3ab1cd4..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.common.system.outputcapture import OutputCapture
-from webkitpy.tool.bot.queueengine import QueueEngine
-from webkitpy.tool.commands.earlywarningsystem import *
-from webkitpy.tool.commands.queuestest import QueuesTest
-from webkitpy.tool.mocktool import MockTool, MockOptions
-
-
-class AbstractEarlyWarningSystemTest(QueuesTest):
- def test_failing_tests_message(self):
- # Needed to define port_name, used in AbstractEarlyWarningSystem.__init__
- class TestEWS(AbstractEarlyWarningSystem):
- port_name = "chromium" # Needs to be a port which port/factory understands.
-
- ews = TestEWS()
- ews.bind_to_tool(MockTool())
- ews._options = MockOptions(port=None, confirm=False)
- OutputCapture().assert_outputs(self, ews.begin_work_queue, expected_logs=self._default_begin_work_queue_logs(ews.name))
- ews._expected_failures.unexpected_failures_observed = lambda results: set(["foo.html", "bar.html"])
- task = Mock()
- patch = ews._tool.bugs.fetch_attachment(10000)
- self.assertMultiLineEqual(ews._failing_tests_message(task, patch), "New failing tests:\nbar.html\nfoo.html")
-
-
-class EarlyWarningSytemTest(QueuesTest):
- def _default_expected_logs(self, ews):
- string_replacements = {
- "name": ews.name,
- "port": ews.port_name,
- }
- if ews._default_run_tests:
- run_tests_line = "Running: webkit-patch --status-host=example.com build-and-test --no-clean --no-update --test --non-interactive --port=%(port)s\n" % string_replacements
- else:
- run_tests_line = ""
- string_replacements['run_tests_line'] = run_tests_line
-
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs(ews.name),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean --port=%(port)s
-Running: webkit-patch --status-host=example.com update --port=%(port)s
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000 --port=%(port)s
-Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=release --port=%(port)s
-%(run_tests_line)sMOCK: update_status: %(name)s Pass
-MOCK: release_work_item: %(name)s 10000
-""" % string_replacements,
- "handle_unexpected_error": "Mock error message\n",
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- }
- return expected_logs
-
- def _test_ews(self, ews):
- ews.bind_to_tool(MockTool())
- options = Mock()
- options.port = None
- options.run_tests = ews._default_run_tests
- self.assert_queue_outputs(ews, expected_logs=self._default_expected_logs(ews), options=options)
-
- def _test_ewses(self):
- self._test_ews(MacEWS())
- self._test_ews(MacWK2EWS())
- self._test_ews(ChromiumLinuxEWS())
- self._test_ews(ChromiumWindowsEWS())
- self._test_ews(ChromiumAndroidEWS())
- self._test_ews(QtEWS())
- self._test_ews(QtWK2EWS())
- self._test_ews(GtkEWS())
- self._test_ews(EflEWS())
diff --git a/Tools/Scripts/webkitpy/tool/commands/openbugs.py b/Tools/Scripts/webkitpy/tool/commands/openbugs.py
deleted file mode 100644
index 8c55aba..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/openbugs.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (c) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import logging
-import re
-import sys
-
-from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
-
-_log = logging.getLogger(__name__)
-
-
-class OpenBugs(AbstractDeclarativeCommand):
- name = "open-bugs"
- help_text = "Finds all bug numbers passed in arguments (or stdin if no args provided) and opens them in a web browser"
-
- bug_number_regexp = re.compile(r"\b\d{4,6}\b")
-
- def _open_bugs(self, bug_ids):
- for bug_id in bug_ids:
- bug_url = self._tool.bugs.bug_url_for_bug_id(bug_id)
- self._tool.user.open_url(bug_url)
-
- # _find_bugs_in_string mostly exists for easy unit testing.
- def _find_bugs_in_string(self, string):
- return self.bug_number_regexp.findall(string)
-
- def _find_bugs_in_iterable(self, iterable):
- return sum([self._find_bugs_in_string(string) for string in iterable], [])
-
- def execute(self, options, args, tool):
- if args:
- bug_ids = self._find_bugs_in_iterable(args)
- else:
- # This won't open bugs until stdin is closed but could be made to easily. That would just make unit testing slightly harder.
- bug_ids = self._find_bugs_in_iterable(sys.stdin)
-
- _log.info("%s bugs found in input." % len(bug_ids))
-
- self._open_bugs(bug_ids)
diff --git a/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py b/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py
deleted file mode 100644
index 680e514..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.commands.openbugs import OpenBugs
-
-class OpenBugsTest(CommandsTest):
-
- find_bugs_in_string_expectations = [
- ["123", []],
- ["1234", ["1234"]],
- ["12345", ["12345"]],
- ["123456", ["123456"]],
- ["1234567", []],
- [" 123456 234567", ["123456", "234567"]],
- ]
-
- def test_find_bugs_in_string(self):
- openbugs = OpenBugs()
- for expectation in self.find_bugs_in_string_expectations:
- self.assertEqual(openbugs._find_bugs_in_string(expectation[0]), expectation[1])
-
- def test_args_parsing(self):
- expected_logs = "2 bugs found in input.\nMOCK: user.open_url: http://example.com/12345\nMOCK: user.open_url: http://example.com/23456\n"
- self.assert_execute_outputs(OpenBugs(), ["12345\n23456"], expected_logs=expected_logs)
diff --git a/Tools/Scripts/webkitpy/tool/commands/queues.py b/Tools/Scripts/webkitpy/tool/commands/queues.py
deleted file mode 100644
index b9a78a8..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/queues.py
+++ /dev/null
@@ -1,487 +0,0 @@
-# Copyright (c) 2009 Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import codecs
-import logging
-import os
-import sys
-import time
-import traceback
-
-from datetime import datetime
-from optparse import make_option
-from StringIO import StringIO
-
-from webkitpy.common.config.committervalidator import CommitterValidator
-from webkitpy.common.config.ports import DeprecatedPort
-from webkitpy.common.net.bugzilla import Attachment
-from webkitpy.common.net.statusserver import StatusServer
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.tool.bot.botinfo import BotInfo
-from webkitpy.tool.bot.commitqueuetask import CommitQueueTask, CommitQueueTaskDelegate
-from webkitpy.tool.bot.expectedfailures import ExpectedFailures
-from webkitpy.tool.bot.feeders import CommitQueueFeeder, EWSFeeder
-from webkitpy.tool.bot.flakytestreporter import FlakyTestReporter
-from webkitpy.tool.bot.layouttestresultsreader import LayoutTestResultsReader
-from webkitpy.tool.bot.patchanalysistask import UnableToApplyPatch
-from webkitpy.tool.bot.queueengine import QueueEngine, QueueEngineDelegate
-from webkitpy.tool.bot.stylequeuetask import StyleQueueTask, StyleQueueTaskDelegate
-from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler
-from webkitpy.tool.multicommandtool import Command, TryAgain
-
-_log = logging.getLogger(__name__)
-
-
-class AbstractQueue(Command, QueueEngineDelegate):
- watchers = [
- ]
-
- _pass_status = "Pass"
- _fail_status = "Fail"
- _retry_status = "Retry"
- _error_status = "Error"
-
- def __init__(self, options=None): # Default values should never be collections (like []) as default values are shared between invocations
- options_list = (options or []) + [
- make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Do not ask the user for confirmation before running the queue. Dangerous!"),
- make_option("--exit-after-iteration", action="store", type="int", dest="iterations", default=None, help="Stop running the queue after iterating this number of times."),
- ]
- Command.__init__(self, "Run the %s" % self.name, options=options_list)
- self._iteration_count = 0
-
- def _cc_watchers(self, bug_id):
- try:
- self._tool.bugs.add_cc_to_bug(bug_id, self.watchers)
- except Exception, e:
- traceback.print_exc()
- _log.error("Failed to CC watchers.")
-
- def run_webkit_patch(self, args):
- webkit_patch_args = [self._tool.path()]
- # FIXME: This is a hack, we should have a more general way to pass global options.
- # FIXME: We must always pass global options and their value in one argument
- # because our global option code looks for the first argument which does
- # not begin with "-" and assumes that is the command name.
- webkit_patch_args += ["--status-host=%s" % self._tool.status_server.host]
- if self._tool.status_server.bot_id:
- webkit_patch_args += ["--bot-id=%s" % self._tool.status_server.bot_id]
- if self._options.port:
- webkit_patch_args += ["--port=%s" % self._options.port]
- webkit_patch_args.extend(args)
-
- try:
- args_for_printing = list(webkit_patch_args)
- args_for_printing[0] = 'webkit-patch' # Printing our path for each log is redundant.
- _log.info("Running: %s" % self._tool.executive.command_for_printing(args_for_printing))
- command_output = self._tool.executive.run_command(webkit_patch_args, cwd=self._tool.scm().checkout_root)
- except ScriptError, e:
- # Make sure the whole output gets printed if the command failed.
- _log.error(e.message_with_output(output_limit=None))
- raise
- return command_output
-
- def _log_directory(self):
- return os.path.join("..", "%s-logs" % self.name)
-
- # QueueEngineDelegate methods
-
- def queue_log_path(self):
- return os.path.join(self._log_directory(), "%s.log" % self.name)
-
- def work_item_log_path(self, work_item):
- raise NotImplementedError, "subclasses must implement"
-
- def begin_work_queue(self):
- _log.info("CAUTION: %s will discard all local changes in \"%s\"" % (self.name, self._tool.scm().checkout_root))
- if self._options.confirm:
- response = self._tool.user.prompt("Are you sure? Type \"yes\" to continue: ")
- if (response != "yes"):
- _log.error("User declined.")
- sys.exit(1)
- _log.info("Running WebKit %s." % self.name)
- self._tool.status_server.update_status(self.name, "Starting Queue")
-
- def stop_work_queue(self, reason):
- self._tool.status_server.update_status(self.name, "Stopping Queue, reason: %s" % reason)
-
- def should_continue_work_queue(self):
- self._iteration_count += 1
- return not self._options.iterations or self._iteration_count <= self._options.iterations
-
- def next_work_item(self):
- raise NotImplementedError, "subclasses must implement"
-
- def process_work_item(self, work_item):
- raise NotImplementedError, "subclasses must implement"
-
- def handle_unexpected_error(self, work_item, message):
- raise NotImplementedError, "subclasses must implement"
-
- # Command methods
-
- def execute(self, options, args, tool, engine=QueueEngine):
- self._options = options # FIXME: This code is wrong. Command.options is a list, this assumes an Options element!
- self._tool = tool # FIXME: This code is wrong too! Command.bind_to_tool handles this!
- return engine(self.name, self, self._tool.wakeup_event, self._options.seconds_to_sleep).run()
-
- @classmethod
- def _log_from_script_error_for_upload(cls, script_error, output_limit=None):
- # We have seen request timeouts with app engine due to large
- # log uploads. Trying only the last 512k.
- if not output_limit:
- output_limit = 512 * 1024 # 512k
- output = script_error.message_with_output(output_limit=output_limit)
- # We pre-encode the string to a byte array before passing it
- # to status_server, because ClientForm (part of mechanize)
- # wants a file-like object with pre-encoded data.
- return StringIO(output.encode("utf-8"))
-
- @classmethod
- def _update_status_for_script_error(cls, tool, state, script_error, is_error=False):
- message = str(script_error)
- if is_error:
- message = "Error: %s" % message
- failure_log = cls._log_from_script_error_for_upload(script_error)
- return tool.status_server.update_status(cls.name, message, state["patch"], failure_log)
-
-
-class FeederQueue(AbstractQueue):
- name = "feeder-queue"
-
- _sleep_duration = 30 # seconds
-
- # AbstractQueue methods
-
- def begin_work_queue(self):
- AbstractQueue.begin_work_queue(self)
- self.feeders = [
- CommitQueueFeeder(self._tool),
- EWSFeeder(self._tool),
- ]
-
- def next_work_item(self):
- # This really show inherit from some more basic class that doesn't
- # understand work items, but the base class in the heirarchy currently
- # understands work items.
- return "synthetic-work-item"
-
- def process_work_item(self, work_item):
- for feeder in self.feeders:
- feeder.feed()
- time.sleep(self._sleep_duration)
- return True
-
- def work_item_log_path(self, work_item):
- return None
-
- def handle_unexpected_error(self, work_item, message):
- _log.error(message)
-
-
-class AbstractPatchQueue(AbstractQueue):
- def _update_status(self, message, patch=None, results_file=None):
- return self._tool.status_server.update_status(self.name, message, patch, results_file)
-
- def _next_patch(self):
- # FIXME: Bugzilla accessibility should be checked here; if it's unaccessible,
- # it should return None.
- patch = None
- while not patch:
- patch_id = self._tool.status_server.next_work_item(self.name)
- if not patch_id:
- return None
- patch = self._tool.bugs.fetch_attachment(patch_id)
- if not patch:
- # FIXME: Using a fake patch because release_work_item has the wrong API.
- # We also don't really need to release the lock (although that's fine),
- # mostly we just need to remove this bogus patch from our queue.
- # If for some reason bugzilla is just down, then it will be re-fed later.
- fake_patch = Attachment({'id': patch_id}, None)
- self._release_work_item(fake_patch)
- return patch
-
- def _release_work_item(self, patch):
- self._tool.status_server.release_work_item(self.name, patch)
-
- def _did_pass(self, patch):
- self._update_status(self._pass_status, patch)
- self._release_work_item(patch)
-
- def _did_fail(self, patch):
- self._update_status(self._fail_status, patch)
- self._release_work_item(patch)
-
- def _did_retry(self, patch):
- self._update_status(self._retry_status, patch)
- self._release_work_item(patch)
-
- def _did_error(self, patch, reason):
- message = "%s: %s" % (self._error_status, reason)
- self._update_status(message, patch)
- self._release_work_item(patch)
-
- def work_item_log_path(self, patch):
- return os.path.join(self._log_directory(), "%s.log" % patch.bug_id())
-
-
-# Used to share code between the EWS and commit-queue.
-class PatchProcessingQueue(AbstractPatchQueue):
- # Subclasses must override.
- port_name = None
-
- def __init__(self, options=None):
- self._port = None # We can't instantiate port here because tool isn't avaialble.
- AbstractPatchQueue.__init__(self, options)
-
- # FIXME: This is a hack to map between the old port names and the new port names.
- def _new_port_name_from_old(self, port_name, platform):
- # The new port system has no concept of xvfb yet.
- if port_name == 'chromium-xvfb':
- return 'chromium'
- return port_name
-
- def begin_work_queue(self):
- AbstractPatchQueue.begin_work_queue(self)
- if not self.port_name:
- return
- # FIXME: This is only used for self._deprecated_port.flag()
- self._deprecated_port = DeprecatedPort.port(self.port_name)
- # FIXME: This violates abstraction
- self._tool._deprecated_port = self._deprecated_port
- self._port = self._tool.port_factory.get(self._new_port_name_from_old(self.port_name, self._tool.platform))
-
- def _upload_results_archive_for_patch(self, patch, results_archive_zip):
- if not self._port:
- self._port = self._tool.port_factory.get(self._new_port_name_from_old(self.port_name, self._tool.platform))
-
- bot_id = self._tool.status_server.bot_id or "bot"
- description = "Archive of layout-test-results from %s for %s" % (bot_id, self._port.name())
- # results_archive is a ZipFile object, grab the File object (.fp) to pass to Mechanize for uploading.
- results_archive_file = results_archive_zip.fp
- # Rewind the file object to start (since Mechanize won't do that automatically)
- # See https://bugs.webkit.org/show_bug.cgi?id=54593
- results_archive_file.seek(0)
- # FIXME: This is a small lie to always say run-webkit-tests since Chromium uses new-run-webkit-tests.
- # We could make this code look up the test script name off the port.
- comment_text = "The attached test failures were seen while running run-webkit-tests on the %s.\n" % (self.name)
- # FIXME: We could easily list the test failures from the archive here,
- # currently callers do that separately.
- comment_text += BotInfo(self._tool, self._port.name()).summary_text()
- self._tool.bugs.add_attachment_to_bug(patch.bug_id(), results_archive_file, description, filename="layout-test-results.zip", comment_text=comment_text)
-
-
-class CommitQueue(PatchProcessingQueue, StepSequenceErrorHandler, CommitQueueTaskDelegate):
- name = "commit-queue"
- port_name = "chromium-xvfb"
-
- # AbstractPatchQueue methods
-
- def begin_work_queue(self):
- PatchProcessingQueue.begin_work_queue(self)
- self.committer_validator = CommitterValidator(self._tool)
- self._expected_failures = ExpectedFailures()
- self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory())
-
- def next_work_item(self):
- return self._next_patch()
-
- def process_work_item(self, patch):
- self._cc_watchers(patch.bug_id())
- task = CommitQueueTask(self, patch)
- try:
- if task.run():
- self._did_pass(patch)
- return True
- self._did_retry(patch)
- except ScriptError, e:
- validator = CommitterValidator(self._tool)
- validator.reject_patch_from_commit_queue(patch.id(), self._error_message_for_bug(task, patch, e))
- results_archive = task.results_archive_from_patch_test_run(patch)
- if results_archive:
- self._upload_results_archive_for_patch(patch, results_archive)
- self._did_fail(patch)
-
- def _failing_tests_message(self, task, patch):
- results = task.results_from_patch_test_run(patch)
- unexpected_failures = self._expected_failures.unexpected_failures_observed(results)
- if not unexpected_failures:
- return None
- return "New failing tests:\n%s" % "\n".join(unexpected_failures)
-
- def _error_message_for_bug(self, task, patch, script_error):
- message = self._failing_tests_message(task, patch)
- if not message:
- message = script_error.message_with_output()
- results_link = self._tool.status_server.results_url_for_status(task.failure_status_id)
- return "%s\nFull output: %s" % (message, results_link)
-
- def handle_unexpected_error(self, patch, message):
- self.committer_validator.reject_patch_from_commit_queue(patch.id(), message)
-
- # CommitQueueTaskDelegate methods
-
- def run_command(self, command):
- self.run_webkit_patch(command + [self._deprecated_port.flag()])
-
- def command_passed(self, message, patch):
- self._update_status(message, patch=patch)
-
- def command_failed(self, message, script_error, patch):
- failure_log = self._log_from_script_error_for_upload(script_error)
- return self._update_status(message, patch=patch, results_file=failure_log)
-
- def expected_failures(self):
- return self._expected_failures
-
- def test_results(self):
- return self._layout_test_results_reader.results()
-
- def archive_last_test_results(self, patch):
- return self._layout_test_results_reader.archive(patch)
-
- def build_style(self):
- return "release"
-
- def refetch_patch(self, patch):
- return self._tool.bugs.fetch_attachment(patch.id())
-
- def report_flaky_tests(self, patch, flaky_test_results, results_archive=None):
- reporter = FlakyTestReporter(self._tool, self.name)
- reporter.report_flaky_tests(patch, flaky_test_results, results_archive)
-
- def did_pass_testing_ews(self, patch):
- # Currently, chromium-ews is the only testing EWS. Once there are more,
- # should make sure they all pass.
- status = self._tool.status_server.patch_status("chromium-ews", patch.id())
- return status == self._pass_status
-
- # StepSequenceErrorHandler methods
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- # Hitting this error handler should be pretty rare. It does occur,
- # however, when a patch no longer applies to top-of-tree in the final
- # land step.
- _log.error(script_error.message_with_output())
-
- @classmethod
- def handle_checkout_needs_update(cls, tool, state, options, error):
- message = "Tests passed, but commit failed (checkout out of date). Updating, then landing without building or re-running tests."
- tool.status_server.update_status(cls.name, message, state["patch"])
- # The only time when we find out that out checkout needs update is
- # when we were ready to actually pull the trigger and land the patch.
- # Rather than spinning in the master process, we retry without
- # building or testing, which is much faster.
- options.build = False
- options.test = False
- options.update = True
- raise TryAgain()
-
-
-class AbstractReviewQueue(PatchProcessingQueue, StepSequenceErrorHandler):
- """This is the base-class for the EWS queues and the style-queue."""
- def __init__(self, options=None):
- PatchProcessingQueue.__init__(self, options)
-
- def review_patch(self, patch):
- raise NotImplementedError("subclasses must implement")
-
- # AbstractPatchQueue methods
-
- def begin_work_queue(self):
- PatchProcessingQueue.begin_work_queue(self)
-
- def next_work_item(self):
- return self._next_patch()
-
- def process_work_item(self, patch):
- try:
- if not self.review_patch(patch):
- return False
- self._did_pass(patch)
- return True
- except ScriptError, e:
- if e.exit_code != QueueEngine.handled_error_code:
- self._did_fail(patch)
- else:
- # The subprocess handled the error, but won't have released the patch, so we do.
- # FIXME: We need to simplify the rules by which _release_work_item is called.
- self._release_work_item(patch)
- raise e
-
- def handle_unexpected_error(self, patch, message):
- _log.error(message)
-
- # StepSequenceErrorHandler methods
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- _log.error(script_error.output)
-
-
-class StyleQueue(AbstractReviewQueue, StyleQueueTaskDelegate):
- name = "style-queue"
-
- def __init__(self):
- AbstractReviewQueue.__init__(self)
-
- def review_patch(self, patch):
- task = StyleQueueTask(self, patch)
- if not task.validate():
- self._did_error(patch, "%s did not process patch." % self.name)
- return False
- try:
- return task.run()
- except UnableToApplyPatch, e:
- self._did_error(patch, "%s unable to apply patch." % self.name)
- return False
- except ScriptError, e:
- message = "Attachment %s did not pass %s:\n\n%s\n\nIf any of these errors are false positives, please file a bug against check-webkit-style." % (patch.id(), self.name, e.output)
- self._tool.bugs.post_comment_to_bug(patch.bug_id(), message, cc=self.watchers)
- self._did_fail(patch)
- return False
- return True
-
- # StyleQueueTaskDelegate methods
-
- def run_command(self, command):
- self.run_webkit_patch(command)
-
- def command_passed(self, message, patch):
- self._update_status(message, patch=patch)
-
- def command_failed(self, message, script_error, patch):
- failure_log = self._log_from_script_error_for_upload(script_error)
- return self._update_status(message, patch=patch, results_file=failure_log)
-
- def expected_failures(self):
- return None
-
- def refetch_patch(self, patch):
- return self._tool.bugs.fetch_attachment(patch.id())
diff --git a/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py b/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py
deleted file mode 100644
index 929f83e..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py
+++ /dev/null
@@ -1,509 +0,0 @@
-# Copyright (C) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import StringIO
-
-from webkitpy.common.checkout.scm import CheckoutNeedsUpdate
-from webkitpy.common.checkout.scm.scm_mock import MockSCM
-from webkitpy.common.net.bugzilla import Attachment
-from webkitpy.common.system.outputcapture import OutputCapture
-from webkitpy.layout_tests.models import test_results
-from webkitpy.layout_tests.models import test_failures
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.commands.queues import *
-from webkitpy.tool.commands.queuestest import QueuesTest
-from webkitpy.tool.commands.stepsequence import StepSequence
-from webkitpy.common.net.statusserver_mock import MockStatusServer
-from webkitpy.tool.mocktool import MockTool, MockOptions
-
-
-class TestCommitQueue(CommitQueue):
- def __init__(self, tool=None):
- CommitQueue.__init__(self)
- if tool:
- self.bind_to_tool(tool)
- self._options = MockOptions(confirm=False, parent_command="commit-queue", port=None)
-
- def begin_work_queue(self):
- output_capture = OutputCapture()
- output_capture.capture_output()
- CommitQueue.begin_work_queue(self)
- output_capture.restore_output()
-
-
-class TestQueue(AbstractPatchQueue):
- name = "test-queue"
-
-
-class TestReviewQueue(AbstractReviewQueue):
- name = "test-review-queue"
-
-
-class TestFeederQueue(FeederQueue):
- _sleep_duration = 0
-
-
-class AbstractQueueTest(CommandsTest):
- def test_log_directory(self):
- self.assertEqual(TestQueue()._log_directory(), os.path.join("..", "test-queue-logs"))
-
- def _assert_run_webkit_patch(self, run_args, port=None):
- queue = TestQueue()
- tool = MockTool()
- tool.status_server.bot_id = "gort"
- tool.executive = Mock()
- queue.bind_to_tool(tool)
- queue._options = Mock()
- queue._options.port = port
-
- queue.run_webkit_patch(run_args)
- expected_run_args = ["echo", "--status-host=example.com", "--bot-id=gort"]
- if port:
- expected_run_args.append("--port=%s" % port)
- expected_run_args.extend(run_args)
- tool.executive.run_command.assert_called_with(expected_run_args, cwd='/mock-checkout')
-
- def test_run_webkit_patch(self):
- self._assert_run_webkit_patch([1])
- self._assert_run_webkit_patch(["one", 2])
- self._assert_run_webkit_patch([1], port="mockport")
-
- def test_iteration_count(self):
- queue = TestQueue()
- queue._options = Mock()
- queue._options.iterations = 3
- self.assertTrue(queue.should_continue_work_queue())
- self.assertTrue(queue.should_continue_work_queue())
- self.assertTrue(queue.should_continue_work_queue())
- self.assertFalse(queue.should_continue_work_queue())
-
- def test_no_iteration_count(self):
- queue = TestQueue()
- queue._options = Mock()
- self.assertTrue(queue.should_continue_work_queue())
- self.assertTrue(queue.should_continue_work_queue())
- self.assertTrue(queue.should_continue_work_queue())
- self.assertTrue(queue.should_continue_work_queue())
-
- def _assert_log_message(self, script_error, log_message):
- failure_log = AbstractQueue._log_from_script_error_for_upload(script_error, output_limit=10)
- self.assertTrue(failure_log.read(), log_message)
-
- def test_log_from_script_error_for_upload(self):
- self._assert_log_message(ScriptError("test"), "test")
- unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
- utf8_tor = unicode_tor.encode("utf-8")
- self._assert_log_message(ScriptError(unicode_tor), utf8_tor)
- script_error = ScriptError(unicode_tor, output=unicode_tor)
- expected_output = "%s\nLast %s characters of output:\n%s" % (utf8_tor, 10, utf8_tor[-10:])
- self._assert_log_message(script_error, expected_output)
-
-
-class FeederQueueTest(QueuesTest):
- def test_feeder_queue(self):
- queue = TestFeederQueue()
- tool = MockTool(log_executive=True)
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("feeder-queue"),
- "process_work_item": """Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)
-Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)
-MOCK setting flag 'commit-queue' to '-' on attachment '10001' with comment 'Rejecting attachment 10001 from commit-queue.\n\nnon-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy/common/config/committers.py.
-
-- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
-
-- If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
-MOCK: update_work_items: commit-queue [10005, 10000]
-Feeding commit-queue items [10005, 10000]
-Feeding EWS (1 r? patch, 1 new)
-MOCK: submit_to_ews: 10002
-""",
- "handle_unexpected_error": "Mock error message\n",
- }
- self.assert_queue_outputs(queue, tool=tool, expected_logs=expected_logs)
-
-
-class AbstractPatchQueueTest(CommandsTest):
- def test_next_patch(self):
- queue = AbstractPatchQueue()
- tool = MockTool()
- queue.bind_to_tool(tool)
- queue._options = Mock()
- queue._options.port = None
- self.assertIsNone(queue._next_patch())
- tool.status_server = MockStatusServer(work_items=[2, 10000, 10001])
- expected_stdout = "MOCK: fetch_attachment: 2 is not a known attachment id\n" # A mock-only message to prevent us from making mistakes.
- expected_logs = "MOCK: release_work_item: None 2\n"
- patch = OutputCapture().assert_outputs(self, queue._next_patch, expected_stdout=expected_stdout, expected_logs=expected_logs)
- # The patch.id() == 2 is ignored because it doesn't exist.
- self.assertEqual(patch.id(), 10000)
- self.assertEqual(queue._next_patch().id(), 10001)
- self.assertEqual(queue._next_patch(), None) # When the queue is empty
-
-
-class PatchProcessingQueueTest(CommandsTest):
- def test_upload_results_archive_for_patch(self):
- queue = PatchProcessingQueue()
- queue.name = "mock-queue"
- tool = MockTool()
- queue.bind_to_tool(tool)
- queue._options = Mock()
- queue._options.port = None
- patch = queue._tool.bugs.fetch_attachment(10001)
- expected_logs = """MOCK add_attachment_to_bug: bug_id=50000, description=Archive of layout-test-results from bot for chromium-mac-snowleopard filename=layout-test-results.zip mimetype=None
--- Begin comment --
-The attached test failures were seen while running run-webkit-tests on the mock-queue.
-Port: chromium-mac-snowleopard Platform: MockPlatform 1.0
--- End comment --
-"""
- OutputCapture().assert_outputs(self, queue._upload_results_archive_for_patch, [patch, Mock()], expected_logs=expected_logs)
-
-
-class NeedsUpdateSequence(StepSequence):
- def _run(self, tool, options, state):
- raise CheckoutNeedsUpdate([], 1, "", None)
-
-
-class AlwaysCommitQueueTool(object):
- def __init__(self):
- self.status_server = MockStatusServer()
-
- def command_by_name(self, name):
- return CommitQueue
-
-
-class SecondThoughtsCommitQueue(TestCommitQueue):
- def __init__(self, tool=None):
- self._reject_patch = False
- TestCommitQueue.__init__(self, tool)
-
- def run_command(self, command):
- # We want to reject the patch after the first validation,
- # so wait to reject it until after some other command has run.
- self._reject_patch = True
- return CommitQueue.run_command(self, command)
-
- def refetch_patch(self, patch):
- if not self._reject_patch:
- return self._tool.bugs.fetch_attachment(patch.id())
-
- attachment_dictionary = {
- "id": patch.id(),
- "bug_id": patch.bug_id(),
- "name": "Rejected",
- "is_obsolete": True,
- "is_patch": False,
- "review": "-",
- "reviewer_email": "foo@bar.com",
- "commit-queue": "-",
- "committer_email": "foo@bar.com",
- "attacher_email": "Contributer1",
- }
- return Attachment(attachment_dictionary, None)
-
-
-class CommitQueueTest(QueuesTest):
- def _mock_test_result(self, testname):
- return test_results.TestResult(testname, [test_failures.FailureTextMismatch()])
-
- def test_commit_queue(self):
- tool = MockTool()
- tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem.
- tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '')
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("commit-queue"),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean --port=chromium-xvfb
-MOCK: update_status: commit-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update --port=chromium-xvfb
-MOCK: update_status: commit-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000 --port=chromium-xvfb
-MOCK: update_status: commit-queue Applied patch
-Running: webkit-patch --status-host=example.com validate-changelog --non-interactive 10000 --port=chromium-xvfb
-MOCK: update_status: commit-queue ChangeLog validated
-Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=release --port=chromium-xvfb
-MOCK: update_status: commit-queue Built patch
-Running: webkit-patch --status-host=example.com build-and-test --no-clean --no-update --test --non-interactive --port=chromium-xvfb
-MOCK: update_status: commit-queue Passed tests
-Running: webkit-patch --status-host=example.com land-attachment --force-clean --non-interactive --parent-command=commit-queue 10000 --port=chromium-xvfb
-MOCK: update_status: commit-queue Landed patch
-MOCK: update_status: commit-queue Pass
-MOCK: release_work_item: commit-queue 10000
-""",
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nMock error message'\n",
- }
- self.assert_queue_outputs(CommitQueue(), tool=tool, expected_logs=expected_logs)
-
- def test_commit_queue_failure(self):
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("commit-queue"),
- "process_work_item": """MOCK: update_status: commit-queue Cleaned working directory
-MOCK: update_status: commit-queue Updated working directory
-MOCK: update_status: commit-queue Patch does not apply
-MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nMOCK script error
-Full output: http://dummy_url'
-MOCK: update_status: commit-queue Fail
-MOCK: release_work_item: commit-queue 10000
-""",
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nMock error message'\n",
- }
- queue = CommitQueue()
-
- def mock_run_webkit_patch(command):
- if command[0] == 'clean' or command[0] == 'update':
- # We want cleaning to succeed so we can error out on a step
- # that causes the commit-queue to reject the patch.
- return
- raise ScriptError('MOCK script error')
-
- queue.run_webkit_patch = mock_run_webkit_patch
- self.assert_queue_outputs(queue, expected_logs=expected_logs)
-
- def test_commit_queue_failure_with_failing_tests(self):
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("commit-queue"),
- "process_work_item": """MOCK: update_status: commit-queue Cleaned working directory
-MOCK: update_status: commit-queue Updated working directory
-MOCK: update_status: commit-queue Patch does not apply
-MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nNew failing tests:
-mock_test_name.html
-another_test_name.html
-Full output: http://dummy_url'
-MOCK: update_status: commit-queue Fail
-MOCK: release_work_item: commit-queue 10000
-""",
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nMock error message'\n",
- }
- queue = CommitQueue()
-
- def mock_run_webkit_patch(command):
- if command[0] == 'clean' or command[0] == 'update':
- # We want cleaning to succeed so we can error out on a step
- # that causes the commit-queue to reject the patch.
- return
- queue._expected_failures.unexpected_failures_observed = lambda results: ["mock_test_name.html", "another_test_name.html"]
- raise ScriptError('MOCK script error')
-
- queue.run_webkit_patch = mock_run_webkit_patch
- self.assert_queue_outputs(queue, expected_logs=expected_logs)
-
- def test_rollout(self):
- tool = MockTool()
- tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem.
- tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '')
- tool.buildbot.light_tree_on_fire()
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("commit-queue"),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean --port=%(port)s
-MOCK: update_status: commit-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update --port=%(port)s
-MOCK: update_status: commit-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000 --port=%(port)s
-MOCK: update_status: commit-queue Applied patch
-Running: webkit-patch --status-host=example.com validate-changelog --non-interactive 10000 --port=%(port)s
-MOCK: update_status: commit-queue ChangeLog validated
-Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=release --port=%(port)s
-MOCK: update_status: commit-queue Built patch
-Running: webkit-patch --status-host=example.com build-and-test --no-clean --no-update --test --non-interactive --port=%(port)s
-MOCK: update_status: commit-queue Passed tests
-Running: webkit-patch --status-host=example.com land-attachment --force-clean --non-interactive --parent-command=commit-queue 10000 --port=%(port)s
-MOCK: update_status: commit-queue Landed patch
-MOCK: update_status: commit-queue Pass
-MOCK: release_work_item: commit-queue 10000
-""" % {"port": CommitQueue.port_name},
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.\n\nMock error message'\n",
- }
- self.assert_queue_outputs(CommitQueue(), tool=tool, expected_logs=expected_logs)
-
- def test_rollout_lands(self):
- tool = MockTool()
- tool.buildbot.light_tree_on_fire()
- rollout_patch = tool.bugs.fetch_attachment(10005) # _patch6, a rollout patch.
- assert(rollout_patch.is_rollout())
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("commit-queue"),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean --port=%(port)s
-MOCK: update_status: commit-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update --port=%(port)s
-MOCK: update_status: commit-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10005 --port=%(port)s
-MOCK: update_status: commit-queue Applied patch
-Running: webkit-patch --status-host=example.com validate-changelog --non-interactive 10005 --port=%(port)s
-MOCK: update_status: commit-queue ChangeLog validated
-Running: webkit-patch --status-host=example.com land-attachment --force-clean --non-interactive --parent-command=commit-queue 10005 --port=%(port)s
-MOCK: update_status: commit-queue Landed patch
-MOCK: update_status: commit-queue Pass
-MOCK: release_work_item: commit-queue 10005
-""" % {"port": CommitQueue.port_name},
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10005' with comment 'Rejecting attachment 10005 from commit-queue.\n\nMock error message'\n",
- }
- self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_logs=expected_logs)
-
- def test_auto_retry(self):
- queue = CommitQueue()
- options = Mock()
- options.parent_command = "commit-queue"
- tool = AlwaysCommitQueueTool()
- sequence = NeedsUpdateSequence(None)
-
- expected_logs = """Commit failed because the checkout is out of date. Please update and try again.
-MOCK: update_status: commit-queue Tests passed, but commit failed (checkout out of date). Updating, then landing without building or re-running tests.
-"""
- state = {'patch': None}
- OutputCapture().assert_outputs(self, sequence.run_and_handle_errors, [tool, options, state], expected_exception=TryAgain, expected_logs=expected_logs)
-
- self.assertTrue(options.update)
- self.assertFalse(options.build)
- self.assertFalse(options.test)
-
- def test_manual_reject_during_processing(self):
- queue = SecondThoughtsCommitQueue(MockTool())
- queue.begin_work_queue()
- queue._tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem.
- queue._tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '')
- queue._options = Mock()
- queue._options.port = None
- expected_logs = """Running: webkit-patch --status-host=example.com clean --port=chromium-xvfb
-MOCK: update_status: commit-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update --port=chromium-xvfb
-MOCK: update_status: commit-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000 --port=chromium-xvfb
-MOCK: update_status: commit-queue Applied patch
-Running: webkit-patch --status-host=example.com validate-changelog --non-interactive 10000 --port=chromium-xvfb
-MOCK: update_status: commit-queue ChangeLog validated
-Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=release --port=chromium-xvfb
-MOCK: update_status: commit-queue Built patch
-Running: webkit-patch --status-host=example.com build-and-test --no-clean --no-update --test --non-interactive --port=chromium-xvfb
-MOCK: update_status: commit-queue Passed tests
-MOCK: update_status: commit-queue Retry
-MOCK: release_work_item: commit-queue 10000
-"""
- OutputCapture().assert_outputs(self, queue.process_work_item, [QueuesTest.mock_work_item], expected_logs=expected_logs)
-
- def test_report_flaky_tests(self):
- queue = TestCommitQueue(MockTool())
- expected_logs = """MOCK bug comment: bug_id=50002, cc=None
---- Begin comment ---
-The commit-queue just saw foo/bar.html flake (text diff) while processing attachment 10000 on bug 50000.
-Port: MockPort Platform: MockPlatform 1.0
---- End comment ---
-
-MOCK add_attachment_to_bug: bug_id=50002, description=Failure diff from bot filename=failure.diff mimetype=None
-MOCK bug comment: bug_id=50002, cc=None
---- Begin comment ---
-The commit-queue just saw bar/baz.html flake (text diff) while processing attachment 10000 on bug 50000.
-Port: MockPort Platform: MockPlatform 1.0
---- End comment ---
-
-bar/baz-diffs.txt does not exist in results archive, uploading entire archive.
-MOCK add_attachment_to_bug: bug_id=50002, description=Archive of layout-test-results from bot filename=layout-test-results.zip mimetype=None
-MOCK bug comment: bug_id=50000, cc=None
---- Begin comment ---
-The commit-queue encountered the following flaky tests while processing attachment 10000:
-
-foo/bar.html bug 50002 (author: abarth@webkit.org)
-bar/baz.html bug 50002 (author: abarth@webkit.org)
-The commit-queue is continuing to process your patch.
---- End comment ---
-
-"""
- test_names = ["foo/bar.html", "bar/baz.html"]
- test_results = [self._mock_test_result(name) for name in test_names]
-
- class MockZipFile(object):
- def __init__(self):
- self.fp = StringIO()
-
- def read(self, path):
- return ""
-
- def namelist(self):
- # This is intentionally missing one diffs.txt to exercise the "upload the whole zip" codepath.
- return ['foo/bar-diffs.txt']
-
- OutputCapture().assert_outputs(self, queue.report_flaky_tests, [QueuesTest.mock_work_item, test_results, MockZipFile()], expected_logs=expected_logs)
-
- def test_did_pass_testing_ews(self):
- tool = MockTool()
- patch = tool.bugs.fetch_attachment(10000)
- queue = TestCommitQueue(tool)
- self.assertFalse(queue.did_pass_testing_ews(patch))
-
-
-class StyleQueueTest(QueuesTest):
- def test_style_queue_with_style_exception(self):
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("style-queue"),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean
-MOCK: update_status: style-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update
-MOCK: update_status: style-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000
-MOCK: update_status: style-queue Applied patch
-Running: webkit-patch --status-host=example.com apply-watchlist-local 50000
-MOCK: update_status: style-queue Watchlist applied
-Running: webkit-patch --status-host=example.com check-style-local --non-interactive --quiet
-MOCK: update_status: style-queue Style checked
-MOCK: update_status: style-queue Pass
-MOCK: release_work_item: style-queue 10000
-""",
- "handle_unexpected_error": "Mock error message\n",
- "handle_script_error": "MOCK output\n",
- }
- tool = MockTool(executive_throws_when_run=set(['check-style']))
- self.assert_queue_outputs(StyleQueue(), expected_logs=expected_logs, tool=tool)
-
- def test_style_queue_with_watch_list_exception(self):
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs("style-queue"),
- "process_work_item": """Running: webkit-patch --status-host=example.com clean
-MOCK: update_status: style-queue Cleaned working directory
-Running: webkit-patch --status-host=example.com update
-MOCK: update_status: style-queue Updated working directory
-Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000
-MOCK: update_status: style-queue Applied patch
-Running: webkit-patch --status-host=example.com apply-watchlist-local 50000
-Exception for ['echo', '--status-host=example.com', 'apply-watchlist-local', 50000]
-
-MOCK command output
-MOCK: update_status: style-queue Unabled to apply watchlist
-Running: webkit-patch --status-host=example.com check-style-local --non-interactive --quiet
-MOCK: update_status: style-queue Style checked
-MOCK: update_status: style-queue Pass
-MOCK: release_work_item: style-queue 10000
-""",
- "handle_unexpected_error": "Mock error message\n",
- "handle_script_error": "MOCK output\n",
- }
- tool = MockTool(executive_throws_when_run=set(['apply-watchlist-local']))
- self.assert_queue_outputs(StyleQueue(), expected_logs=expected_logs, tool=tool)
diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
index c6c4d2a..a2f3b03 100644
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -196,6 +196,7 @@
else:
results_url = self._results_url(options.builder)
self._baseline_suffix_list = options.suffixes.split(',')
+
for suffix in self._baseline_suffix_list:
self._rebaseline_test(options.builder, options.test, options.move_overwritten_baselines_to, suffix, results_url)
self._scm_changes['remove-lines'].append({'builder': options.builder, 'test': options.test})
@@ -306,24 +307,26 @@
builders_to_fallback_paths[builder] = fallback_path
return builders_to_fallback_paths.keys()
- def _rebaseline_commands(self, test_list, options):
-
+ def _rebaseline_commands(self, test_prefix_list, options):
path_to_webkit_patch = self._tool.path()
cwd = self._tool.scm().checkout_root
commands = []
- for test in test_list:
- for builder in self._builders_to_fetch_from(test_list[test]):
- suffixes = ','.join(test_list[test][builder])
- cmd_line = [path_to_webkit_patch, 'rebaseline-test-internal', '--suffixes', suffixes, '--builder', builder, '--test', test]
- if options.move_overwritten_baselines:
- move_overwritten_baselines_to = builders.move_overwritten_baselines_to(builder)
- for platform in move_overwritten_baselines_to:
- cmd_line.extend(['--move-overwritten-baselines-to', platform])
- if options.results_directory:
- cmd_line.extend(['--results-directory', options.results_directory])
- if options.verbose:
- cmd_line.append('--verbose')
- commands.append(tuple([cmd_line, cwd]))
+ port = self._tool.port_factory.get()
+
+ for test_prefix in test_prefix_list:
+ for test in port.tests([test_prefix]):
+ for builder in self._builders_to_fetch_from(test_prefix_list[test_prefix]):
+ suffixes = ','.join(test_prefix_list[test_prefix][builder])
+ cmd_line = [path_to_webkit_patch, 'rebaseline-test-internal', '--suffixes', suffixes, '--builder', builder, '--test', test]
+ if options.move_overwritten_baselines:
+ move_overwritten_baselines_to = builders.move_overwritten_baselines_to(builder)
+ for platform in move_overwritten_baselines_to:
+ cmd_line.extend(['--move-overwritten-baselines-to', platform])
+ if options.results_directory:
+ cmd_line.extend(['--results-directory', options.results_directory])
+ if options.verbose:
+ cmd_line.append('--verbose')
+ commands.append(tuple([cmd_line, cwd]))
return commands
def _files_to_add(self, command_results):
@@ -353,12 +356,12 @@
return list(files_to_add), lines_to_remove
- def _optimize_baselines(self, test_list, verbose=False):
+ def _optimize_baselines(self, test_prefix_list, verbose=False):
# We don't run this in parallel because modifying the SCM in parallel is unreliable.
- for test in test_list:
+ for test in test_prefix_list:
all_suffixes = set()
- for builder in self._builders_to_fetch_from(test_list[test]):
- all_suffixes.update(test_list[test][builder])
+ for builder in self._builders_to_fetch_from(test_prefix_list[test]):
+ all_suffixes.update(test_prefix_list[test][builder])
# FIXME: We should propagate the platform options as well.
self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(all_suffixes), test], verbose)
@@ -373,13 +376,13 @@
expectationsString = expectations.remove_configuration_from_test(test, test_configuration)
self._tool.filesystem.write_text_file(path, expectationsString)
- def _rebaseline(self, options, test_list):
- for test, builders_to_check in sorted(test_list.items()):
+ def _rebaseline(self, options, test_prefix_list):
+ for test, builders_to_check in sorted(test_prefix_list.items()):
_log.info("Rebaselining %s" % test)
for builder, suffixes in sorted(builders_to_check.items()):
_log.debug(" %s: %s" % (builder, ",".join(suffixes)))
- commands = self._rebaseline_commands(test_list, options)
+ commands = self._rebaseline_commands(test_prefix_list, options)
command_results = self._tool.executive.run_in_parallel(commands)
log_output = '\n'.join(result[2] for result in command_results).replace('\n\n', '\n')
for line in log_output.split('\n'):
@@ -392,7 +395,7 @@
self._update_expectations_files(lines_to_remove)
if options.optimize:
- self._optimize_baselines(test_list, options.verbose)
+ self._optimize_baselines(test_prefix_list, options.verbose)
class RebaselineJson(AbstractParallelRebaselineCommand):
@@ -419,7 +422,7 @@
self.move_overwritten_baselines_option,
self.no_optimize_option,
] + self.platform_options)
- self._test_list = None
+ self._test_prefix_list = None
def _tests_to_rebaseline(self, port):
tests_to_rebaseline = {}
@@ -439,21 +442,21 @@
for test_name, suffixes in tests:
_log.info(" %s (%s)" % (test_name, ','.join(suffixes)))
- if test_name not in self._test_list:
- self._test_list[test_name] = {}
- self._test_list[test_name][builder_name] = suffixes
+ if test_name not in self._test_prefix_list:
+ self._test_prefix_list[test_name] = {}
+ self._test_prefix_list[test_name][builder_name] = suffixes
def execute(self, options, args, tool):
options.results_directory = None
- self._test_list = {}
+ self._test_prefix_list = {}
port_names = tool.port_factory.all_port_names(options.platform)
for port_name in port_names:
self._add_tests_to_rebaseline_for_port(port_name)
- if not self._test_list:
+ if not self._test_prefix_list:
_log.warning("Did not find any tests marked Rebaseline.")
return
- self._rebaseline(options, self._test_list)
+ self._rebaseline(options, self._test_prefix_list)
class Rebaseline(AbstractParallelRebaselineCommand):
@@ -493,17 +496,17 @@
else:
builders_to_check = self._builders_to_pull_from()
- test_list = {}
+ test_prefix_list = {}
suffixes_to_update = options.suffixes.split(",")
for builder in builders_to_check:
tests = args or self._tests_to_update(builder)
for test in tests:
- if test not in test_list:
- test_list[test] = {}
- test_list[test][builder.name()] = suffixes_to_update
+ if test not in test_prefix_list:
+ test_prefix_list[test] = {}
+ test_prefix_list[test][builder.name()] = suffixes_to_update
if options.verbose:
- _log.debug("rebaseline-json: " + str(test_list))
+ _log.debug("rebaseline-json: " + str(test_prefix_list))
- self._rebaseline(options, test_list)
+ self._rebaseline(options, test_prefix_list)
diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
index c982731..b64746a 100644
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
@@ -112,15 +112,18 @@
self.assertItemsEqual(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
def test_rebaseline_test_with_results_directory(self):
+ self._write("userscripts/another-test.html", "test data")
self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
self.options.results_directory = '/tmp'
self.command._rebaseline_test_and_update_expectations(self.options)
self.assertItemsEqual(self.tool.web.urls_fetched, ['file:///tmp/userscripts/another-test-actual.txt'])
def test_rebaseline_reftest(self):
+ self._write("userscripts/another-test.html", "test data")
self._write("userscripts/another-test-expected.html", "generic result")
OutputCapture().assert_outputs(self, self.command._rebaseline_test_and_update_expectations, args=[self.options],
expected_logs="Cannot rebaseline reftest: userscripts/another-test.html\n")
+ self.assertDictEqual(self.command._scm_changes, {'add': [], 'remove-lines': []})
def test_rebaseline_test_and_print_scm_changes(self):
self.command._print_scm_changes = True
@@ -306,6 +309,7 @@
def test_rebaseline_all(self):
options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None)
+ self._write("user-scripts/another-test.html", "Dummy test contents")
self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
# Note that we have one run_in_parallel() call followed by a run_command()
@@ -315,6 +319,7 @@
def test_rebaseline_debug(self):
options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None)
+ self._write("user-scripts/another-test.html", "Dummy test contents")
self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
# Note that we have one run_in_parallel() call followed by a run_command()
@@ -324,6 +329,7 @@
def test_move_overwritten(self):
options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=True, results_directory=None)
+ self._write("user-scripts/another-test.html", "Dummy test contents")
self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
# Note that we have one run_in_parallel() call followed by a run_command()
@@ -333,6 +339,7 @@
def test_no_optimize(self):
options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory=None)
+ self._write("user-scripts/another-test.html", "Dummy test contents")
self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
# Note that we have only one run_in_parallel() call
@@ -341,6 +348,7 @@
def test_results_directory(self):
options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory='/tmp')
+ self._write("user-scripts/another-test.html", "Dummy test contents")
self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
# Note that we have only one run_in_parallel() call
@@ -401,24 +409,44 @@
self.command._builders_to_pull_from = lambda: [MockBuilder('MOCK builder')]
self.command._tests_to_update = lambda builder: ['mock/path/to/test.html']
+ self._write("mock/path/to/test.html", "Dummy test contents")
+
self._zero_out_test_expectations()
old_exact_matches = builders._exact_matches
- oc = OutputCapture()
try:
builders._exact_matches = {
"MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
}
- oc.capture_output()
self.command.execute(MockOptions(optimize=False, builders=None, suffixes="txt,png", verbose=True, move_overwritten_baselines=False), [], self.tool)
finally:
- oc.restore_output()
builders._exact_matches = old_exact_matches
calls = filter(lambda x: x != ['qmake', '-v'] and x[0] != 'perl', self.tool.executive.calls)
self.assertEqual(calls,
[[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'mock/path/to/test.html', '--verbose']]])
+ def test_rebaseline_directory(self):
+ self.command._builders_to_pull_from = lambda: [MockBuilder('MOCK builder')]
+ self.command._tests_to_update = lambda builder: ['userscripts']
+
+ self._write("userscripts/first-test.html", "test data")
+ self._write("userscripts/second-test.html", "test data")
+
+ old_exact_matches = builders._exact_matches
+ try:
+ builders._exact_matches = {
+ "MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
+ }
+ self.command.execute(MockOptions(optimize=False, builders=None, suffixes="txt,png", verbose=True, move_overwritten_baselines=False), [], self.tool)
+ finally:
+ builders._exact_matches = old_exact_matches
+
+ calls = filter(lambda x: x != ['qmake', '-v'] and x[0] != 'perl', self.tool.executive.calls)
+ self.assertEqual(calls,
+ [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'userscripts/first-test.html', '--verbose'],
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'userscripts/second-test.html', '--verbose']]])
+
class TestRebaselineExpectations(_BaseTestCase):
command_constructor = RebaselineExpectations
@@ -433,6 +461,8 @@
self.tool.executive = MockExecutive2()
+ self._write("userscripts/another-test.html", "Dummy test contents")
+ self._write("userscripts/images.svg", "Dummy test contents")
self.command._tests_to_rebaseline = lambda port: {'userscripts/another-test.html': set(['txt']), 'userscripts/images.svg': set(['png'])}
self.command.execute(self.options, [], self.tool)
diff --git a/Tools/Scripts/webkitpy/tool/commands/roll.py b/Tools/Scripts/webkitpy/tool/commands/roll.py
deleted file mode 100644
index 8237319..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/roll.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (c) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
-
-from webkitpy.tool import steps
-
-
-default_changelog_message = "Unreviewed. Rolled DEPS.\n\n"
-
-class RollChromiumDEPS(AbstractSequencedCommand):
- name = "roll-chromium-deps"
- help_text = "Updates Chromium DEPS (LKGR as the revision will use the last-known good revision of Chromium)"
- argument_names = "CHROMIUM_REVISION"
- steps = [
- steps.UpdateChromiumDEPS,
- steps.PrepareChangeLogForDEPSRoll,
- steps.ConfirmDiff,
- steps.Commit,
- ]
-
- def _prepare_state(self, options, args, tool):
- return {
- "chromium_revision": (args and args[0]),
- "changelog_message": default_changelog_message,
- }
-
-
-class PostChromiumDEPSRoll(AbstractSequencedCommand):
- name = "post-chromium-deps-roll"
- help_text = "Posts a patch to update Chromium DEPS (LKGR as the revision will use the last-known good revision of Chromium)"
- argument_names = "CHROMIUM_REVISION CHROMIUM_REVISION_NAME [CHANGELOG_MESSAGE]"
- steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.UpdateChromiumDEPS,
- steps.PrepareChangeLogForDEPSRoll,
- steps.CreateBug,
- steps.PostDiff,
- ]
-
- def _prepare_state(self, options, args, tool):
- options.review = False
- options.request_commit = True
-
- chromium_revision = args[0]
- chromium_revision_name = args[1]
- changelog_message = args[2] if len(args) >= 3 else default_changelog_message
- return {
- "chromium_revision": chromium_revision,
- "changelog_message": changelog_message,
- "bug_title": "Roll Chromium DEPS to %s" % chromium_revision_name,
- "bug_description": "A DEPS roll a day keeps the build break away.",
- }
diff --git a/Tools/Scripts/webkitpy/tool/commands/roll_unittest.py b/Tools/Scripts/webkitpy/tool/commands/roll_unittest.py
deleted file mode 100644
index 9e805dd..0000000
--- a/Tools/Scripts/webkitpy/tool/commands/roll_unittest.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.commands.roll import *
-from webkitpy.tool.mocktool import MockOptions, MockTool
-
-
-class RollCommandsTest(CommandsTest):
- def test_update_chromium_deps(self):
- expected_logs = """Updating Chromium DEPS to 6764
-MOCK: MockDEPS.write_variable(chromium_rev, 6764)
-MOCK: user.open_url: file://...
-Was that diff correct?
-Committed r49824: <http://trac.webkit.org/changeset/49824>
-"""
- options = MockOptions(non_interactive=False)
- self.assert_execute_outputs(RollChromiumDEPS(), [6764], options=options, expected_logs=expected_logs)
-
- def test_update_chromium_deps_older_revision(self):
- options = MockOptions(non_interactive=False)
- expected_logs = """Current Chromium DEPS revision 6564 is newer than 5764.
-Unable to update Chromium DEPS.
-"""
- self.assert_execute_outputs(RollChromiumDEPS(), [5764], options=options, expected_logs=expected_logs, expected_exception=SystemExit)
-
-
-class PostRollCommandsTest(CommandsTest):
- def test_prepare_state(self):
- postroll = PostChromiumDEPSRoll()
- options = MockOptions()
- tool = MockTool()
- lkgr_state = postroll._prepare_state(options, [None, "last-known good revision"], tool)
- self.assertIsNone(lkgr_state["chromium_revision"])
- self.assertEqual("Roll Chromium DEPS to last-known good revision", lkgr_state["bug_title"])
- self.assertEqual("Unreviewed. Rolled DEPS.\n\n", lkgr_state["changelog_message"])
- revision_state = postroll._prepare_state(options, ["1234", "r1234", "test message"], tool)
- self.assertEqual("1234", revision_state["chromium_revision"])
- self.assertEqual("Roll Chromium DEPS to r1234", revision_state["bug_title"])
- self.assertEqual("test message", revision_state["changelog_message"])
diff --git a/Tools/Scripts/webkitpy/tool/steps/__init__.py b/Tools/Scripts/webkitpy/tool/steps/__init__.py
index 709de5b..96ac98f 100644
--- a/Tools/Scripts/webkitpy/tool/steps/__init__.py
+++ b/Tools/Scripts/webkitpy/tool/steps/__init__.py
@@ -50,7 +50,6 @@
from webkitpy.tool.steps.options import Options
from webkitpy.tool.steps.postdiff import PostDiff
from webkitpy.tool.steps.postdiffforcommit import PostDiffForCommit
-from webkitpy.tool.steps.postdiffforrevert import PostDiffForRevert
from webkitpy.tool.steps.preparechangelog import PrepareChangeLog
from webkitpy.tool.steps.preparechangelogfordepsroll import PrepareChangeLogForDEPSRoll
from webkitpy.tool.steps.preparechangelogforrevert import PrepareChangeLogForRevert
diff --git a/Tools/Scripts/webkitpy/tool/steps/postdiffforrevert.py b/Tools/Scripts/webkitpy/tool/steps/postdiffforrevert.py
deleted file mode 100644
index 2900eb3..0000000
--- a/Tools/Scripts/webkitpy/tool/steps/postdiffforrevert.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.common.net.bugzilla import Attachment
-from webkitpy.tool.steps.abstractstep import AbstractStep
-
-
-class PostDiffForRevert(AbstractStep):
- def run(self, state):
- comment_text = "Any committer can land this patch automatically by \
-marking it commit-queue+. The commit-queue will build and test \
-the patch before landing to ensure that the rollout will be \
-successful. This process takes approximately 15 minutes.\n\n\
-If you would like to land the rollout faster, you can use the \
-following command:\n\n\
- webkit-patch land-attachment ATTACHMENT_ID\n\n\
-where ATTACHMENT_ID is the ID of this attachment."
- self._tool.bugs.add_patch_to_bug(
- state["bug_id"],
- self.cached_lookup(state, "diff"),
- "%s%s" % (Attachment.rollout_preamble, state["revision"]),
- comment_text=comment_text,
- mark_for_review=False,
- mark_for_commit_queue=True)
diff --git a/Tools/TestResultServer/app.yaml b/Tools/TestResultServer/app.yaml
index 1026be1..e5a2b31 100644
--- a/Tools/TestResultServer/app.yaml
+++ b/Tools/TestResultServer/app.yaml
@@ -1,8 +1,7 @@
application: test-results
version: 1
-runtime: python27
+runtime: python
api_version: 1
-threadsafe: true
handlers:
- url: /stylesheets
@@ -12,8 +11,8 @@
static_dir: static-dashboards
- url: /testfile/delete
- script: main.app
+ script: main.py
login: admin
- url: /.*
- script: main.app
+ script: main.py
diff --git a/Tools/TestResultServer/handlers/menu.py b/Tools/TestResultServer/handlers/menu.py
index 7b5403a..f15e53c 100644
--- a/Tools/TestResultServer/handlers/menu.py
+++ b/Tools/TestResultServer/handlers/menu.py
@@ -26,9 +26,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import webapp2
-
from google.appengine.api import users
+from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
dashboards = [
@@ -45,7 +44,7 @@
]
-class Menu(webapp2.RequestHandler):
+class Menu(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
diff --git a/Tools/TestResultServer/handlers/testfilehandler.py b/Tools/TestResultServer/handlers/testfilehandler.py
index 759d7d6..fd17202 100644
--- a/Tools/TestResultServer/handlers/testfilehandler.py
+++ b/Tools/TestResultServer/handlers/testfilehandler.py
@@ -30,9 +30,9 @@
import logging
import re
import urllib
-import webapp2
from google.appengine.api import users
+from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext import db
@@ -60,7 +60,7 @@
return json
-class DeleteFile(webapp2.RequestHandler):
+class DeleteFile(webapp.RequestHandler):
"""Delete test file for a given builder and name from datastore."""
def get(self):
@@ -81,7 +81,7 @@
% (master, builder, test_type, name))
-class GetFile(webapp2.RequestHandler):
+class GetFile(webapp.RequestHandler):
"""Get file content or list of files for given builder and name."""
def _get_file_list(self, master, builder, test_type, name, callback_name=None):
@@ -210,7 +210,7 @@
self._serve_json(json, date)
-class Upload(webapp2.RequestHandler):
+class Upload(webapp.RequestHandler):
"""Upload test results file to datastore."""
def post(self):
@@ -268,7 +268,7 @@
self.response.out.write("OK")
-class UploadForm(webapp2.RequestHandler):
+class UploadForm(webapp.RequestHandler):
"""Show a form so user can upload a file."""
def get(self):
diff --git a/Tools/TestResultServer/main.py b/Tools/TestResultServer/main.py
index 3bab073..2fa61e5 100644
--- a/Tools/TestResultServer/main.py
+++ b/Tools/TestResultServer/main.py
@@ -26,7 +26,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import webapp2
+# Request a modern Django
+from google.appengine.dist import use_library
+use_library('django', '1.1')
+
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp.util import run_wsgi_app
from handlers import menu
from handlers import testfilehandler
@@ -39,4 +44,11 @@
('/*|/menu', menu.Menu),
]
-app = webapp2.WSGIApplication(routes, debug=True)
+application = webapp.WSGIApplication(routes, debug=True)
+
+
+def main():
+ run_wsgi_app(application)
+
+if __name__ == "__main__":
+ main()
diff --git a/Tools/TestResultServer/model/datastorefile.py b/Tools/TestResultServer/model/datastorefile.py
index bfa4c3c..ac28d64 100755
--- a/Tools/TestResultServer/model/datastorefile.py
+++ b/Tools/TestResultServer/model/datastorefile.py
@@ -26,6 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from datetime import datetime
import logging
from google.appengine.ext import db
diff --git a/Tools/TestResultServer/model/jsonresults.py b/Tools/TestResultServer/model/jsonresults.py
index 9da9d32..16316f3 100755
--- a/Tools/TestResultServer/model/jsonresults.py
+++ b/Tools/TestResultServer/model/jsonresults.py
@@ -26,7 +26,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import json
+from datetime import datetime
+from django.utils import simplejson
import logging
import sys
import traceback
@@ -106,8 +107,8 @@
return data
@classmethod
- def _generate_file_data(cls, data, sort_keys=False):
- return json.dumps(data, separators=(',', ':'), sort_keys=sort_keys)
+ def _generate_file_data(cls, json, sort_keys=False):
+ return simplejson.dumps(json, separators=(',', ':'), sort_keys=sort_keys)
@classmethod
def _load_json(cls, file_data):
@@ -117,7 +118,7 @@
return None
try:
- return json.loads(json_results_str)
+ return simplejson.loads(json_results_str)
except:
logging.debug(json_results_str)
logging.error("Failed to load json results: %s", traceback.print_exception(*sys.exc_info()))
diff --git a/Tools/TestResultServer/model/jsonresults_unittest.py b/Tools/TestResultServer/model/jsonresults_unittest.py
index 969f9b4..0e65d0b 100755
--- a/Tools/TestResultServer/model/jsonresults_unittest.py
+++ b/Tools/TestResultServer/model/jsonresults_unittest.py
@@ -33,7 +33,8 @@
print "ERROR: Add the TestResultServer, google_appengine and yaml/lib directories to your PYTHONPATH"
raise
-import json
+from django.utils import simplejson
+
import unittest
@@ -80,9 +81,9 @@
self._builder = "Webkit"
def test_strip_prefix_suffix(self):
- json_string = "['contents']"
- self.assertEqual(JsonResults._strip_prefix_suffix("ADD_RESULTS(" + json_string + ");"), json_string)
- self.assertEqual(JsonResults._strip_prefix_suffix(json_string), json_string)
+ json = "['contents']"
+ self.assertEqual(JsonResults._strip_prefix_suffix("ADD_RESULTS(" + json + ");"), json)
+ self.assertEqual(JsonResults._strip_prefix_suffix(json), json)
def _make_test_json(self, test_data):
if not test_data:
@@ -93,7 +94,7 @@
if not builds or not tests:
return ""
- json_string = JSON_RESULTS_TEMPLATE
+ json = JSON_RESULTS_TEMPLATE
counts = []
build_numbers = []
@@ -107,17 +108,17 @@
chrome_revision.append("3000%s" % build)
times.append("100000%s000" % build)
- json_string = json_string.replace("[TESTDATA_COUNTS]", ",".join(counts))
- json_string = json_string.replace("[TESTDATA_COUNT]", ",".join(builds))
- json_string = json_string.replace("[TESTDATA_BUILDNUMBERS]", ",".join(build_numbers))
- json_string = json_string.replace("[TESTDATA_WEBKITREVISION]", ",".join(webkit_revision))
- json_string = json_string.replace("[TESTDATA_CHROMEREVISION]", ",".join(chrome_revision))
- json_string = json_string.replace("[TESTDATA_TIMES]", ",".join(times))
+ json = json.replace("[TESTDATA_COUNTS]", ",".join(counts))
+ json = json.replace("[TESTDATA_COUNT]", ",".join(builds))
+ json = json.replace("[TESTDATA_BUILDNUMBERS]", ",".join(build_numbers))
+ json = json.replace("[TESTDATA_WEBKITREVISION]", ",".join(webkit_revision))
+ json = json.replace("[TESTDATA_CHROMEREVISION]", ",".join(chrome_revision))
+ json = json.replace("[TESTDATA_TIMES]", ",".join(times))
version = str(test_data["version"]) if "version" in test_data else "4"
- json_string = json_string.replace("[VERSION]", version)
- json_string = json_string.replace("{[TESTDATA_TESTS]}", json.dumps(tests, separators=(',', ':'), sort_keys=True))
- return json_string
+ json = json.replace("[VERSION]", version)
+ json = json.replace("{[TESTDATA_TESTS]}", simplejson.dumps(tests, separators=(',', ':'), sort_keys=True))
+ return json
def _test_merge(self, aggregated_data, incremental_data, expected_data, max_builds=jsonresults.JSON_RESULTS_MAX_BUILDS):
aggregated_results = self._make_test_json(aggregated_data)
@@ -132,7 +133,7 @@
def _test_get_test_list(self, input_data, expected_data):
input_results = self._make_test_json(input_data)
- expected_results = JSON_RESULTS_TEST_LIST_TEMPLATE.replace("{[TESTDATA_TESTS]}", json.dumps(expected_data, separators=(',', ':')))
+ expected_results = JSON_RESULTS_TEST_LIST_TEMPLATE.replace("{[TESTDATA_TESTS]}", simplejson.dumps(expected_data, separators=(',', ':')))
actual_results = JsonResults.get_test_list(self._builder, input_results)
self.assertEqual(actual_results, expected_results)