1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 var loadfailures = loadfailures || {}; 6 7 (function() { 8 9 loadfailures._groupIndex = 0; 10 loadfailures._testTypeIndex = 0; 11 loadfailures._failureData = {}; 12 loadfailures._loader = null; 13 14 // FIXME: This is a gross hack to make it so that changing the test type and group in loadNextTestType don't reload the page. 15 history.reloadRequiringParameters = history.reloadRequiringParameters.filter(function(item) { return item != 'testType' && item != 'group'; }); 16 17 loadfailures.loadNextTestType = function(historyInstance) 18 { 19 var group = builders.groups[loadfailures._groupIndex]; 20 21 if (loadfailures._loader) { 22 var testType = builders.testTypes[loadfailures._testTypeIndex]; 23 var failures = loadfailures._loader.buildersThatFailedToLoad(); 24 if (failures.length) 25 loadfailures._failureData[group].failingBuilders[testType] = failures; 26 27 var stale = loadfailures._loader.staleBuilders(); 28 if (stale.length) 29 loadfailures._failureData[group].staleBuilders[testType] = stale; 30 31 if ((failures.length || stale.length) && !Object.keys(g_resultsByBuilder).length) 32 loadfailures._failureData[group].testTypesWithNoSuccessfullLoads.push(testType); 33 34 for (var builder in builders.builderToMaster) 35 loadfailures._failureData[group].builderToMaster[builder] = builders.builderToMaster[builder]; 36 } 37 38 loadfailures._testTypeIndex++; 39 if (loadfailures._testTypeIndex == builders.testTypes.length) { 40 41 loadfailures._groupIndex++; 42 loadfailures._testTypeIndex = 0; 43 44 if (loadfailures._groupIndex == builders.groups.length) { 45 loadfailures._generatePage(); 46 return; 47 } 48 } 49 50 var group = builders.groups[loadfailures._groupIndex]; 51 if (!loadfailures._failureData[group]) { 52 loadfailures._failureData[group] = { 53 failingBuilders: {}, 54 staleBuilders: {}, 55 testTypesWithNoSuccessfullLoads: [], 56 builderToMaster: {}, 57 } 58 } 59 historyInstance.crossDashboardState.group = group; 60 historyInstance.crossDashboardState.testType = builders.testTypes[loadfailures._testTypeIndex]; 61 62 var totalIterations = builders.groups.length * builders.testTypes.length; 63 var currentIteration = loadfailures._groupIndex * builders.testTypes.length + loadfailures._testTypeIndex 64 $('content').innerHTML = 'Loading ' + currentIteration + '/' + totalIterations + ' ' + 65 historyInstance.crossDashboardState.group + ': ' + historyInstance.crossDashboardState.testType + '...'; 66 67 // FIXME: Gross hack to allow loading all the builders for different test types. 68 // Change loader.js to allow you to pass in the state that it fills instead of setting globals. 69 g_resultsByBuilder = {}; 70 loadfailures._loader = new loader.Loader() 71 loadfailures._loader.load(); 72 } 73 74 loadfailures._generatePage = function() 75 { 76 $('content').innerHTML = loadfailures._html(loadfailures._failureData); 77 } 78 79 loadfailures._htmlForBuilder = function(builder, testType, builderToMaster) 80 { 81 return '<tr class="builder">' + 82 '<td>' + builder + 83 '<td><a href="http://test-results.appspot.com/testfile?testtype=' + 84 testType + '&builder=' + builder + '&master=' + builderToMaster[builder].name + '">uploaded results</a>' + 85 '<td><a href="' + builderToMaster[builder].builderPath(builder) + '">buildbot</a>' + 86 '</tr>'; 87 } 88 89 loadfailures._html = function(failureData) 90 { 91 var html = ''; 92 Object.keys(failureData).forEach(function(group) { 93 var failingBuildersByTestType = failureData[group].failingBuilders; 94 var staleBuildersByTestType = failureData[group].staleBuilders; 95 var testTypesWithNoSuccessfullLoads = failureData[group].testTypesWithNoSuccessfullLoads; 96 var builderToMaster = failureData[group].builderToMaster; 97 98 var testTypes = testTypesWithNoSuccessfullLoads.concat(Object.keys(failingBuildersByTestType).concat(Object.keys(staleBuildersByTestType))); 99 var uniqueTestTypes = testTypes.sort().filter(function(value, index, array) { 100 return array.indexOf(value) === index; 101 }); 102 103 if (!uniqueTestTypes.length) 104 return; 105 106 html += '<h1>' + group + '</h1>' + 107 '<table><tr><th>Test type</th><th>>1 week stale</th><th>>1 day stale, <1 week stale</th></tr>'; 108 109 uniqueTestTypes.forEach(function(testType) { 110 var failures = failingBuildersByTestType[testType] || []; 111 var failureHtml = ''; 112 failures.sort().forEach(function(builder) { 113 failureHtml += loadfailures._htmlForBuilder(builder, testType, builderToMaster); 114 }); 115 116 var stale = staleBuildersByTestType[testType] || []; 117 var staleHtml = ''; 118 stale.sort().forEach(function(builder) { 119 staleHtml += loadfailures._htmlForBuilder(builder, testType, builderToMaster); 120 }); 121 122 var noBuildersHtml = testTypesWithNoSuccessfullLoads.indexOf(testType) != -1 ? '<b>No builders with up to date results.</b>' : ''; 123 124 html += '<tr>' + 125 '<td><a href="http://test-results.appspot.com/testfile?name=results.json&testtype=' + testType + '" target=_blank>' + 126 testType + 127 '</a></td>' + 128 '<td>' + noBuildersHtml + '<table>' + failureHtml + '</table></td>' + 129 '<td><table>' + staleHtml + '</table></td>' + 130 '</tr>'; 131 }); 132 html += '</table>'; 133 }); 134 return html; 135 } 136 137 // FIXME: Once dashboard_base, loader and ui stop using the g_history global, we can stop setting it here. 138 g_history = new history.History({ 139 generatePage: loadfailures.loadNextTestType, 140 }); 141 g_history.parseCrossDashboardParameters(); 142 143 window.addEventListener('load', function() { 144 // FIXME: Come up with a better way to do this. This early return is just to avoid 145 // executing this code when it's loaded in the unittests. 146 if (!$('content')) 147 return; 148 loadfailures.loadNextTestType(g_history); 149 }, false); 150 151 })(); 152