Home | History | Annotate | Download | only in static-dashboards
      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