f3c58ff43a92eaffcc6149236f71f7b7a087485f
[WebKit-https.git] / Tools / TestResultServer / static-dashboards / flakiness_dashboard_unittests.js
1 // Copyright (C) 2011 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 resetGlobals()
30 {
31     allExpectations = null;
32     allTests = null;
33     g_expectationsByPlatform = {};
34     g_resultsByBuilder = {};
35     g_allExpectations = null;
36     g_allTestsTrie = null;
37     g_currentState = {};
38     g_crossDashboardState = {};
39     g_testToResultsMap = {};
40
41     for (var key in g_defaultCrossDashboardStateValues)
42         g_crossDashboardState[key] = g_defaultCrossDashboardStateValues[key];
43
44     LOAD_BUILDBOT_DATA([{
45         name: 'ChromiumWebkit',
46         url: 'dummyurl', 
47         tests: {'layout-tests': {'builders': ['WebKit Linux', 'WebKit Linux (dbg)', 'WebKit Mac10.7', 'WebKit Win', 'WebKit Win (dbg)']}}
48     },
49     {
50         name: 'webkit.org',
51         url: 'dummyurl',
52         tests: {'layout-tests': {'builders': ['Apple SnowLeopard Tests', 'Qt Linux Tests', 'Chromium Mac10.7 Tests', 'GTK Win']}}
53     }]);
54  
55     for (var group in LAYOUT_TESTS_BUILDER_GROUPS)
56         LAYOUT_TESTS_BUILDER_GROUPS[group] = null;
57 }
58
59 function stubResultsByBuilder(data)
60 {
61     for (var builder in currentBuilders())
62     {
63         g_resultsByBuilder[builder] = data[builder] || {'tests': []};
64     };
65 }
66
67 function runExpectationsTest(builder, test, expectations, modifiers)
68 {
69     // Put in some dummy results. processExpectations expects the test to be
70     // there.
71     var tests = {};
72     tests[test] = {'results': [[100, 'F']], 'times': [[100, 0]]};
73     var results = {};
74     results[builder] = {'tests': tests};
75     stubResultsByBuilder(results);
76
77     processExpectations();
78     var resultsForTest = createResultsObjectForTest(test, builder);
79     populateExpectationsData(resultsForTest);
80
81     var message = 'Builder: ' + resultsForTest.builder + ' test: ' + resultsForTest.test;
82     equal(resultsForTest.expectations, expectations, message);
83     equal(resultsForTest.modifiers, modifiers, message);
84 }
85
86 test('flattenTrie', 1, function() {
87     resetGlobals();
88     var tests = {
89         'bar.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
90         'foo': {
91             'bar': {
92                 'baz.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
93             }
94         }
95     };
96     var expectedFlattenedTests = {
97         'bar.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
98         'foo/bar/baz.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
99     };
100     equal(JSON.stringify(flattenTrie(tests)), JSON.stringify(expectedFlattenedTests))
101 });
102
103 test('releaseFail', 2, function() {
104     resetGlobals();
105     loadBuildersList('@ToT - chromium.org', 'layout-tests');
106
107     var builder = 'WebKit Win';
108     var test = 'foo/1.html';
109     var expectationsArray = [
110         {'modifiers': 'RELEASE', 'expectations': 'FAIL'}
111     ];
112     g_expectationsByPlatform['CHROMIUM'] = getParsedExpectations('[ Release ] ' + test + ' [ Failure ]');
113     runExpectationsTest(builder, test, 'FAIL', 'RELEASE');
114 });
115
116 test('releaseFailDebugCrashReleaseBuilder', 2, function() {
117     resetGlobals();
118     loadBuildersList('@ToT - chromium.org', 'layout-tests');
119     var builder = 'WebKit Win';
120     var test = 'foo/1.html';
121     var expectationsArray = [
122         {'modifiers': 'RELEASE', 'expectations': 'FAIL'},
123         {'modifiers': 'DEBUG', 'expectations': 'CRASH'}
124     ];
125     g_expectationsByPlatform['CHROMIUM'] = getParsedExpectations('[ Release ] ' + test + ' [ Failure ]\n' +
126         '[ Debug ] ' + test + ' [ Crash ]');
127     runExpectationsTest(builder, test, 'FAIL', 'RELEASE');
128 });
129
130 test('releaseFailDebugCrashDebugBuilder', 2, function() {
131     resetGlobals();
132     loadBuildersList('@ToT - chromium.org', 'layout-tests');
133     var builder = 'WebKit Win (dbg)';
134     var test = 'foo/1.html';
135     var expectationsArray = [
136         {'modifiers': 'RELEASE', 'expectations': 'FAIL'},
137         {'modifiers': 'DEBUG', 'expectations': 'CRASH'}
138     ];
139     g_expectationsByPlatform['CHROMIUM'] = getParsedExpectations('[ Release ] ' + test + ' [ Failure ]\n' +
140         '[ Debug ] ' + test + ' [ Crash ]');
141     runExpectationsTest(builder, test, 'CRASH', 'DEBUG');
142 });
143
144 test('overrideJustBuildType', 12, function() {
145     resetGlobals();
146     loadBuildersList('@ToT - chromium.org', 'layout-tests');
147     var test = 'bar/1.html';
148     g_expectationsByPlatform['CHROMIUM'] = getParsedExpectations('bar [ WontFix Failure Pass Timeout ]\n' +
149         '[ Mac ] ' + test + ' [ WontFix Failure ]\n' +
150         '[ Linux Debug ] ' + test + ' [ Crash ]');
151     
152     runExpectationsTest('WebKit Win', test, 'FAIL PASS TIMEOUT', 'WONTFIX');
153     runExpectationsTest('WebKit Win (dbg)(3)', test, 'FAIL PASS TIMEOUT', 'WONTFIX');
154     runExpectationsTest('WebKit Linux', test, 'FAIL PASS TIMEOUT', 'WONTFIX');
155     runExpectationsTest('WebKit Linux (dbg)(3)', test, 'CRASH', 'LINUX DEBUG');
156     runExpectationsTest('WebKit Mac10.7', test, 'FAIL', 'MAC WONTFIX');
157     runExpectationsTest('WebKit Mac10.7 (dbg)(3)', test, 'FAIL', 'MAC WONTFIX');
158 });
159
160 test('platformAndBuildType', 78, function() {
161     var runPlatformAndBuildTypeTest = function(builder, expectedPlatform, expectedBuildType) {
162         g_perBuilderPlatformAndBuildType = {};
163         buildInfo = platformAndBuildType(builder);
164         var message = 'Builder: ' + builder;
165         equal(buildInfo.platform, expectedPlatform, message);
166         equal(buildInfo.buildType, expectedBuildType, message);
167     }
168     runPlatformAndBuildTypeTest('WebKit Win (deps)', 'CHROMIUM_XP', 'RELEASE');
169     runPlatformAndBuildTypeTest('WebKit Win (deps)(dbg)(1)', 'CHROMIUM_XP', 'DEBUG');
170     runPlatformAndBuildTypeTest('WebKit Win (deps)(dbg)(2)', 'CHROMIUM_XP', 'DEBUG');
171     runPlatformAndBuildTypeTest('WebKit Linux (deps)', 'CHROMIUM_LUCID', 'RELEASE');
172     runPlatformAndBuildTypeTest('WebKit Linux (deps)(dbg)(1)', 'CHROMIUM_LUCID', 'DEBUG');
173     runPlatformAndBuildTypeTest('WebKit Linux (deps)(dbg)(2)', 'CHROMIUM_LUCID', 'DEBUG');
174     runPlatformAndBuildTypeTest('WebKit Mac10.6 (deps)', 'CHROMIUM_SNOWLEOPARD', 'RELEASE');
175     runPlatformAndBuildTypeTest('WebKit Mac10.6 (deps)(dbg)(1)', 'CHROMIUM_SNOWLEOPARD', 'DEBUG');
176     runPlatformAndBuildTypeTest('WebKit Mac10.6 (deps)(dbg)(2)', 'CHROMIUM_SNOWLEOPARD', 'DEBUG');
177     runPlatformAndBuildTypeTest('WebKit Win', 'CHROMIUM_XP', 'RELEASE');
178     runPlatformAndBuildTypeTest('WebKit Win7', 'CHROMIUM_WIN7', 'RELEASE');
179     runPlatformAndBuildTypeTest('WebKit Win (dbg)(1)', 'CHROMIUM_XP', 'DEBUG');
180     runPlatformAndBuildTypeTest('WebKit Win (dbg)(2)', 'CHROMIUM_XP', 'DEBUG');
181     runPlatformAndBuildTypeTest('WebKit Linux', 'CHROMIUM_LUCID', 'RELEASE');
182     runPlatformAndBuildTypeTest('WebKit Linux 32', 'CHROMIUM_LUCID', 'RELEASE');
183     runPlatformAndBuildTypeTest('WebKit Linux (dbg)(1)', 'CHROMIUM_LUCID', 'DEBUG');
184     runPlatformAndBuildTypeTest('WebKit Linux (dbg)(2)', 'CHROMIUM_LUCID', 'DEBUG');
185     runPlatformAndBuildTypeTest('WebKit Mac10.6', 'CHROMIUM_SNOWLEOPARD', 'RELEASE');
186     runPlatformAndBuildTypeTest('WebKit Mac10.6 (dbg)', 'CHROMIUM_SNOWLEOPARD', 'DEBUG');
187     runPlatformAndBuildTypeTest('XP Tests', 'CHROMIUM_XP', 'RELEASE');
188     runPlatformAndBuildTypeTest('Interactive Tests (dbg)', 'CHROMIUM_XP', 'DEBUG');
189     
190     g_crossDashboardState.group = '@ToT - webkit.org';
191     g_crossDashboardState.testType = 'layout-tests';
192     runPlatformAndBuildTypeTest('Chromium Win Release (Tests)', 'CHROMIUM_XP', 'RELEASE');
193     runPlatformAndBuildTypeTest('Chromium Linux Release (Tests)', 'CHROMIUM_LUCID', 'RELEASE');
194     runPlatformAndBuildTypeTest('Chromium Mac Release (Tests)', 'CHROMIUM_SNOWLEOPARD', 'RELEASE');
195     
196     // FIXME: These platforms should match whatever we use in the TestExpectations format.
197     runPlatformAndBuildTypeTest('Lion Release (Tests)', 'APPLE_MAC_LION_WK1', 'RELEASE');
198     runPlatformAndBuildTypeTest('Lion Debug (Tests)', 'APPLE_MAC_LION_WK1', 'DEBUG');
199     runPlatformAndBuildTypeTest('SnowLeopard Intel Release (Tests)', 'APPLE_MAC_SNOWLEOPARD_WK1', 'RELEASE');
200     runPlatformAndBuildTypeTest('SnowLeopard Intel Leaks', 'APPLE_MAC_SNOWLEOPARD_WK1', 'RELEASE');
201     runPlatformAndBuildTypeTest('SnowLeopard Intel Debug (Tests)', 'APPLE_MAC_SNOWLEOPARD_WK1', 'DEBUG');
202     runPlatformAndBuildTypeTest('GTK Linux 32-bit Release', 'GTK_LINUX_WK1', 'RELEASE');
203     runPlatformAndBuildTypeTest('GTK Linux 32-bit Debug', 'GTK_LINUX_WK1', 'DEBUG');
204     runPlatformAndBuildTypeTest('GTK Linux 64-bit Debug', 'GTK_LINUX_WK1', 'DEBUG');
205     runPlatformAndBuildTypeTest('GTK Linux 64-bit Debug WK2', 'GTK_LINUX_WK2', 'DEBUG');
206     runPlatformAndBuildTypeTest('Qt Linux Release', 'QT_LINUX', 'RELEASE');
207     runPlatformAndBuildTypeTest('Windows 7 Release (Tests)', 'APPLE_WIN_WIN7', 'RELEASE');
208     runPlatformAndBuildTypeTest('Windows XP Debug (Tests)', 'APPLE_WIN_XP', 'DEBUG');
209     
210     // FIXME: Should WebKit2 be it's own platform?
211     runPlatformAndBuildTypeTest('SnowLeopard Intel Release (WebKit2 Tests)', 'APPLE_MAC_SNOWLEOPARD_WK2', 'RELEASE');
212     runPlatformAndBuildTypeTest('SnowLeopard Intel Debug (WebKit2 Tests)', 'APPLE_MAC_SNOWLEOPARD_WK2', 'DEBUG');
213     runPlatformAndBuildTypeTest('Windows 7 Release (WebKit2 Tests)', 'APPLE_WIN_WIN7', 'RELEASE');    
214 });
215
216 test('realModifiers', 3, function() {
217     equal(realModifiers('BUG(Foo) LINUX LION WIN DEBUG SLOW'), 'SLOW');
218     equal(realModifiers('BUG(Foo) LUCID MAC XP RELEASE SKIP'), 'SKIP');
219     equal(realModifiers('BUG(Foo)'), '');
220 });
221
222 test('allTestsWithSamePlatformAndBuildType', 1, function() {
223     // FIXME: test that allTestsWithSamePlatformAndBuildType actually returns the right set of tests.
224     var expectedPlatformsList = ['CHROMIUM_LION', 'CHROMIUM_SNOWLEOPARD', 'CHROMIUM_XP', 'CHROMIUM_VISTA', 'CHROMIUM_WIN7', 'CHROMIUM_LUCID',
225                                  'CHROMIUM_ANDROID', 'APPLE_MAC_LION_WK1', 'APPLE_MAC_LION_WK2', 'APPLE_MAC_SNOWLEOPARD_WK1', 'APPLE_MAC_SNOWLEOPARD_WK2',
226                                  'APPLE_WIN_XP', 'APPLE_WIN_WIN7',  'GTK_LINUX_WK1', 'GTK_LINUX_WK2', 'QT_LINUX', 'EFL_LINUX_WK1', 'EFL_LINUX_WK2'];
227     var actualPlatformsList = Object.keys(g_allTestsByPlatformAndBuildType);
228     deepEqual(expectedPlatformsList, actualPlatformsList);
229 });
230
231 test('filterBugs',4, function() {
232     var filtered = filterBugs('Skip crbug.com/123 webkit.org/b/123 Slow Bug(Tony) Debug')
233     equal(filtered.modifiers, 'Skip Slow Debug');
234     equal(filtered.bugs, 'crbug.com/123 webkit.org/b/123 Bug(Tony)');
235
236     filtered = filterBugs('Skip Slow Debug')
237     equal(filtered.modifiers, 'Skip Slow Debug');
238     equal(filtered.bugs, '');
239 });
240
241 test('getExpectations', 16, function() {
242     resetGlobals();
243     loadBuildersList('@ToT - chromium.org', 'layout-tests');
244  
245     stubResultsByBuilder({
246         'WebKit Win' : {
247             'tests': {
248                 'foo/test1.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
249                 'foo/test2.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
250                 'foo/test3.html': {'results': [[100, 'F']], 'times': [[100, 0]]},
251                 'test1.html': {'results': [[100, 'F']], 'times': [[100, 0]]}
252             }
253         }
254     });
255
256     g_expectationsByPlatform['CHROMIUM'] = getParsedExpectations('Bug(123) foo [ Failure Pass Crash ]\n' +
257         'Bug(Foo) [ Release ] foo/test1.html [ Failure ]\n' +
258         '[ Debug ] foo/test1.html [ Crash ]\n' +
259         'Bug(456) foo/test2.html [ Failure ]\n' +
260         '[ Linux Debug ] foo/test2.html [ Crash ]\n' +
261         '[ Release ] test1.html [ Failure ]\n' +
262         '[ Debug ] test1.html [ Crash ]\n');
263     g_expectationsByPlatform['CHROMIUM_ANDROID'] = getParsedExpectations('Bug(654) foo/test2.html [ Crash ]\n');
264
265     g_expectationsByPlatform['GTK'] = getParsedExpectations('Bug(42) foo/test2.html [ ImageOnlyFailure ]\n' +
266         '[ Debug ] test1.html [ Crash ]\n');
267     g_expectationsByPlatform['GTK_LINUX_WK1'] = getParsedExpectations('[ Release ] foo/test1.html [ ImageOnlyFailure ]\n' +
268         'Bug(789) foo/test2.html [ Crash ]\n');
269     g_expectationsByPlatform['GTK_LINUX_WK2'] = getParsedExpectations('Bug(987) foo/test2.html [ Failure ]\n');
270
271     processExpectations();
272     
273     var expectations = getExpectations('foo/test1.html', 'CHROMIUM_XP', 'DEBUG');
274     equal(JSON.stringify(expectations), '{"modifiers":"DEBUG","expectations":"CRASH"}');
275
276     var expectations = getExpectations('foo/test1.html', 'CHROMIUM_LUCID', 'RELEASE');
277     equal(JSON.stringify(expectations), '{"modifiers":"Bug(Foo) RELEASE","expectations":"FAIL"}');
278
279     var expectations = getExpectations('foo/test2.html', 'CHROMIUM_LUCID', 'RELEASE');
280     equal(JSON.stringify(expectations), '{"modifiers":"Bug(456)","expectations":"FAIL"}');
281
282     var expectations = getExpectations('foo/test2.html', 'CHROMIUM_LION', 'DEBUG');
283     equal(JSON.stringify(expectations), '{"modifiers":"Bug(456)","expectations":"FAIL"}');
284
285     var expectations = getExpectations('foo/test2.html', 'CHROMIUM_LUCID', 'DEBUG');
286     equal(JSON.stringify(expectations), '{"modifiers":"LINUX DEBUG","expectations":"CRASH"}');
287
288     var expectations = getExpectations('foo/test2.html', 'CHROMIUM_ANDROID', 'RELEASE');
289     equal(JSON.stringify(expectations), '{"modifiers":"Bug(654)","expectations":"CRASH"}');
290
291     var expectations = getExpectations('test1.html', 'CHROMIUM_ANDROID', 'RELEASE');
292     equal(JSON.stringify(expectations), '{"modifiers":"RELEASE","expectations":"FAIL"}');
293
294     var expectations = getExpectations('foo/test3.html', 'CHROMIUM_LUCID', 'DEBUG');
295     equal(JSON.stringify(expectations), '{"modifiers":"Bug(123)","expectations":"FAIL PASS CRASH"}');
296
297     var expectations = getExpectations('test1.html', 'CHROMIUM_XP', 'DEBUG');
298     equal(JSON.stringify(expectations), '{"modifiers":"DEBUG","expectations":"CRASH"}');
299
300     var expectations = getExpectations('test1.html', 'CHROMIUM_LUCID', 'RELEASE');
301     equal(JSON.stringify(expectations), '{"modifiers":"RELEASE","expectations":"FAIL"}');
302
303     var expectations = getExpectations('foo/test1.html', 'GTK_LINUX_WK1', 'RELEASE');
304     equal(JSON.stringify(expectations), '{"modifiers":"RELEASE","expectations":"IMAGE"}');
305
306     var expectations = getExpectations('foo/test2.html', 'GTK_LINUX_WK1', 'DEBUG');
307     equal(JSON.stringify(expectations), '{"modifiers":"Bug(789)","expectations":"CRASH"}');
308
309     var expectations = getExpectations('test1.html', 'GTK_LINUX_WK1', 'DEBUG');
310     equal(JSON.stringify(expectations), '{"modifiers":"DEBUG","expectations":"CRASH"}');
311
312     var expectations = getExpectations('foo/test2.html', 'GTK_LINUX_WK2', 'DEBUG');
313     equal(JSON.stringify(expectations), '{"modifiers":"Bug(987)","expectations":"FAIL"}');
314
315     var expectations = getExpectations('foo/test2.html', 'GTK_LINUX_WK2', 'RELEASE');
316     equal(JSON.stringify(expectations), '{"modifiers":"Bug(987)","expectations":"FAIL"}');
317
318     var expectations = getExpectations('test1.html', 'GTK_LINUX_WK2', 'DEBUG');
319     equal(JSON.stringify(expectations), '{"modifiers":"DEBUG","expectations":"CRASH"}');
320 });
321
322 test('substringList', 2, function() {
323     g_crossDashboardState.testType = 'gtest';
324     g_currentState.tests = 'test.FLAKY_foo test.FAILS_foo1 test.DISABLED_foo2 test.MAYBE_foo3 test.foo4';
325     equal(substringList().toString(), 'test.foo,test.foo1,test.foo2,test.foo3,test.foo4');
326
327     g_crossDashboardState.testType = 'layout-tests';
328     g_currentState.tests = 'foo/bar.FLAKY_foo.html';
329     equal(substringList().toString(), 'foo/bar.FLAKY_foo.html');
330 });
331
332 test('htmlForTestsWithExpectationsButNoFailures', 4, function() {
333     loadBuildersList('@ToT - chromium.org', 'layout-tests');
334     var builder = 'WebKit Win';
335     g_perBuilderWithExpectationsButNoFailures[builder] = ['passing-test1.html', 'passing-test2.html'];
336     g_perBuilderSkippedPaths[builder] = ['skipped-test1.html'];
337     g_resultsByBuilder[builder] = { buildNumbers: [5, 4, 3, 1] };
338
339     g_currentState.showUnexpectedPasses = true;
340     g_currentState.showSkipped = true;
341
342     g_crossDashboardState.group = '@ToT - chromium.org';
343     g_crossDashboardState.testType = 'layout-tests';
344     
345     var container = document.createElement('div');
346     container.innerHTML = htmlForTestsWithExpectationsButNoFailures(builder);
347     equal(container.querySelectorAll('#passing-tests > div').length, 2);
348     equal(container.querySelectorAll('#skipped-tests > div').length, 1);
349     
350     g_currentState.showUnexpectedPasses = false;
351     g_currentState.showSkipped = false;
352     
353     var container = document.createElement('div');
354     container.innerHTML = htmlForTestsWithExpectationsButNoFailures(builder);
355     equal(container.querySelectorAll('#passing-tests > div').length, 0);
356     equal(container.querySelectorAll('#skipped-tests > div').length, 0);
357 });
358
359 test('headerForTestTableHtml', 1, function() {
360     var container = document.createElement('div');
361     container.innerHTML = headerForTestTableHtml();
362     equal(container.querySelectorAll('input').length, 5);
363 });
364
365 test('htmlForTestTypeSwitcherGroup', 6, function() {
366     var container = document.createElement('div');
367     g_crossDashboardState.testType = 'ui_tests';
368     container.innerHTML = ui.html.testTypeSwitcher(true);
369     var selects = container.querySelectorAll('select');
370     equal(selects.length, 2);
371     var group = selects[1];
372     equal(group.parentNode.textContent.indexOf('Group:'), 0);
373     equal(group.children.length, 3);
374
375     g_crossDashboardState.testType = 'layout-tests';
376     container.innerHTML = ui.html.testTypeSwitcher(true);
377     var selects = container.querySelectorAll('select');
378     equal(selects.length, 2);
379     var group = selects[1];
380     equal(group.parentNode.textContent.indexOf('Group:'), 0);
381     equal(group.children.length, 4);
382 });
383
384 test('htmlForIndividualTestOnAllBuilders', 1, function() {
385     resetGlobals();
386     loadBuildersList('@ToT - chromium.org', 'layout-tests');
387     equal(htmlForIndividualTestOnAllBuilders('foo/nonexistant.html'), '<div class="not-found">Test not found. Either it does not exist, is skipped or passes on all platforms.</div>');
388 });
389
390 test('htmlForIndividualTestOnAllBuildersWithResultsLinksNonexistant', 1, function() {
391     resetGlobals();
392     loadBuildersList('@ToT - chromium.org', 'layout-tests');
393     equal(htmlForIndividualTestOnAllBuildersWithResultsLinks('foo/nonexistant.html'),
394         '<div class="not-found">Test not found. Either it does not exist, is skipped or passes on all platforms.</div>' +
395         '<div class=expectations test=foo/nonexistant.html>' +
396             '<div>' +
397                 '<span class=link onclick="setQueryParameter(\'showExpectations\', true)">Show results</span> | ' +
398                 '<span class=link onclick="setQueryParameter(\'showLargeExpectations\', true)">Show large thumbnails</span> | ' +
399                 '<b>Only shows actual results/diffs from the most recent *failure* on each bot.</b>' +
400             '</div>' +
401         '</div>');
402 });
403
404 test('htmlForIndividualTestOnAllBuildersWithResultsLinks', 1, function() {
405     resetGlobals();
406     loadBuildersList('@ToT - chromium.org', 'layout-tests');
407
408     var builderName = 'WebKit Linux';
409     var test = 'dummytest.html';
410     g_testToResultsMap[test] = [createResultsObjectForTest(test, builderName)];
411
412     equal(htmlForIndividualTestOnAllBuildersWithResultsLinks(test),
413         '<table class=test-table><thead><tr>' +
414                 '<th sortValue=test><div class=table-header-content><span></span><span class=header-text>test</span></div></th>' +
415                 '<th sortValue=bugs><div class=table-header-content><span></span><span class=header-text>bugs</span></div></th>' +
416                 '<th sortValue=modifiers><div class=table-header-content><span></span><span class=header-text>modifiers</span></div></th>' +
417                 '<th sortValue=expectations><div class=table-header-content><span></span><span class=header-text>expectations</span></div></th>' +
418                 '<th sortValue=slowest><div class=table-header-content><span></span><span class=header-text>slowest run</span></div></th>' +
419                 '<th sortValue=flakiness colspan=10000><div class=table-header-content><span></span><span class=header-text>flakiness (numbers are runtimes in seconds)</span></div></th>' +
420             '</tr></thead>' +
421             '<tbody></tbody>' +
422         '</table>' +
423         '<div>The following builders either don\'t run this test (e.g. it\'s skipped) or all runs passed:</div>' +
424         '<div class=skipped-builder-list>' +
425             '<div class=skipped-builder>WebKit Linux (dbg)</div><div class=skipped-builder>WebKit Mac10.7</div><div class=skipped-builder>WebKit Win</div><div class=skipped-builder>WebKit Win (dbg)</div>' +
426         '</div>' +
427         '<div class=expectations test=dummytest.html>' +
428             '<div><span class=link onclick="setQueryParameter(\'showExpectations\', true)">Show results</span> | ' +
429             '<span class=link onclick="setQueryParameter(\'showLargeExpectations\', true)">Show large thumbnails</span> | ' +
430             '<b>Only shows actual results/diffs from the most recent *failure* on each bot.</b></div>' +
431         '</div>');
432 });
433
434 test('htmlForIndividualTestOnAllBuildersWithResultsLinksWebkitMaster', 1, function() {
435     resetGlobals();
436     g_crossDashboardState.group = '@ToT - webkit.org';
437     loadBuildersList('@ToT - webkit.org', 'layout-tests');
438
439     var builderName = 'Apple SnowLeopard Tests';
440     var test = 'dummytest.html';
441     g_testToResultsMap[test] = [createResultsObjectForTest(test, builderName)];
442
443     equal(htmlForIndividualTestOnAllBuildersWithResultsLinks(test),
444         '<table class=test-table><thead><tr>' +
445                 '<th sortValue=test><div class=table-header-content><span></span><span class=header-text>test</span></div></th>' +
446                 '<th sortValue=bugs><div class=table-header-content><span></span><span class=header-text>bugs</span></div></th>' +
447                 '<th sortValue=modifiers><div class=table-header-content><span></span><span class=header-text>modifiers</span></div></th>' +
448                 '<th sortValue=expectations><div class=table-header-content><span></span><span class=header-text>expectations</span></div></th>' +
449                 '<th sortValue=slowest><div class=table-header-content><span></span><span class=header-text>slowest run</span></div></th>' +
450                 '<th sortValue=flakiness colspan=10000><div class=table-header-content><span></span><span class=header-text>flakiness (numbers are runtimes in seconds)</span></div></th>' +
451             '</tr></thead>' +
452             '<tbody></tbody>' +
453         '</table>' +
454         '<div>The following builders either don\'t run this test (e.g. it\'s skipped) or all runs passed:</div>' +
455         '<div class=skipped-builder-list>' +
456             '<div class=skipped-builder>Qt Linux Tests</div><div class=skipped-builder>Chromium Mac10.7 Tests</div><div class=skipped-builder>GTK Win</div>' +
457         '</div>' +
458         '<div class=expectations test=dummytest.html>' +
459             '<div><span class=link onclick="setQueryParameter(\'showExpectations\', true)">Show results</span> | ' +
460             '<span class=link onclick="setQueryParameter(\'showLargeExpectations\', true)">Show large thumbnails</span>' +
461             '<form onsubmit="setQueryParameter(\'revision\', revision.value);return false;">' +
462                 'Show results for WebKit revision: <input name=revision placeholder="e.g. 65540" value="" id=revision-input>' +
463             '</form></div>' +
464         '</div>');
465 });
466
467 test('htmlForIndividualTests', 4, function() {
468     resetGlobals();
469     loadBuildersList('@ToT - chromium.org', 'layout-tests');
470     var test1 = 'foo/nonexistant.html';
471     var test2 = 'bar/nonexistant.html';
472
473     g_currentState.showChrome = false;
474
475     var tests = [test1, test2];
476     equal(htmlForIndividualTests(tests),
477         '<h2><a href="http://trac.webkit.org/browser/trunk/LayoutTests/foo/nonexistant.html" target="_blank">foo/nonexistant.html</a></h2>' +
478         htmlForIndividualTestOnAllBuilders(test1) + 
479         '<div class=expectations test=foo/nonexistant.html>' +
480             '<div><span class=link onclick=\"setQueryParameter(\'showExpectations\', true)\">Show results</span> | ' +
481             '<span class=link onclick=\"setQueryParameter(\'showLargeExpectations\', true)\">Show large thumbnails</span> | ' +
482             '<b>Only shows actual results/diffs from the most recent *failure* on each bot.</b></div>' +
483         '</div>' +
484         '<hr>' +
485         '<h2><a href="http://trac.webkit.org/browser/trunk/LayoutTests/bar/nonexistant.html" target="_blank">bar/nonexistant.html</a></h2>' +
486         htmlForIndividualTestOnAllBuilders(test2) +
487         '<div class=expectations test=bar/nonexistant.html>' +
488             '<div><span class=link onclick=\"setQueryParameter(\'showExpectations\', true)\">Show results</span> | ' +
489             '<span class=link onclick=\"setQueryParameter(\'showLargeExpectations\', true)\">Show large thumbnails</span> | ' +
490             '<b>Only shows actual results/diffs from the most recent *failure* on each bot.</b></div>' +
491         '</div>');
492
493     tests = [test1];
494     equal(htmlForIndividualTests(tests), htmlForIndividualTestOnAllBuilders(test1) +
495         '<div class=expectations test=foo/nonexistant.html>' +
496             '<div><span class=link onclick=\"setQueryParameter(\'showExpectations\', true)\">Show results</span> | ' +
497             '<span class=link onclick=\"setQueryParameter(\'showLargeExpectations\', true)\">Show large thumbnails</span> | ' +
498             '<b>Only shows actual results/diffs from the most recent *failure* on each bot.</b></div>' +
499         '</div>');
500
501     g_currentState.showChrome = true;
502
503     equal(htmlForIndividualTests(tests),
504         '<h2><a href="http://trac.webkit.org/browser/trunk/LayoutTests/foo/nonexistant.html" target="_blank">foo/nonexistant.html</a></h2>' +
505         htmlForIndividualTestOnAllBuildersWithResultsLinks(test1));
506
507     tests = [test1, test2];
508     equal(htmlForIndividualTests(tests),
509         '<h2><a href="http://trac.webkit.org/browser/trunk/LayoutTests/foo/nonexistant.html" target="_blank">foo/nonexistant.html</a></h2>' +
510         htmlForIndividualTestOnAllBuildersWithResultsLinks(test1) + '<hr>' +
511         '<h2><a href="http://trac.webkit.org/browser/trunk/LayoutTests/bar/nonexistant.html" target="_blank">bar/nonexistant.html</a></h2>' +
512         htmlForIndividualTestOnAllBuildersWithResultsLinks(test2));
513 });
514
515 test('htmlForSingleTestRow', 1, function() {
516     resetGlobals();
517     var builder = 'dummyBuilder';
518     BUILDER_TO_MASTER[builder] = CHROMIUM_WEBKIT_BUILDER_MASTER;
519     var test = createResultsObjectForTest('foo/exists.html', builder);
520     g_currentState.showCorrectExpectations = true;
521     g_resultsByBuilder[builder] = {buildNumbers: [2, 1], webkitRevision: [1234, 1233]};
522     test.rawResults = [[1, 'F'], [2, 'I']];
523     test.rawTimes = [[1, 0], [2, 5]];
524     var expected = '<tr>' +
525         '<td class="test-link"><span class="link" onclick="setQueryParameter(\'tests\',\'foo/exists.html\');">foo/exists.html</span>' +
526         '<td class=options-container><a href="https://bugs.webkit.org/enter_bug.cgi?assigned_to=webkit-unassigned%40lists.webkit.org&product=WebKit&form_name=enter_bug&component=Tools%20%2F%20Tests&short_desc=Layout%20Test%20foo%2Fexists.html%20is%20failing&comment=The%20following%20layout%20test%20is%20failing%20on%20%5Binsert%20platform%5D%0A%0Afoo%2Fexists.html%0A%0AProbable%20cause%3A%0A%0A%5Binsert%20probable%20cause%5D" class="file-bug">FILE BUG</a>' +
527         '<td class=options-container>' +
528             '<td class=options-container>' +
529                 '<td><td title="TEXT. Click for more info." class="results F merge" onclick=\'showPopupForBuild(event, "dummyBuilder",0,"foo/exists.html")\'>&nbsp;' +
530                 '<td title="IMAGE. Click for more info." class="results I" onclick=\'showPopupForBuild(event, "dummyBuilder",1,"foo/exists.html")\'>5';
531
532     equal(htmlForSingleTestRow(test), expected);
533 });
534
535 test('lookupVirtualTestSuite', 2, function() {
536     equal(lookupVirtualTestSuite('fast/canvas/foo.html'), '');
537     equal(lookupVirtualTestSuite('platform/chromium/virtual/gpu/fast/canvas/foo.html'), 'platform/chromium/virtual/gpu/fast/canvas');
538 });
539
540 test('baseTest', 2, function() {
541     equal(baseTest('fast/canvas/foo.html', ''), 'fast/canvas/foo.html');
542     equal(baseTest('platform/chromium/virtual/gpu/fast/canvas/foo.html', 'platform/chromium/virtual/gpu/fast/canvas'), 'fast/canvas/foo.html');
543 });
544
545 // FIXME: Create builders_tests.js and move this there.
546
547 test('isChromiumWebkitTipOfTreeTestRunner', 1, function() {
548     var builderList = ["WebKit Linux", "WebKit Linux (dbg)", "WebKit Linux 32", "WebKit Mac10.6", "WebKit Mac10.6 (dbg)",
549         "WebKit Mac10.6 (deps)", "WebKit Mac10.7", "WebKit Win", "WebKit Win (dbg)(1)", "WebKit Win (dbg)(2)", "WebKit Win (deps)",
550         "WebKit Win7", "Linux (Content Shell)"];
551     var expectedBuilders = ["WebKit Linux", "WebKit Linux (dbg)", "WebKit Linux 32", "WebKit Mac10.6",
552         "WebKit Mac10.6 (dbg)", "WebKit Mac10.7", "WebKit Win", "WebKit Win (dbg)(1)", "WebKit Win (dbg)(2)", "WebKit Win7"];
553     deepEqual(builderList.filter(isChromiumWebkitTipOfTreeTestRunner), expectedBuilders);
554 });
555
556 test('isChromiumWebkitDepsTestRunner', 1, function() {
557     var builderList = ["Chrome Frame Tests", "GPU Linux (NVIDIA)", "GPU Linux (dbg) (NVIDIA)", "GPU Mac", "GPU Mac (dbg)", "GPU Win7 (NVIDIA)", "GPU Win7 (dbg) (NVIDIA)", "Linux Perf", "Linux Tests",
558         "Linux Valgrind", "Mac Builder (dbg)", "Mac10.6 Perf", "Mac10.6 Tests", "Vista Perf", "Vista Tests", "WebKit Linux", "WebKit Linux ASAN",  "WebKit Linux (dbg)", "WebKit Linux (deps)", "WebKit Linux 32",
559         "WebKit Mac10.6", "WebKit Mac10.6 (dbg)", "WebKit Mac10.6 (deps)", "WebKit Mac10.7", "WebKit Win", "WebKit Win (dbg)(1)", "WebKit Win (dbg)(2)", "WebKit Win (deps)",
560         "WebKit Win7", "Win (dbg)", "Win Builder"];
561     var expectedBuilders = ["WebKit Linux (deps)", "WebKit Mac10.6 (deps)", "WebKit Win (deps)"];
562     deepEqual(builderList.filter(isChromiumWebkitDepsTestRunner), expectedBuilders);
563 });
564
565 test('queryHashAsMap', 2, function() {
566     equal(window.location.hash, '#useTestData=true');
567     deepEqual(queryHashAsMap(), {useTestData: 'true'});
568 });
569
570 test('parseCrossDashboardParameters', 2, function() {
571     equal(window.location.hash, '#useTestData=true');
572     parseCrossDashboardParameters();
573
574     var expectedParameters = {};
575     for (var key in g_defaultCrossDashboardStateValues)
576         expectedParameters[key] = g_defaultCrossDashboardStateValues[key];
577     expectedParameters.useTestData = true;
578
579     deepEqual(g_crossDashboardState, expectedParameters);
580 });
581
582 test('diffStates', 5, function() {
583     var newState = {a: 1, b: 2};
584     deepEqual(diffStates(null, newState), newState);
585
586     var oldState = {a: 1};
587     deepEqual(diffStates(oldState, newState), {b: 2});
588
589     // FIXME: This is kind of weird. I think the existing users of this code work correctly, but it's a confusing result.
590     var oldState = {c: 1};
591     deepEqual(diffStates(oldState, newState), {a:1, b: 2});
592
593     var oldState = {a: 1, b: 2};
594     deepEqual(diffStates(oldState, newState), {});
595
596     var oldState = {a: 2, b: 3};
597     deepEqual(diffStates(oldState, newState), {a: 1, b: 2});
598 });
599
600
601 test('builderGroupIsToTWebKitAttribute', 2, function() {
602     var dummyMaster = new builders.BuilderMaster('Chromium', 'dummyurl', {'layout-tests': {'builders': ['WebKit Linux', 'WebKit Linux (dbg)', 'WebKit Mac10.7', 'WebKit Win']}});
603     var testBuilderGroups = {
604         '@ToT - dummy.org': new BuilderGroup(BuilderGroup.TOT_WEBKIT),
605         '@DEPS - dummy.org': new BuilderGroup(BuilderGroup.DEPS_WEBKIT),
606     }
607
608     var testJSONData = "{ \"Dummy Builder 1\": null, \"Dummy Builder 2\": null }";
609     requestBuilderList(testBuilderGroups, 'ChromiumWebkit', '@ToT - dummy.org', testBuilderGroups['@ToT - dummy.org'], 'layout-tests');
610     equal(testBuilderGroups['@ToT - dummy.org'].isToTWebKit, true);
611     requestBuilderList(testBuilderGroups, 'ChromiumWebkit', '@DEPS - dummy.org', testBuilderGroups['@DEPS - dummy.org'], 'layout-tests');
612     equal(testBuilderGroups['@DEPS - dummy.org'].isToTWebKit, false);
613 });
614
615 test('requestBuilderListAddsBuilderGroupEntry', 1, function() {
616     var testBuilderGroups = { '@ToT - dummy.org': null };
617     var builderGroup = new BuilderGroup(BuilderGroup.TOT_WEBKIT);
618     var groupName = '@ToT - dummy.org';
619     requestBuilderList(testBuilderGroups, 'ChromiumWebkit', groupName, builderGroup, 'layout-tests');
620
621     equal(testBuilderGroups['@ToT - dummy.org'], builderGroup);
622 })
623
624 test('sortTests', 4, function() {
625     var test1 = createResultsObjectForTest('foo/test1.html', 'dummyBuilder');
626     var test2 = createResultsObjectForTest('foo/test2.html', 'dummyBuilder');
627     var test3 = createResultsObjectForTest('foo/test3.html', 'dummyBuilder');
628     test1.modifiers = 'b';
629     test2.modifiers = 'a';
630     test3.modifiers = '';
631
632     var tests = [test1, test2, test3];
633     sortTests(tests, 'modifiers', FORWARD);
634     deepEqual(tests, [test2, test1, test3]);
635     sortTests(tests, 'modifiers', BACKWARD);
636     deepEqual(tests, [test3, test1, test2]);
637
638     test1.bugs = 'b';
639     test2.bugs = 'a';
640     test3.bugs = '';
641
642     var tests = [test1, test2, test3];
643     sortTests(tests, 'bugs', FORWARD);
644     deepEqual(tests, [test2, test1, test3]);
645     sortTests(tests, 'bugs', BACKWARD);
646     deepEqual(tests, [test3, test1, test2]);
647 });
648
649 test('popup', 2, function() {
650     ui.popup.show(document.body, 'dummy content');
651     ok(document.querySelector('#popup'));
652     ui.popup.hide();
653     ok(!document.querySelector('#popup'));
654 });
655
656 test('gpuResultsPath', 3, function() {
657   equal(gpuResultsPath('777777', 'Win7 Release (ATI)'), '777777_Win7_Release_ATI_');
658   equal(gpuResultsPath('123', 'GPU Linux (dbg)(NVIDIA)'), '123_GPU_Linux_dbg_NVIDIA_');
659   equal(gpuResultsPath('12345', 'GPU Mac'), '12345_GPU_Mac');
660 });
661
662 test('TestTrie', 3, function() {
663     var builders = {
664         "Dummy Chromium Windows Builder": true,
665         "Dummy GTK Linux Builder": true,
666         "Dummy Apple Mac Lion Builder": true
667     };
668
669     var resultsByBuilder = {
670         "Dummy Chromium Windows Builder": {
671             tests: {
672                 "foo": true,
673                 "foo/bar/1.html": true,
674                 "foo/bar/baz": true
675             }
676         },
677         "Dummy GTK Linux Builder": {
678             tests: {
679                 "bar": true,
680                 "foo/1.html": true,
681                 "foo/bar/2.html": true,
682                 "foo/bar/baz/1.html": true,
683             }
684         },
685         "Dummy Apple Mac Lion Builder": {
686             tests: {
687                 "foo/bar/3.html": true,
688                 "foo/bar/baz/foo": true,
689             }
690         }
691     };
692     var expectedTrie = {
693         "foo": {
694             "bar": {
695                 "1.html": true,
696                 "2.html": true,
697                 "3.html": true,
698                 "baz": {
699                     "1.html": true,
700                     "foo": true
701                 }
702             },
703             "1.html": true
704         },
705         "bar": true
706     }
707
708     var trie = new TestTrie(builders, resultsByBuilder);
709     deepEqual(trie._trie, expectedTrie);
710
711     var leafsOfCompleteTrieTraversal = [];
712     var expectedLeafs = ["foo/bar/1.html", "foo/bar/baz/1.html", "foo/bar/baz/foo", "foo/bar/2.html", "foo/bar/3.html", "foo/1.html", "bar"];
713     trie.forEach(function(triePath) {
714         leafsOfCompleteTrieTraversal.push(triePath);
715     });
716     deepEqual(leafsOfCompleteTrieTraversal, expectedLeafs);
717
718     var leafsOfPartialTrieTraversal = [];
719     expectedLeafs = ["foo/bar/1.html", "foo/bar/baz/1.html", "foo/bar/baz/foo", "foo/bar/2.html", "foo/bar/3.html"];
720     trie.forEach(function(triePath) {
721         leafsOfPartialTrieTraversal.push(triePath);
722     }, "foo/bar");
723     deepEqual(leafsOfPartialTrieTraversal, expectedLeafs);
724 });
725
726 test('changeTestTypeInvalidatesGroup', 1, function() {
727     resetGlobals();
728     var originalGroup = '@ToT - chromium.org';
729     var originalTestType = 'layout-tests';
730     loadBuildersList(originalGroup, originalTestType);
731     g_crossDashboardState.group = originalGroup;
732     g_crossDashboardState.testType = originalTestType;
733
734     invalidateQueryParameters({'testType': 'ui_tests'});
735     notEqual(g_crossDashboardState.group, originalGroup, "group should have been invalidated");   
736 });