Make a builder group support+expect multiple loads.
[WebKit-https.git] / Tools / TestResultServer / static-dashboards / builders.js
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 // @fileoverview File that lists builders, their masters, and logical groupings
30 // of them.
31
32 function BuilderMaster(name, basePath)
33 {
34     this.name = name;
35     this.basePath = basePath;
36 }
37
38 BuilderMaster.prototype.logPath = function(builder, buildNumber)
39 {
40     return this.basePath + 'builders/' + builder + '/builds/' + buildNumber;
41 };
42
43 BuilderMaster.prototype.builderJsonPath = function()
44 {
45     return this.basePath + 'json/builders';
46 };
47
48 CHROMIUM_BUILDER_MASTER = new BuilderMaster('Chromium', 'http://build.chromium.org/p/chromium/');
49 CHROMIUM_WIN_BUILDER_MASTER = new BuilderMaster('ChromiumWin', 'http://build.chromium.org/p/chromium.win/');
50 CHROMIUM_MAC_BUILDER_MASTER = new BuilderMaster('ChromiumMac', 'http://build.chromium.org/p/chromium.mac/');
51 CHROMIUM_LINUX_BUILDER_MASTER = new BuilderMaster('ChromiumLinux', 'http://build.chromium.org/p/chromium.linux/');
52 CHROMIUMOS_BUILDER_MASTER = new BuilderMaster('ChromiumChromiumOS', 'http://build.chromium.org/p/chromium.chromiumos/');
53 CHROMIUM_GPU_BUILDER_MASTER = new BuilderMaster('ChromiumGPU', 'http://build.chromium.org/p/chromium.gpu/');
54 CHROMIUM_GPU_FYI_BUILDER_MASTER = new BuilderMaster('ChromiumGPUFYI', 'http://build.chromium.org/p/chromium.gpu.fyi/');
55 CHROMIUM_WEBKIT_BUILDER_MASTER = new BuilderMaster('ChromiumWebkit', 'http://build.chromium.org/p/chromium.webkit/');
56 WEBKIT_BUILDER_MASTER = new BuilderMaster('webkit.org', 'http://build.webkit.org/');
57
58 var LEGACY_BUILDER_MASTERS_TO_GROUPS = {
59     'Chromium': '@DEPS - chromium.org',
60     'ChromiumChromiumOS': '@DEPS CrOS - chromium.org',
61     'ChromiumGPU': '@DEPS - chromium.org',
62     'ChromiumGPUFYI': '@DEPS FYI - chromium.org',
63     'ChromiumWebkit': '@ToT - chromium.org',
64     'webkit.org': '@ToT - webkit.org'
65 };
66
67 function BuilderGroup(isToTWebKit)
68 {
69     this.isToTWebKit = isToTWebKit;
70     // Map of builderName (the name shown in the waterfall) to builderPath (the
71     // path used in the builder's URL)
72     this.builders = {};
73     this.groups = 0;
74     this.expectedGroups = 0;
75 }
76
77 BuilderGroup.prototype.setbuilder = function(builder, flags) {
78     this.builders[builder] = builder.replace(/[ .()]/g, '_');
79     // FIXME: Remove this at some point, we don't actually use DEFAULT_BUILDER
80     //        in any meaningful way anymore.  We always just default to the
81     //        first builder in alphabetical order.
82     if (flags & BuilderGroup.DEFAULT_BUILDER)
83         this.defaultBuilder = builder;
84 };
85
86 BuilderGroup.prototype.append = function(builders) {
87     builders.forEach(function(builderAndFlags) {
88         var builder = builderAndFlags[0];
89         var flags = builderAndFlags[1];
90         this.setbuilder(builder, flags);
91     }, this);
92     this.groups += 1;
93 };
94
95 BuilderGroup.prototype.loaded = function() {
96     return this.groups >= this.expectedGroups;
97 }
98
99 BuilderGroup.prototype.setup = function()
100 {
101     // FIXME: instead of copying these to globals, it would be better if
102     // the rest of the code read things from the BuilderGroup instance directly
103     g_defaultBuilderName = this.defaultBuilder;
104     g_builders = this.builders;
105 };
106
107 BuilderGroup.TOT_WEBKIT = true;
108 BuilderGroup.DEPS_WEBKIT = false;
109 BuilderGroup.DEFAULT_BUILDER = 1 << 1;
110
111 var BUILDER_TO_MASTER = {};
112 function associateBuildersWithMaster(builders, master)
113 {
114     builders.forEach(function(builderAndFlags) {
115         var builder = builderAndFlags[0];
116         BUILDER_TO_MASTER[builder] = master;
117     });
118 }
119
120 function requestBuilderList(builderGroups, builderFilter, master, groupName, groupEnum, builderGroup)
121 {
122     if (!(groupName in builderGroups))
123         builderGroups[groupName] = builderGroup;
124
125     var onLoad = partial(onBuilderListLoad, builderGroups, builderFilter, master, groupName, groupEnum);
126     var xhr = new XMLHttpRequest();
127     var url = master.builderJsonPath();
128     xhr.open('GET', url, true);
129     xhr.onload = function() {
130         if (xhr.status == 200)
131             onLoad(JSON.parse(xhr.response));
132         else
133             onErrorLoadingBuilderList(url, builderGroups, groupName);
134     };
135     xhr.onerror = function() { onErrorLoadingBuilderList(url, builderGroups, groupName); };
136     xhr.send();
137     builderGroups[groupName].expectedGroups += 1;
138 }
139
140 function isChromiumDepsGpuTestRunner(builder)
141 {
142     return true;
143 }
144
145 function isChromiumDepsFyiGpuTestRunner(builder)
146 {
147     // FIXME: This is kind of wonky, but there's not really a better pattern.
148     return builder.indexOf('(') != -1;
149 }
150
151 function isChromiumTipOfTreeGpuTestRunner(builder)
152 {
153     return builder.indexOf('GPU') != -1;
154 }
155
156 function isWebkitTestRunner(builder)
157 {
158     if (builder.indexOf('Tests') != -1) {
159         // Apple Windows bots still run old-run-webkit-tests, so they don't upload data.
160         return builder.indexOf('Windows') == -1 || (builder.indexOf('Qt') != -1 && builder.indexOf('Chromium') != -1);
161     }
162     return builder.indexOf('GTK') != -1 || builder == 'Qt Linux Release';
163 }
164
165 function isChromiumWebkitTipOfTreeTestRunner(builder)
166 {
167     return builder.indexOf('Webkit') != -1 && builder.indexOf('Builder') == -1 && builder.indexOf('(deps)') == -1 && builder.indexOf('ASAN') == -1;
168 }
169
170 function isChromiumWebkitDepsTestRunner(builder)
171 {
172     return builder.indexOf('Webkit') != -1 && builder.indexOf('Builder') == -1 && builder.indexOf('(deps)') != -1;
173 }
174
175 function isChromiumDepsGTestRunner(builder)
176 {
177     return builder.indexOf('Tests') != -1 && builder.indexOf('Chrome Frame') == -1;
178 }
179
180 function isChromiumDepsCrosGTestRunner(builder)
181 {
182     return builder.indexOf('Tests') != -1;
183 }
184
185 function isChromiumTipOfTreeGTestRunner(builder)
186 {
187     return !isChromiumTipOfTreeGpuTestRunner(builder) && builder.indexOf('Builder') == -1 && builder.indexOf('Perf') == -1 &&
188          builder.indexOf('Webkit') == -1 && builder.indexOf('Valgrind') == -1 && builder.indexOf('Chrome Frame') == -1;
189 }
190
191 function generateBuildersFromBuilderList(builderList, filter)
192 {
193     return builderList.filter(filter).map(function(tester, index) {
194         var builder = [tester];
195         if (!index)
196             builder.push(BuilderGroup.DEFAULT_BUILDER);
197         return builder;
198     });
199 }
200
201 function onBuilderListLoad(builderGroups, builderFilter, master, groupName, groupEnum, json)
202 {
203     var builders = generateBuildersFromBuilderList(Object.keys(json), builderFilter);
204     associateBuildersWithMaster(builders, master);
205     builderGroups[groupName].append(builders);
206     if (builderGroups[groupName].loaded())
207         g_handleBuildersListLoaded();
208 }
209
210 function onErrorLoadingBuilderList(url, builderGroups, groupName)
211 {
212     builderGroups[groupName].groups += 1;
213     console.log('Could not load list of builders from ' + url + '. Try reloading.');
214 }
215
216 function loadBuildersList(groupName, testType) {
217     if (testType == 'gpu_tests') {
218         switch(groupName) {
219         case '@DEPS - chromium.org':
220             var builderGroup = new BuilderGroup(BuilderGroup.DEPS_WEBKIT);
221             requestBuilderList(CHROMIUM_GPU_TESTS_BUILDER_GROUPS, isChromiumDepsGpuTestRunner, CHROMIUM_GPU_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
222             break;
223
224         case '@DEPS FYI - chromium.org':
225             var builderGroup = new BuilderGroup(BuilderGroup.DEPS_WEBKIT);
226             requestBuilderList(CHROMIUM_GPU_TESTS_BUILDER_GROUPS, isChromiumDepsFyiGpuTestRunner, CHROMIUM_GPU_FYI_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
227             break;
228
229         case '@ToT - chromium.org':
230             var builderGroup = new BuilderGroup(BuilderGroup.TOT_WEBKIT);
231             requestBuilderList(CHROMIUM_GPU_TESTS_BUILDER_GROUPS, isChromiumTipOfTreeGpuTestRunner, CHROMIUM_WEBKIT_BUILDER_MASTER, groupName, BuilderGroup.TOT_WEBKIT, builderGroup);
232             break;
233         }
234     } else if (testType == 'layout-tests') {
235         switch(groupName) {
236         case '@ToT - chromium.org':
237             var builderGroup = new BuilderGroup(BuilderGroup.TOT_WEBKIT);
238             requestBuilderList(LAYOUT_TESTS_BUILDER_GROUPS, isChromiumWebkitTipOfTreeTestRunner, CHROMIUM_WEBKIT_BUILDER_MASTER, groupName, BuilderGroup.TOT_WEBKIT, builderGroup);
239             break;
240
241         case '@ToT - webkit.org':
242             var builderGroup = new BuilderGroup(BuilderGroup.TOT_WEBKIT);
243             requestBuilderList(LAYOUT_TESTS_BUILDER_GROUPS, isWebkitTestRunner, WEBKIT_BUILDER_MASTER, groupName, BuilderGroup.TOT_WEBKIT, builderGroup);
244             break;
245
246         case '@DEPS - chromium.org':
247             var builderGroup = new BuilderGroup(BuilderGroup.DEPS_WEBKIT);
248             requestBuilderList(LAYOUT_TESTS_BUILDER_GROUPS, isChromiumWebkitDepsTestRunner, CHROMIUM_WEBKIT_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
249             break;
250         }
251     } else {
252         switch(groupName) {
253         case '@DEPS - chromium.org':
254             var builderGroup = new BuilderGroup(BuilderGroup.DEPS_WEBKIT);
255             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumDepsGTestRunner, CHROMIUM_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
256             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumDepsGTestRunner, CHROMIUM_WIN_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
257             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumDepsGTestRunner, CHROMIUM_MAC_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
258             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumDepsGTestRunner, CHROMIUM_LINUX_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
259             break;
260
261         case '@DEPS CrOS - chromium.org':
262             var builderGroup = new BuilderGroup(BuilderGroup.DEPS_WEBKIT);
263             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumDepsCrosGTestRunner, CHROMIUMOS_BUILDER_MASTER, groupName, BuilderGroup.DEPS_WEBKIT, builderGroup);
264             break;
265
266         case '@ToT - chromium.org':
267             var builderGroup = new BuilderGroup(BuilderGroup.TOT_WEBKIT);
268             requestBuilderList(CHROMIUM_GTESTS_BUILDER_GROUPS, isChromiumTipOfTreeGTestRunner, CHROMIUM_WEBKIT_BUILDER_MASTER, groupName, BuilderGroup.TOT_WEBKIT, builderGroup);
269             break;
270         }
271     }
272 }
273
274 var LAYOUT_TESTS_BUILDER_GROUPS = {
275     '@ToT - chromium.org': null,
276     '@ToT - webkit.org': null,
277     '@DEPS - chromium.org': null,
278 };
279
280 var CHROMIUM_GPU_TESTS_BUILDER_GROUPS = {
281     '@DEPS - chromium.org': null,
282     '@DEPS FYI - chromium.org': null,
283     '@ToT - chromium.org': null,
284 };
285
286 var CHROMIUM_GTESTS_BUILDER_GROUPS = {
287     '@DEPS - chromium.org': null,
288     '@DEPS CrOS - chromium.org': null,
289     '@ToT - chromium.org': null,
290 };