1 // Copyright (C) 2012 Google Inc. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google Inc. nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 function LOAD_BUILDBOT_DATA(builderData) 30 { 31 builders.masters = {}; 32 var groups = {}; 33 var testTypes = {}; 34 builderData['masters'].forEach(function(master) { 35 builders.masters[master.name] = new builders.BuilderMaster(master.name, master.url, master.tests, master.groups); 36 37 master.groups.forEach(function(group) { groups[group] = true; }); 38 39 Object.keys(master.tests).forEach(function(testType) { 40 if (builders.testTypeUploadsToFlakinessDashboardServer(testType)) 41 testTypes[testType] = true; 42 }); 43 }); 44 builders.groups = Object.keys(groups); 45 builders.groups.sort(); 46 builders.testTypes = Object.keys(testTypes); 47 builders.testTypes.sort(); 48 } 49 50 var builders = builders || {}; 51 52 (function() { 53 54 builders.testTypeUploadsToFlakinessDashboardServer = function(testType) 55 { 56 // FIXME: Encode whether the test uploads to the server in the buildbot json so 57 // we can include that data in buildbot.jsonp and not need to do ugly heuristics 58 // based off the name of the test suite. This code both has some false positives 59 // and some false negatives. 60 return !testType.match(/_only|_ignore|_perf$/) && !testType.match(/^memory test:|install_/) && testType != 'Run tests'; 61 } 62 63 var currentBuilderGroup = {}; 64 var testTypesThatRunToTBlinkBots = ['layout-tests', 'webkit_unit_tests']; 65 66 builders.getBuilderGroup = function(groupName, testType) 67 { 68 if (!builders in currentBuilderGroup) { 69 currentBuilderGroup = builders.loadBuildersList(groupName, testType); 70 } 71 return currentBuilderGroup; 72 } 73 74 function isChromiumWebkitTipOfTreeTestRunner(builder) 75 { 76 // FIXME: Remove the Android check once the android tests bot is actually uploading results. 77 return builder.indexOf('ASAN') == -1 && 78 builder.indexOf('Android') == -1 && 79 !isChromiumWebkitDepsTestRunner(builder); 80 } 81 82 function isChromiumWebkitDepsTestRunner(builder) 83 { 84 return builder.indexOf('(deps)') != -1; 85 } 86 87 builders._builderFilter = function(groupName, masterName, testType) 88 { 89 if (testTypesThatRunToTBlinkBots.indexOf(testType) == -1) { 90 if (masterName == 'ChromiumWebkit' && groupName != '@ToT Blink') 91 return function() { return false }; 92 return null; 93 } 94 95 if (groupName == '@ToT Blink') 96 return isChromiumWebkitTipOfTreeTestRunner; 97 98 if (groupName == '@ToT Chromium') 99 return isChromiumWebkitDepsTestRunner; 100 101 return null; 102 } 103 104 var builderToMaster = {}; 105 106 builders.master = function(builderName) 107 { 108 return builderToMaster[builderName]; 109 } 110 111 function populateBuilderToMaster() 112 { 113 var allMasterNames = Object.keys(builders.masters); 114 115 allMasterNames.forEach(function(masterName) { 116 var master = builders.masters[masterName]; 117 var testTypes = Object.keys(master.tests); 118 testTypes.forEach(function (testType) { 119 var builderList = master.tests[testType].builders; 120 builderList.forEach(function (builderName) { 121 builderToMaster[builderName] = master; 122 }); 123 }); 124 }); 125 } 126 127 builders.loadBuildersList = function(groupName, testType) 128 { 129 if (!groupName || !testType) { 130 console.warn("Group name and/or test type were empty."); 131 return new builders.BuilderGroup(false); 132 } 133 var builderGroup = new builders.BuilderGroup(groupName == '@ToT Blink'); 134 135 for (masterName in builders.masters) { 136 if (!builders.masters[masterName]) 137 continue; 138 139 var master = builders.masters[masterName]; 140 var hasTest = testType in master.tests; 141 var isInGroup = master.groups.indexOf(groupName) != -1; 142 143 if (hasTest && isInGroup) { 144 var builderList = master.tests[testType].builders; 145 var builderFilter = builders._builderFilter(groupName, masterName, testType); 146 if (builderFilter) 147 builderList = builderList.filter(builderFilter); 148 builderGroup.append(builderList); 149 } 150 } 151 152 populateBuilderToMaster(); 153 154 currentBuilderGroup = builderGroup; 155 return currentBuilderGroup; 156 } 157 158 builders.getAllGroupNames = function() 159 { 160 return builders.groups; 161 } 162 163 builders.BuilderMaster = function(name, basePath, tests, groups) 164 { 165 this.name = name; 166 this.basePath = basePath; 167 this.tests = tests; 168 this.groups = groups; 169 } 170 171 builders.BuilderMaster.prototype = { 172 logPath: function(builder, buildNumber) 173 { 174 return this.basePath + '/builders/' + builder + '/builds/' + buildNumber; 175 }, 176 builderJsonPath: function() 177 { 178 return this.basePath + '/json/builders'; 179 }, 180 } 181 182 builders.BuilderGroup = function(isToTBlink) 183 { 184 this.isToTBlink = isToTBlink; 185 // Map of builderName (the name shown in the waterfall) to builderPath (the 186 // path used in the builder's URL) 187 this.builders = {}; 188 } 189 190 builders.BuilderGroup.prototype = { 191 append: function(builders) { 192 builders.forEach(function(builderName) { 193 this.builders[builderName] = builderName.replace(/[ .()]/g, '_'); 194 }, this); 195 }, 196 defaultBuilder: function() 197 { 198 for (var builder in this.builders) 199 return builder; 200 console.error('There are no builders in this builder group.'); 201 }, 202 master: function() 203 { 204 return builders.master(this.defaultBuilder()); 205 }, 206 } 207 208 builders.groupNamesForTestType = function(testType) 209 { 210 var groupNames = []; 211 for (masterName in builders.masters) { 212 var master = builders.masters[masterName]; 213 if (testType in master.tests) { 214 groupNames = groupNames.concat(master.groups); 215 } 216 } 217 218 if (groupNames.length == 0) { 219 console.error("The current test type wasn't present in any groups:", testType); 220 return groupNames; 221 } 222 223 var groupNames = groupNames.reduce(function(prev, curr) { 224 if (prev.indexOf(curr) == -1) { 225 prev.push(curr); 226 } 227 return prev; 228 }, []); 229 230 return groupNames; 231 } 232 233 })(); 234