});
};
-// jQuery makes jsonp requests somewhat ugly (which is fair given that they're
-// terrible for security). We use this wrapper to make our lives slightly easier.
-net.jsonp = function(url, onsuccess)
+// We use XMLHttpRequest and CORS to fetch JSONP rather than using script tags.
+// That's better for security and performance, but we need the server to cooperate
+// by setting CORS headers.
+net.jsonp = function(url, callback)
{
$.ajax({
url: url,
- dataType: 'jsonp',
- success: onsuccess
+ success: function(jsonp) {
+ callback(base.parseJSONP(jsonp));
+ },
+ error: function() {
+ callback({});
+ },
});
};
(function() {
-var kTestResultsServer = 'http://test-results.appspot.com/';
-var kTestResultsQuery = kTestResultsServer + 'testfile?'
-var kTestType = 'layout-tests';
-var kMasterName = 'ChromiumWebkit';
-
var kLayoutTestResultsServer = 'http://build.chromium.org/f/chromium/layout_test_results/';
var kLayoutTestResultsPath = '/results/layout-test-results/';
var kResultsName = 'full_results.json';
+var kBuildLinkRegexp = /a href="\d+\/"/g;
+var kBuildNumberRegexp = /\d+/;
+
var PASS = 'PASS';
var TIMEOUT = 'TIMEOUT';
var TEXT = 'TEXT';
return result === PASS;
}
-function resultsParameters(builderName, testName)
-{
- return {
- builder: builderName,
- master: kMasterName,
- testtype: kTestType,
- name: testName,
- };
-}
-
function possibleSuffixListFor(failureTypeList)
{
var suffixList = [];
});
};
-function resultsSummaryURL(builderName, resultsName)
+results.directoryForBuilder = function(builderName)
+{
+ return builderName.replace(/[ .()]/g, '_');
+}
+
+function resultsDirectoryURL(builderName)
+{
+ return kLayoutTestResultsServer + results.directoryForBuilder(builderName) + kLayoutTestResultsPath;
+}
+
+function resultsDirectoryListingURL(builderName)
+{
+ return kLayoutTestResultsServer + results.directoryForBuilder(builderName) + '/';
+}
+
+function resultsDirectoryURLForBuildNumber(builderName, buildNumber)
{
- return resultsDirectoryURL(builderName) + resultsName;
+ return resultsDirectoryListingURL(builderName) + buildNumber + '/'
}
-function directoryOfResultsSummaryURL(builderName, testName)
+function resultsSummaryURL(builderName)
{
- var parameters = resultsParameters(builderName, testName);
- parameters['dir'] = 1;
- return kTestResultsQuery + $.param(parameters);
+ return resultsDirectoryURL(builderName) + kResultsName;
}
-var g_resultsCache = new base.AsynchronousCache(function(key, callback) {
- net.jsonp(kTestResultsServer + 'testfile?key=' + key, callback);
+function resultsSummaryURLForBuildNumber(builderName, buildNumber)
+{
+ return resultsDirectoryURLForBuildNumber(builderName, buildNumber) + kResultsName;
+}
+
+var g_resultsCache = new base.AsynchronousCache(function (key, callback) {
+ net.jsonp(key, callback);
});
function anyIsFailure(resultsList)
return base.uniquifyArray(collectedResults);
};
+function historicalResultsSummaryURLs(builderName, callback)
+{
+ net.get(resultsDirectoryListingURL(builderName), function(directoryListing) {
+ var summaryURLs = directoryListing.match(kBuildLinkRegexp).map(function(buildLink) {
+ var buildNumber = parseInt(buildLink.match(kBuildNumberRegexp)[0]);
+ return resultsSummaryURLForBuildNumber(builderName, buildNumber);
+ }).reverse();
+ callback(summaryURLs);
+ });
+}
+
function walkHistory(builderName, testName, callback)
{
var indexOfNextKeyToFetch = 0;
continueWalk();
}
- net.jsonp(directoryOfResultsSummaryURL(builderName, kResultsName), function(directory) {
- keyList = directory.map(function (element) { return element.key; });
+ historicalResultsSummaryURLs(builderName, function(summaryURLs) {
+ keyList = summaryURLs;
continueWalk();
});
}
return currentNode;
};
-results.directoryForBuilder = function(builderName)
-{
- return builderName.replace(/[ .()]/g, '_');
-}
-
-function resultsDirectoryURL(builderName)
-{
- return kLayoutTestResultsServer + results.directoryForBuilder(builderName) + kLayoutTestResultsPath;
-}
-
results.resultKind = function(url)
{
if (/-actual\.[a-z]+$/.test(url))
results.fetchResultsForBuilder = function(builderName, callback)
{
- net.get(resultsSummaryURL(builderName, kResultsName), function(jsonp) {
- callback(base.parseJSONP(jsonp));
- });
+ net.jsonp(resultsSummaryURL(builderName), callback);
};
results.fetchResultsByBuilder = function(builderNameList, callback)
var simulator = new NetworkSimulator();
var keyMap = {
- "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGLncUAw": {
- "tests": {
- "userscripts": {
- "another-test.html": {
- "expected": "PASS",
- "actual": "TEXT"
- }
+ "Mock_Builder": {
+ "11108": {
+ "tests": {
+ "userscripts": {
+ "another-test.html": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ }
+ },
},
+ "revision": "90430"
},
- "revision": "90430"
- },
- "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGNfTUAw":{
- "tests": {
- "userscripts": {
- "user-script-video-document.html": {
- "expected": "FAIL",
- "actual": "TEXT"
+ "11107":{
+ "tests": {
+ "userscripts": {
+ "user-script-video-document.html": {
+ "expected": "FAIL",
+ "actual": "TEXT"
+ },
+ "another-test.html": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ }
},
- "another-test.html": {
- "expected": "PASS",
- "actual": "TEXT"
- }
},
+ "revision": "90429"
},
- "revision": "90429"
- },
- "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGJWCUQw":{
- "tests": {
- "userscripts": {
- "another-test.html": {
- "expected": "PASS",
- "actual": "TEXT"
- }
+ "11106":{
+ "tests": {
+ "userscripts": {
+ "another-test.html": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ }
+ },
},
+ "revision": "90426"
},
- "revision": "90426"
- },
- "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGKbLUAw":{
- "tests": {
- "userscripts": {
- "user-script-video-document.html": {
- "expected": "FAIL",
- "actual": "TEXT"
+ "11105":{
+ "tests": {
+ "userscripts": {
+ "user-script-video-document.html": {
+ "expected": "FAIL",
+ "actual": "TEXT"
+ },
},
},
+ "revision": "90424"
},
- "revision": "90424"
},
- "abc":{
- "tests": {
- "userscripts": {
- "another-test.html": {
- "expected": "PASS",
- "actual": "TEXT"
- }
+ "Another_Builder": {
+ "22202":{
+ "tests": {
+ "userscripts": {
+ "another-test.html": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ }
+ },
},
+ "revision": "90426"
},
- "revision": "90426"
- },
- "xyz":{
- "tests": {
+ "22201":{
+ "tests": {
+ },
+ "revision": "90425"
},
- "revision": "90425"
- }
+ },
};
simulator.jsonp = function(url, callback) {
simulator.scheduleCallback(function() {
- if (/dir=1/.test(url)) {
- if (/builder=Mock/.test(url)) {
- callback([
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGLncUAw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGNfTUAw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGJWCUQw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGKbLUAw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGOj5UAw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGP-AUQw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGPL3UAw" },
- { "key": "agx0ZXN0LXJlc3VsdHNyEAsSCFRlc3RGaWxlGNHJQAw" },
- ]);
- } else if (/builder=Another/.test(url)) {
- callback([
- { "key": "abc" },
- { "key": "xyz" },
- ]);
- } else {
- ok(false, 'Unexpected URL: ' + url);
- }
- } else {
- var key = url.match(/key=([^&]+)/)[1];
- callback(keyMap[key]);
- }
+ var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)];
+ callback(result ? result : {});
+ });
+ };
+
+ simulator.get = function(url, callback) {
+ simulator.scheduleCallback(function() {
+ if (/Mock_Builder/.test(url))
+ callback('<a href="11101/"></a><a href="11102/"></a><a href="11103/"></a><a href="11104/"></a><a href="11105/"></a><a href="11106/"></a><a href="11107/"></a><a href="11108/"></a>');
+ else if (/Another_Builder/.test(url))
+ callback('<a href="22201/"></a><a href="22202/"></a>');
+ else
+ ok(false, 'Unexpected URL: ' + url);
});
};
+
simulator.runTest(function() {
results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html", function(oldestFailingRevision, newestPassingRevision) {
equals(oldestFailingRevision, 90426);
var simulator = new NetworkSimulator();
var keyMap = {
- "vsfdsfdsafsdafasd": {
- "tests": {
- "userscripts": {
- "another-test.html": {
- "expected": "PASS",
- "actual": "TEXT"
- }
+ "Mock_Builder": {
+ "11103": {
+ "tests": {
+ "userscripts": {
+ "another-test.html": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ }
+ },
},
+ "revision": ""
},
- "revision": ""
- },
- "gavsavsrfgwaevwefawvae":{
- "tests": {
+ "11102":{
+ "tests": {
+ },
+ "revision": ""
},
- "revision": ""
},
};
simulator.jsonp = function(url, callback) {
simulator.scheduleCallback(function() {
- if (/dir=1/.test(url)) {
- callback([
- { "key": "vsfdsfdsafsdafasd" },
- { "key": "gavsavsrfgwaevwefawvae" },
- ]);
- } else {
- var key = url.match(/key=([^&]+)/)[1];
- callback(keyMap[key]);
- }
+ var result = keyMap[/[^/]+_Builder/.exec(url)][/\d+/.exec(url)];
+ callback(result ? result : {});
+ });
+ };
+
+ simulator.get = function(url, callback) {
+ simulator.scheduleCallback(function() {
+ callback('<a href="11101/"></a><a href="11102/"></a><a href="11103/"></a>');
});
};
+
simulator.runTest(function() {
results.regressionRangeForFailure("Mock Builder", "userscripts/another-test.html", function(oldestFailingRevision, newestPassingRevision) {
equals(oldestFailingRevision, 0);
+2011-09-28 Adam Barth <abarth@webkit.org>
+
+ garden-o-matic shouldn't depend on test-results.appspot.com
+ https://bugs.webkit.org/show_bug.cgi?id=69019
+
+ Reviewed by Dimitri Glazkov.
+
+ This patch moves garden-o-matic from getting full_results.json from
+ test-results.appspot.com to getting that information directly from the
+ buildbot. This patch improve the load time and accuracy of
+ garden-o-matic because test-results.appspot.com is slow and is dropping
+ a significant number of writes (see
+ https://bugs.webkit.org/show_bug.cgi?id=68748).
+
+ * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/net.js:
+ * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/results.js:
+ * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/results_unittests.js:
+
2011-09-28 David Levin <levin@chromium.org>
watchlist: Add a way to load the watchlist from config.