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

Side by Side Diff: Tools/GardeningServer/scripts/results.js

Issue 173133003: Convert garden-o-matic guts over to promises where appropriate (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: update to ToT Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // FIXME: Add support for the rest of the result types. 67 // FIXME: Add support for the rest of the result types.
68 ]; 68 ];
69 69
70 // Kinds of results. 70 // Kinds of results.
71 results.kActualKind = 'actual'; 71 results.kActualKind = 'actual';
72 results.kExpectedKind = 'expected'; 72 results.kExpectedKind = 'expected';
73 results.kDiffKind = 'diff'; 73 results.kDiffKind = 'diff';
74 results.kUnknownKind = 'unknown'; 74 results.kUnknownKind = 'unknown';
75 75
76 // Types of tests. 76 // Types of tests.
77 results.kImageType = 'image' 77 results.kImageType = 'image';
78 results.kAudioType = 'audio' 78 results.kAudioType = 'audio';
79 results.kTextType = 'text' 79 results.kTextType = 'text';
80 // FIXME: There are more types of tests. 80 // FIXME: There are more types of tests.
81 81
82 function possibleSuffixListFor(failureTypeList) 82 function possibleSuffixListFor(failureTypeList)
83 { 83 {
84 var suffixList = []; 84 var suffixList = [];
85 85
86 function pushImageSuffixes() 86 function pushImageSuffixes()
87 { 87 {
88 suffixList.push(kExpectedImageSuffix); 88 suffixList.push(kExpectedImageSuffix);
89 suffixList.push(kActualImageSuffix); 89 suffixList.push(kActualImageSuffix);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 function resultsSummaryURL(builderName) 188 function resultsSummaryURL(builderName)
189 { 189 {
190 return resultsDirectoryURL(builderName) + kResultsName; 190 return resultsDirectoryURL(builderName) + kResultsName;
191 } 191 }
192 192
193 function resultsSummaryURLForBuildNumber(builderName, buildNumber) 193 function resultsSummaryURLForBuildNumber(builderName, buildNumber)
194 { 194 {
195 return resultsDirectoryURLForBuildNumber(builderName, buildNumber) + kResult sName; 195 return resultsDirectoryURLForBuildNumber(builderName, buildNumber) + kResult sName;
196 } 196 }
197 197
198 var g_resultsCache = new base.AsynchronousCache(function (key, callback) { 198 var g_resultsCache = new base.AsynchronousCache(function(key) {
199 net.jsonp(key).then(callback); 199 return net.jsonp(key);
200 }); 200 });
201 201
202 results.ResultAnalyzer = base.extends(Object, { 202 results.ResultAnalyzer = base.extends(Object, {
203 init: function(resultNode) 203 init: function(resultNode)
204 { 204 {
205 this._isUnexpected = resultNode.is_unexpected; 205 this._isUnexpected = resultNode.is_unexpected;
206 this._actual = resultNode ? results.failureTypeList(resultNode.actual) : []; 206 this._actual = resultNode ? results.failureTypeList(resultNode.actual) : [];
207 this._expected = resultNode ? this._addImpliedExpectations(results.failu reTypeList(resultNode.expected)) : []; 207 this._expected = resultNode ? this._addImpliedExpectations(results.failu reTypeList(resultNode.expected)) : [];
208 }, 208 },
209 _addImpliedExpectations: function(resultsList) 209 _addImpliedExpectations: function(resultsList)
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 { 306 {
307 var collectedResults = []; 307 var collectedResults = [];
308 $.each(dictionaryOfResultNodes, function(key, resultNode) { 308 $.each(dictionaryOfResultNodes, function(key, resultNode) {
309 var analyzer = new results.ResultAnalyzer(resultNode); 309 var analyzer = new results.ResultAnalyzer(resultNode);
310 collectedResults = collectedResults.concat(analyzer.unexpectedResults()) ; 310 collectedResults = collectedResults.concat(analyzer.unexpectedResults()) ;
311 }); 311 });
312 return base.uniquifyArray(collectedResults); 312 return base.uniquifyArray(collectedResults);
313 }; 313 };
314 314
315 // Callback data is [{ buildNumber:, url: }] 315 // Callback data is [{ buildNumber:, url: }]
316 function historicalResultsLocations(builderName, callback) 316 function historicalResultsLocations(builderName)
317 { 317 {
318 var historicalResultsData = []; 318 var historicalResultsData = [];
319
320 function parseListingDocument(prefixListingDocument) { 319 function parseListingDocument(prefixListingDocument) {
321 $(prefixListingDocument).find("Prefix").each(function() { 320 $(prefixListingDocument).find("Prefix").each(function() {
322 var buildString = this.textContent.replace(config.resultsDirectoryNa meFromBuilderName(builderName) + '/', ''); 321 var buildString = this.textContent.replace(config.resultsDirectoryNa meFromBuilderName(builderName) + '/', '');
323 if (buildString.match(/\d+\//)) { 322 if (buildString.match(/\d+\//)) {
324 var buildNumber = parseInt(buildString); 323 var buildNumber = parseInt(buildString);
325 var resultsData = { 324 var resultsData = {
326 'buildNumber': buildNumber, 325 'buildNumber': buildNumber,
327 'url': resultsSummaryURLForBuildNumber(builderName, buildNum ber) 326 'url': resultsSummaryURLForBuildNumber(builderName, buildNum ber)
328 }; 327 };
329 historicalResultsData.unshift(resultsData); 328 historicalResultsData.unshift(resultsData);
330 } 329 }
331 }); 330 });
332 var nextMarker = $(prefixListingDocument).find('NextMarker').get(); 331 var nextMarker = $(prefixListingDocument).find('NextMarker').get();
333 if (nextMarker.length) { 332 if (nextMarker.length) {
334 var nextListingURL = resultsPrefixListingURL(builderName, nextMarker [0].textContent); 333 var nextListingURL = resultsPrefixListingURL(builderName, nextMarker [0].textContent);
335 net.xml(nextListingURL).then(parseListingDocument); 334 return net.xml(nextListingURL).then(function(doc) {
335 return parseListingDocument(doc);
336 });
336 } else { 337 } else {
337 callback(historicalResultsData); 338 return historicalResultsData;
338 } 339 }
339 } 340 }
340 341
341 builders.mostRecentBuildForBuilder(builderName, function (mostRecentBuildNum ber) { 342 return builders.mostRecentBuildForBuilder(builderName).then(function (mostRe centBuildNumber) {
342 var marker = config.resultsDirectoryNameFromBuilderName(builderName) + " /" + (mostRecentBuildNumber - 100) + "/"; 343 var marker = config.resultsDirectoryNameFromBuilderName(builderName) + " /" + (mostRecentBuildNumber - 100) + "/";
343 var listingURL = resultsPrefixListingURL(builderName, marker); 344 var listingURL = resultsPrefixListingURL(builderName, marker);
344 net.xml(listingURL).then(parseListingDocument); 345 return net.xml(listingURL).then(function(doc) {
346 return parseListingDocument(doc);
347 });
345 }); 348 });
346 } 349 }
347 350
348 function walkHistory(builderName, testName, callback) 351 // This will repeatedly call continueCallback(revision, resultNode) until it ret urns false.
352 function walkHistory(builderName, testName, continueCallback)
349 { 353 {
350 var indexOfNextKeyToFetch = 0; 354 var indexOfNextKeyToFetch = 0;
351 var keyList = []; 355 var keyList = [];
352 356
353 function continueWalk() 357 function continueWalk()
354 { 358 {
355 if (indexOfNextKeyToFetch >= keyList.length) { 359 if (indexOfNextKeyToFetch >= keyList.length) {
356 processResultNode(0, null); 360 processResultNode(0, null);
357 return; 361 return;
358 } 362 }
359 363
360 var resultsURL = keyList[indexOfNextKeyToFetch].url; 364 var resultsURL = keyList[indexOfNextKeyToFetch].url;
361 ++indexOfNextKeyToFetch; 365 ++indexOfNextKeyToFetch;
362 g_resultsCache.get(resultsURL, function(resultsTree) { 366 g_resultsCache.get(resultsURL).then(function(resultsTree) {
363 if ($.isEmptyObject(resultsTree)) { 367 if ($.isEmptyObject(resultsTree)) {
364 continueWalk(); 368 continueWalk();
365 return; 369 return;
366 } 370 }
367 var resultNode = results.resultNodeForTest(resultsTree, testName); 371 var resultNode = results.resultNodeForTest(resultsTree, testName);
368 var revision = parseInt(resultsTree['blink_revision']) 372 var revision = parseInt(resultsTree['blink_revision']);
369 if (isNaN(revision)) 373 if (isNaN(revision))
370 revision = 0; 374 revision = 0;
371 processResultNode(revision, resultNode); 375 processResultNode(revision, resultNode);
372 }); 376 });
373 } 377 }
374 378
375 function processResultNode(revision, resultNode) 379 function processResultNode(revision, resultNode)
376 { 380 {
377 var shouldContinue = callback(revision, resultNode); 381 var shouldContinue = continueCallback(revision, resultNode);
378 if (!shouldContinue) 382 if (!shouldContinue)
379 return; 383 return;
380 continueWalk(); 384 continueWalk();
381 } 385 }
382 386
383 historicalResultsLocations(builderName, function(resultsLocations) { 387 historicalResultsLocations(builderName).then(function(resultsLocations) {
384 keyList = resultsLocations; 388 keyList = resultsLocations;
385 continueWalk(); 389 continueWalk();
386 }); 390 });
387 } 391 }
388 392
389 results.regressionRangeForFailure = function(builderName, testName, callback) 393 results.regressionRangeForFailure = function(builderName, testName) {
390 { 394 return new Promise(function(resolve, reject) {
391 var oldestFailingRevision = 0; 395 var oldestFailingRevision = 0;
392 var newestPassingRevision = 0; 396 var newestPassingRevision = 0;
393 397
394 walkHistory(builderName, testName, function(revision, resultNode) { 398 walkHistory(builderName, testName, function(revision, resultNode) {
395 if (!revision) { 399 if (!revision) {
396 callback(oldestFailingRevision, newestPassingRevision); 400 resolve([oldestFailingRevision, newestPassingRevision]);
401 return false;
402 }
403 if (!resultNode) {
404 newestPassingRevision = revision;
405 resolve([oldestFailingRevision, newestPassingRevision]);
406 return false;
407 }
408 if (isUnexpectedFailure(resultNode)) {
409 oldestFailingRevision = revision;
410 return true;
411 }
412 if (!oldestFailingRevision)
413 return true; // We need to keep looking for a failing revision.
414 newestPassingRevision = revision;
415 resolve([oldestFailingRevision, newestPassingRevision]);
397 return false; 416 return false;
398 } 417 });
399 if (!resultNode) {
400 newestPassingRevision = revision;
401 callback(oldestFailingRevision, newestPassingRevision);
402 return false;
403 }
404 if (isUnexpectedFailure(resultNode)) {
405 oldestFailingRevision = revision;
406 return true;
407 }
408 if (!oldestFailingRevision)
409 return true; // We need to keep looking for a failing revision.
410 newestPassingRevision = revision;
411 callback(oldestFailingRevision, newestPassingRevision);
412 return false;
413 }); 418 });
414 }; 419 };
415 420
416 function mergeRegressionRanges(regressionRanges) 421 function mergeRegressionRanges(regressionRanges)
417 { 422 {
418 var mergedRange = {}; 423 var mergedRange = {};
419 424
420 mergedRange.oldestFailingRevision = 0; 425 mergedRange.oldestFailingRevision = 0;
421 mergedRange.newestPassingRevision = 0; 426 mergedRange.newestPassingRevision = 0;
422 427
423 $.each(regressionRanges, function(builderName, range) { 428 $.each(regressionRanges, function(builderName, range) {
424 if (!range.oldestFailingRevision && !range.newestPassingRevision) 429 if (!range.oldestFailingRevision && !range.newestPassingRevision)
425 return 430 return
426 431
427 if (!mergedRange.oldestFailingRevision) 432 if (!mergedRange.oldestFailingRevision)
428 mergedRange.oldestFailingRevision = range.oldestFailingRevision; 433 mergedRange.oldestFailingRevision = range.oldestFailingRevision;
429 if (!mergedRange.newestPassingRevision) 434 if (!mergedRange.newestPassingRevision)
430 mergedRange.newestPassingRevision = range.newestPassingRevision; 435 mergedRange.newestPassingRevision = range.newestPassingRevision;
431 436
432 if (range.oldestFailingRevision && range.oldestFailingRevision < mergedR ange.oldestFailingRevision) 437 if (range.oldestFailingRevision && range.oldestFailingRevision < mergedR ange.oldestFailingRevision)
433 mergedRange.oldestFailingRevision = range.oldestFailingRevision; 438 mergedRange.oldestFailingRevision = range.oldestFailingRevision;
434 if (range.newestPassingRevision > mergedRange.newestPassingRevision) 439 if (range.newestPassingRevision > mergedRange.newestPassingRevision)
435 mergedRange.newestPassingRevision = range.newestPassingRevision; 440 mergedRange.newestPassingRevision = range.newestPassingRevision;
436 }); 441 });
437 442
438 return mergedRange; 443 return mergedRange;
439 } 444 }
440 445
441 results.unifyRegressionRanges = function(builderNameList, testName, callback) 446 results.unifyRegressionRanges = function(builderNameList, testName) {
442 {
443 var regressionRanges = {}; 447 var regressionRanges = {};
444 448
445 var tracker = new base.RequestTracker(builderNameList.length, function() { 449 var rangePromises = [];
450 $.each(builderNameList, function(index, builderName) {
451 rangePromises.push(results.regressionRangeForFailure(builderName, testNa me)
452 .then(function(result) {
453 var oldestFailingRevision = result[0];
454 var newestPassingRevision = result[1];
455 var range = {};
456 range.oldestFailingRevision = oldestFailingRevisi on;
457 range.newestPassingRevision = newestPassingRevisi on;
458 regressionRanges[builderName] = range;
459 }));
460 });
461 return Promise.all(rangePromises).then(function() {
446 var mergedRange = mergeRegressionRanges(regressionRanges); 462 var mergedRange = mergeRegressionRanges(regressionRanges);
447 callback(mergedRange.oldestFailingRevision, mergedRange.newestPassingRev ision); 463 return [mergedRange.oldestFailingRevision, mergedRange.newestPassingRevi sion];
448 });
449
450 $.each(builderNameList, function(index, builderName) {
451 results.regressionRangeForFailure(builderName, testName, function(oldest FailingRevision, newestPassingRevision) {
452 var range = {};
453 range.oldestFailingRevision = oldestFailingRevision;
454 range.newestPassingRevision = newestPassingRevision;
455 regressionRanges[builderName] = range;
456 tracker.requestComplete();
457 });
458 }); 464 });
459 }; 465 };
460 466
461 results.resultNodeForTest = function(resultsTree, testName) 467 results.resultNodeForTest = function(resultsTree, testName)
462 { 468 {
463 var testNamePath = testName.split('/'); 469 var testNamePath = testName.split('/');
464 var currentNode = resultsTree['tests']; 470 var currentNode = resultsTree['tests'];
465 $.each(testNamePath, function(index, segmentName) { 471 $.each(testNamePath, function(index, segmentName) {
466 if (!currentNode) 472 if (!currentNode)
467 return; 473 return;
(...skipping 26 matching lines...) Expand all
494 { 500 {
495 var sortedURLs = []; 501 var sortedURLs = [];
496 $.each(kPreferredSuffixOrder, function(i, suffix) { 502 $.each(kPreferredSuffixOrder, function(i, suffix) {
497 $.each(urls, function(j, url) { 503 $.each(urls, function(j, url) {
498 if (!base.endsWith(url, suffix)) 504 if (!base.endsWith(url, suffix))
499 return; 505 return;
500 sortedURLs.push(url); 506 sortedURLs.push(url);
501 }); 507 });
502 }); 508 });
503 if (sortedURLs.length != urls.length) 509 if (sortedURLs.length != urls.length)
504 throw "sortResultURLsBySuffix failed to return the same number of URLs." 510 throw "sortResultURLsBySuffix failed to return the same number of URLs." ;
505 return sortedURLs; 511 return sortedURLs;
506 } 512 }
507 513
508 results.fetchResultsURLs = function(failureInfo, callback) 514 results.fetchResultsURLs = function(failureInfo)
509 { 515 {
510 var testNameStem = base.trimExtension(failureInfo.testName); 516 var testNameStem = base.trimExtension(failureInfo.testName);
511 var urlStem = resultsDirectoryURL(failureInfo.builderName); 517 var urlStem = resultsDirectoryURL(failureInfo.builderName);
512 518
513 var suffixList = possibleSuffixListFor(failureInfo.failureTypeList); 519 var suffixList = possibleSuffixListFor(failureInfo.failureTypeList);
514 var resultURLs = []; 520 var resultURLs = [];
515 var tracker = new base.RequestTracker(suffixList.length, function() { 521 var probePromises = [];
516 callback(sortResultURLsBySuffix(resultURLs));
517 });
518 $.each(suffixList, function(index, suffix) { 522 $.each(suffixList, function(index, suffix) {
519 var url = urlStem + testNameStem + suffix; 523 var url = urlStem + testNameStem + suffix;
520 net.probe(url).then( 524 probePromises.push(net.probe(url).then(
521 function() { 525 function() {
522 resultURLs.push(url); 526 resultURLs.push(url);
523 tracker.requestComplete();
524 }, 527 },
525 function() { 528 function() {}));
526 tracker.requestComplete(); 529 });
527 }); 530 return Promise.all(probePromises).then(function() {
531 return sortResultURLsBySuffix(resultURLs);
528 }); 532 });
529 }; 533 };
530 534
531 results.fetchResultsByBuilder = function(builderNameList, callback) 535 results.fetchResultsByBuilder = function(builderNameList)
532 { 536 {
533 var resultsByBuilder = {}; 537 var resultsByBuilder = {};
534 var tracker = new base.RequestTracker(builderNameList.length, function() { 538 var fetchPromises = [];
535 callback(resultsByBuilder);
536 });
537 $.each(builderNameList, function(index, builderName) { 539 $.each(builderNameList, function(index, builderName) {
538 var resultsURL = resultsSummaryURL(builderName); 540 var resultsURL = resultsSummaryURL(builderName);
539 net.jsonp(resultsURL).then(function(resultsTree) { 541 fetchPromises.push(net.jsonp(resultsURL).then(function(resultsTree) {
540 resultsByBuilder[builderName] = resultsTree; 542 resultsByBuilder[builderName] = resultsTree;
541 tracker.requestComplete(); 543 }));
542 }); 544 });
545 return Promise.all(fetchPromises).then(function() {
546 return resultsByBuilder;
543 }); 547 });
544 }; 548 };
545 549
546 })(); 550 })();
OLDNEW
« no previous file with comments | « Tools/GardeningServer/scripts/model_unittests.js ('k') | Tools/GardeningServer/scripts/results_unittests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698