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

Side by Side Diff: Tools/TestResultServer/static-dashboards/flakiness_dashboard.js

Issue 359533004: Group flakiness results by blink revision (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Cleanup for landing Created 6 years, 5 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
« no previous file with comments | « no previous file | Tools/TestResultServer/static-dashboards/flakiness_dashboard_tests.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (C) 2012 Google Inc. All rights reserved. 1 // Copyright (C) 2012 Google Inc. All rights reserved.
2 // 2 //
3 // Redistribution and use in source and binary forms, with or without 3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are 4 // modification, are permitted provided that the following conditions are
5 // met: 5 // met:
6 // 6 //
7 // * Redistributions of source code must retain the above copyright 7 // * 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 // * Redistributions in binary form must reproduce the above 9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer 10 // copyright notice, this list of conditions and the following disclaimer
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 '/' + buildNumber + '/layout-test-results.zip">layout-test-results.z ip</a></li>'; 530 '/' + buildNumber + '/layout-test-results.zip">layout-test-results.z ip</a></li>';
531 } 531 }
532 532
533 if (!g_history.isLayoutTestResults() && opt_testName && isFailure(builder, o pt_testName, index)) 533 if (!g_history.isLayoutTestResults() && opt_testName && isFailure(builder, o pt_testName, index))
534 html += '<li>' + linkHTMLToOpenWindow(buildBasePath + pathToFailureLog(o pt_testName), 'Failure log') + '</li>'; 534 html += '<li>' + linkHTMLToOpenWindow(buildBasePath + pathToFailureLog(o pt_testName), 'Failure log') + '</li>';
535 535
536 html += '</ul>'; 536 html += '</ul>';
537 ui.popup.show(e.target, html); 537 ui.popup.show(e.target, html);
538 } 538 }
539 539
540 function showPopupForInterpolatedResult(e, revision)
541 {
542 var html = 'This bot did not run the test for r' + revision + '.';
543 ui.popup.show(e.target, html);
544 }
545
540 function classNameForFailureString(failure) 546 function classNameForFailureString(failure)
541 { 547 {
542 return failure.replace(/(\+|\ )/, ''); 548 return failure.replace(/(\+|\ )/, '');
543 } 549 }
544 550
545 function htmlForTestResults(test) 551 function htmlForTestResults(test, revisions)
546 { 552 {
547 var html = ''; 553 var html = '';
548 var testResults = test.rawResults.concat(); 554 var testResults = test.rawResults.concat();
549 var times = test.rawTimes.concat(); 555 var times = test.rawTimes.concat();
550 var builder = test.builder; 556 var builder = test.builder;
551 var master = builders.master(builder); 557 var master = builders.master(builder);
552 var buildNumbers = g_resultsByBuilder[builder].buildNumbers; 558 var buildNumbers = g_resultsByBuilder[builder].buildNumbers;
553 559
560 // FIXME: Support other revision types instead of just chrome/blink.
561 var revisionType = g_history.isBlinkGroup() ?
562 results.BLINK_REVISIONS : results.CHROME_REVISIONS;
563
564 var cells = [];
565 for (var index = 0; index < revisions.length; index++)
566 cells.push({revision: revisions[index]});
567
554 var indexToReplaceCurrentResult = -1; 568 var indexToReplaceCurrentResult = -1;
555 var indexToReplaceCurrentTime = -1; 569 var indexToReplaceCurrentTime = -1;
556 for (var i = 0; i < buildNumbers.length; i++) { 570 for (var i = 0; i < buildNumbers.length; i++) {
557 var currentResultArray, currentTimeArray, innerHTML, resultString; 571 var currentResultArray, currentTimeArray, currentTime, resultString;
558 572
559 if (i > indexToReplaceCurrentResult) { 573 if (i > indexToReplaceCurrentResult) {
560 currentResultArray = testResults.shift(); 574 currentResultArray = testResults.shift();
561 if (currentResultArray) { 575 if (currentResultArray) {
562 resultString = g_resultsByBuilder[builder][results.FAILURE_MAP][ currentResultArray[results.RLE.VALUE]]; 576 resultString = g_resultsByBuilder[builder][results.FAILURE_MAP][ currentResultArray[results.RLE.VALUE]];
563 indexToReplaceCurrentResult += currentResultArray[results.RLE.LE NGTH]; 577 indexToReplaceCurrentResult += currentResultArray[results.RLE.LE NGTH];
564 } else { 578 } else {
565 resultString = results.NO_DATA; 579 resultString = results.NO_DATA;
566 indexToReplaceCurrentResult += buildNumbers.length; 580 indexToReplaceCurrentResult += buildNumbers.length;
567 } 581 }
568 } 582 }
569 583
570 if (i > indexToReplaceCurrentTime) { 584 if (i > indexToReplaceCurrentTime) {
571 currentTimeArray = times.shift(); 585 currentTimeArray = times.shift();
572 var currentTime = 0; 586 currentTime = 0;
573 if (currentResultArray) { 587 if (currentResultArray) {
574 currentTime = currentTimeArray[results.RLE.VALUE]; 588 currentTime = currentTimeArray[results.RLE.VALUE];
575 indexToReplaceCurrentTime += currentTimeArray[results.RLE.LENGTH]; 589 indexToReplaceCurrentTime += currentTimeArray[results.RLE.LENGTH];
576 } else 590 } else
577 indexToReplaceCurrentTime += buildNumbers.length; 591 indexToReplaceCurrentTime += buildNumbers.length;
578
579 innerHTML = currentTime || '&nbsp;';
580 } 592 }
581 593
582 html += '<td title="' + resultString + '. Click for more info." class="r esults ' + classNameForFailureString(resultString) + 594 var revision = parseInt(
583 '" onclick=\'showPopupForBuild(event, "' + builder + '",' + i + ',"' + test.test + '")\'>' + innerHTML; 595 g_resultsByBuilder[builder][revisionType][i], 10);
596
597 // Locate the empty cell corresponding to this blink revision.
598 var cell = undefined;
599 for (var index = 0; index < cells.length; index++) {
600 if (cells[index].revision == revision && !cells[index].html) {
601 cell = cells[index];
602 break;
603 }
604 }
605
606 cell.className = classNameForFailureString(resultString);
607 cell.hasResult =
608 resultString !== results.NO_DATA && resultString !== results.NOTRUN;
609 cell.html = '<td'
610 + ' title="' + resultString + '. Click for more info."'
611 + ' class="results ' + cell.className + '"'
612 + ' onclick=\'showPopupForBuild(event,'
613 + ' "' + builder + '",' + i + ',"' + test.test + '")\'>'
614 + (currentTime || (cell.hasResult ? '' : '?')) + '</td>';
584 } 615 }
616
617 populateEmptyCells(cells);
618
619 for (var index = 0; index < cells.length; index++)
620 html += cells[index].html;
621
585 return html; 622 return html;
586 } 623 }
587 624
625 // Fill in cells where no test data is available with a question mark.
626 // If the next and previous runs were equal, an "interpolated" result is shown.
627 function populateEmptyCells(cells)
628 {
629 for (var index = 1; index < cells.length; index++) {
630 var prevCell = cells[index - 1];
631 cells[index].nextClassName =
632 prevCell.hasResult ? prevCell.className : prevCell.nextClassName;
633 }
634
635 for (var index = cells.length - 2; index >= 0; --index) {
636 var nextCell = cells[index + 1];
637 cells[index].prevClassName =
638 nextCell.hasResult ? nextCell.className : nextCell.prevClassName;
639 }
640
641 cells.forEach(function(cell) {
642 if (!cell.html) {
643 var interpolateResult =
644 cell.nextClassName && cell.nextClassName == cell.prevClassName;
645 cell.className = interpolateResult ? cell.nextClassName : "NODATA";
646 cell.html = '<td'
647 + ' title="Unknown result. Did not run tests."'
648 + ' onclick=\'showPopupForInterpolatedResult(event,'
649 + ' ' + cell.revision + ')\''
650 + ' class="results interpolatedResult ' + cell.className + '"'
651 + ' >?</td>';
652 }
653 });
654 }
655
588 function shouldShowTest(testResult) 656 function shouldShowTest(testResult)
589 { 657 {
590 if (!g_history.isLayoutTestResults()) 658 if (!g_history.isLayoutTestResults())
591 return true; 659 return true;
592 660
593 if (testResult.expectations == 'WONTFIX') 661 if (testResult.expectations == 'WONTFIX')
594 return g_history.dashboardSpecificState.showWontFix; 662 return g_history.dashboardSpecificState.showWontFix;
595 663
596 if (testResult.expectations == results.SKIP) 664 if (testResult.expectations == results.SKIP)
597 return g_history.dashboardSpecificState.showSkip; 665 return g_history.dashboardSpecificState.showSkip;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 var bugHtml; 710 var bugHtml;
643 if (string.startsWith(bug, 'Bug(')) 711 if (string.startsWith(bug, 'Bug('))
644 bugHtml = bug; 712 bugHtml = bug;
645 else 713 else
646 bugHtml = '<a href="http://' + bug + '">' + bug + '</a>'; 714 bugHtml = '<a href="http://' + bug + '">' + bug + '</a>';
647 html += '<div>' + bugHtml + '</div>' 715 html += '<div>' + bugHtml + '</div>'
648 }); 716 });
649 return html; 717 return html;
650 } 718 }
651 719
652 function htmlForSingleTestRow(test, showBuilderNames) 720 function htmlForSingleTestRow(test, showBuilderNames, revisions)
653 { 721 {
654 var headers = tableHeaders(); 722 var headers = tableHeaders();
655 var html = ''; 723 var html = '';
656 for (var i = 0; i < headers.length; i++) { 724 for (var i = 0; i < headers.length; i++) {
657 var header = headers[i]; 725 var header = headers[i];
658 if (string.startsWith(header, 'test') || string.startsWith(header, 'buil der')) { 726 if (string.startsWith(header, 'test') || string.startsWith(header, 'buil der')) {
659 var testCellClassName = 'test-link' + (showBuilderNames ? ' builder- name' : ''); 727 var testCellClassName = 'test-link' + (showBuilderNames ? ' builder- name' : '');
660 var testCellHTML = showBuilderNames ? test.builder : '<span class="l ink" onclick="g_history.setQueryParameter(\'tests\',\'' + test.test +'\');">' + test.test + '</span>'; 728 var testCellHTML = showBuilderNames ? test.builder : '<span class="l ink" onclick="g_history.setQueryParameter(\'tests\',\'' + test.test +'\');">' + test.test + '</span>';
661 html += '<tr><td class="' + testCellClassName + '">' + testCellHTML; 729 html += '<tr><td class="' + testCellClassName + '">' + testCellHTML;
662 } else if (string.startsWith(header, 'bugs')) 730 } else if (string.startsWith(header, 'bugs'))
663 // FIXME: linkify bugs. 731 // FIXME: linkify bugs.
664 html += '<td class=options-container>' + (linkifyBugs(test.bugs) || createBugHTML(test)); 732 html += '<td class=options-container>' + (linkifyBugs(test.bugs) || createBugHTML(test));
665 else if (string.startsWith(header, 'expectations')) 733 else if (string.startsWith(header, 'expectations'))
666 html += '<td class=options-container>' + test.expectations; 734 html += '<td class=options-container>' + test.expectations;
667 else if (string.startsWith(header, 'slowest')) 735 else if (string.startsWith(header, 'slowest'))
668 html += '<td>' + (test.slowestTime ? test.slowestTime + 's' : ''); 736 html += '<td>' + (test.slowestTime ? test.slowestTime + 's' : '');
669 else if (string.startsWith(header, 'flakiness')) 737 else if (string.startsWith(header, 'flakiness'))
670 html += htmlForTestResults(test); 738 html += htmlForTestResults(test, revisions);
671 } 739 }
672 return html; 740 return html;
673 } 741 }
674 742
675 function sortColumnFromTableHeader(headerText) 743 function sortColumnFromTableHeader(headerText)
676 { 744 {
677 return headerText.split(' ', 1)[0]; 745 return headerText.split(' ', 1)[0];
678 } 746 }
679 747
680 function htmlForTableColumnHeader(headerName, opt_fillColSpan) 748 function htmlForTableColumnHeader(headerName, opt_fillColSpan)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 sortFunctionGetter = numericSort; 844 sortFunctionGetter = numericSort;
777 resultsProperty = 'slowestTime'; 845 resultsProperty = 'slowestTime';
778 } else { 846 } else {
779 sortFunctionGetter = alphanumericCompare; 847 sortFunctionGetter = alphanumericCompare;
780 resultsProperty = column; 848 resultsProperty = column;
781 } 849 }
782 850
783 tests.sort(sortFunctionGetter(resultsProperty, order == BACKWARD)); 851 tests.sort(sortFunctionGetter(resultsProperty, order == BACKWARD));
784 } 852 }
785 853
854 // Return an array of revisions across all builders such that all of a builder's
855 // builds have a unique entry in the list. The currently selected group
856 // (e.g., @ToT Chromium) determines which revision type is not collapsed.
857 // Note that revisions may not be unique: a single builder can have two runs at
858 // the same blink revision but different chrome revisions which will result in
859 // multiple entries of the same blink revision.
860 function collapsedRevisionList(testResults)
861 {
862 // FIXME: Support other revision types instead of just chrome/blink.
863 var revisionType = g_history.isBlinkGroup() ?
864 results.BLINK_REVISIONS : results.CHROME_REVISIONS;
865
866 var revisionsCountedSet = {};
867 for (var resultIndex = 0; resultIndex < testResults.length; resultIndex++) {
868 var builder = testResults[resultIndex].builder;
869 var build = g_resultsByBuilder[builder];
870 var buildNumbers = build.buildNumbers;
871 var builderRevisionsCountedSet = {};
872 for (var i = 0; i < buildNumbers.length; i++) {
873 var revision = build[revisionType][i];
874 builderRevisionsCountedSet[revision] =
875 (builderRevisionsCountedSet[revision] || 0) + 1;
876 }
877
878 // Join builder's revisions with the total revisions for all builders.
879 for (var revision in builderRevisionsCountedSet)
880 revisionsCountedSet[revision] = Math.max(revisionsCountedSet[revisio n] || 0, builderRevisionsCountedSet[revision]);
881 }
882
883 var revisionsArray = [];
884 for (var revision in revisionsCountedSet) {
885 for (var i = revisionsCountedSet[revision] - 1; i >= 0; --i)
886 revisionsArray.push(revision);
887 }
888
889 revisionsArray.sort(function(a, b) {
890 return (b - a);
891 });
892 return revisionsArray;
893 }
894
786 function htmlForIndividualTestOnAllBuilders(test) 895 function htmlForIndividualTestOnAllBuilders(test)
787 { 896 {
788 processTestRunsForAllBuilders(); 897 processTestRunsForAllBuilders();
789 898
790 var testResults = g_testToResultsMap[test]; 899 var testResults = g_testToResultsMap[test];
791 if (!testResults) 900 if (!testResults)
792 return '<div class="not-found">Test not found. Either it does not exist, is skipped or passes on all recorded runs.</div>'; 901 return '<div class="not-found">Test not found. Either it does not exist, is skipped or passes on all recorded runs.</div>';
793 902
794 var html = ''; 903 var html = '';
795 var shownBuilders = []; 904 var shownBuilders = [];
905 var revisions = collapsedRevisionList(testResults);
796 for (var j = 0; j < testResults.length; j++) { 906 for (var j = 0; j < testResults.length; j++) {
797 shownBuilders.push(testResults[j].builder); 907 shownBuilders.push(testResults[j].builder);
798 var showBuilderNames = true; 908 var showBuilderNames = true;
799 html += htmlForSingleTestRow(testResults[j], showBuilderNames); 909 html += htmlForSingleTestRow(testResults[j], showBuilderNames, revisions );
800 } 910 }
801 911
802 var skippedBuilders = [] 912 var skippedBuilders = []
803 for (builder in currentBuilders()) { 913 for (builder in currentBuilders()) {
804 if (shownBuilders.indexOf(builder) == -1) 914 if (shownBuilders.indexOf(builder) == -1)
805 skippedBuilders.push(builder); 915 skippedBuilders.push(builder);
806 } 916 }
807 917
808 var skippedBuildersHtml = ''; 918 var skippedBuildersHtml = '';
809 if (skippedBuilders.length) { 919 if (skippedBuilders.length) {
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 { 1364 {
1255 processTestRunsForBuilder(builderName); 1365 processTestRunsForBuilder(builderName);
1256 1366
1257 var filteredResults = g_perBuilderFailures[builderName].filter(shouldShowTes t); 1367 var filteredResults = g_perBuilderFailures[builderName].filter(shouldShowTes t);
1258 sortTests(filteredResults, g_history.dashboardSpecificState.sortColumn, g_hi story.dashboardSpecificState.sortOrder); 1368 sortTests(filteredResults, g_history.dashboardSpecificState.sortColumn, g_hi story.dashboardSpecificState.sortOrder);
1259 1369
1260 var testsHTML = ''; 1370 var testsHTML = '';
1261 if (filteredResults.length) { 1371 if (filteredResults.length) {
1262 var tableRowsHTML = ''; 1372 var tableRowsHTML = '';
1263 var showBuilderNames = false; 1373 var showBuilderNames = false;
1374 var revisions = collapsedRevisionList(filteredResults);
1264 for (var i = 0; i < filteredResults.length; i++) 1375 for (var i = 0; i < filteredResults.length; i++)
1265 tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilde rNames) 1376 tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilde rNames, revisions);
1266 testsHTML = htmlForTestTable(tableRowsHTML); 1377 testsHTML = htmlForTestTable(tableRowsHTML);
1267 } else { 1378 } else {
1268 if (g_history.isLayoutTestResults()) 1379 if (g_history.isLayoutTestResults())
1269 testsHTML += '<div>Fill in one of the text inputs or checkboxes abov e to show failures.</div>'; 1380 testsHTML += '<div>Fill in one of the text inputs or checkboxes abov e to show failures.</div>';
1270 else 1381 else
1271 testsHTML += '<div>No tests have failed!</div>'; 1382 testsHTML += '<div>No tests have failed!</div>';
1272 } 1383 }
1273 1384
1274 var html = htmlForNavBar(); 1385 var html = htmlForNavBar();
1275 1386
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1380 // escape key 1491 // escape key
1381 hideLegend(); 1492 hideLegend();
1382 ui.popup.hide(); 1493 ui.popup.hide();
1383 } 1494 }
1384 }, false); 1495 }, false);
1385 1496
1386 window.addEventListener('load', function() { 1497 window.addEventListener('load', function() {
1387 resourceLoader = new loader.Loader(); 1498 resourceLoader = new loader.Loader();
1388 resourceLoader.load(); 1499 resourceLoader.load();
1389 }, false); 1500 }, false);
OLDNEW
« no previous file with comments | « no previous file | Tools/TestResultServer/static-dashboards/flakiness_dashboard_tests.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698