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