Add a JSCOnly MIPS buildbot
[WebKit-https.git] / Tools / BuildSlaveSupport / build.webkit.org-config / steps_unittest.py
1 #! /usr/bin/env python
2
3 import sys
4 import os
5 import StringIO
6 import unittest
7 import make_passwords_json
8 import json
9
10 from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS, SKIPPED, EXCEPTION
11 from buildbot.steps import source
12 from steps import (CheckOutSource, Run32bitJSCTests, RunAndUploadPerfTests, RunBenchmarkTests,
13                    RunJavaScriptCoreTests, RunLLINTCLoopTests, RunTest262Tests, RunUnitTests, RunWebKitTests)
14
15 # Show DepricationWarnings come from buildbot - it isn't default with Python 2.7 or newer.
16 # See https://bugs.webkit.org/show_bug.cgi?id=90161 for details.
17 import warnings
18 warnings.simplefilter('default')
19
20
21 class BuildBotConfigLoader(object):
22     def _add_webkitpy_to_sys_path(self):
23         # When files are passed to the python interpreter on the command line (e.g. python test.py) __file__ is a relative path.
24         absolute_file_path = os.path.abspath(__file__)
25         webkit_org_config_dir = os.path.dirname(absolute_file_path)
26         build_slave_support_dir = os.path.dirname(webkit_org_config_dir)
27         webkit_tools_dir = os.path.dirname(build_slave_support_dir)
28         scripts_dir = os.path.join(webkit_tools_dir, 'Scripts')
29         sys.path.append(scripts_dir)
30
31     def _mock_open(self, filename):
32         if filename == 'passwords.json':
33             return StringIO.StringIO(json.dumps(make_passwords_json.create_mock_slave_passwords_dict()))
34         return __builtins__.open(filename)
35
36     def _add_dependant_modules_to_sys_modules(self):
37         from webkitpy.thirdparty.autoinstalled import buildbot
38         sys.modules['buildbot'] = buildbot
39
40     def load_config(self, master_cfg_path):
41         # Before we can use webkitpy.thirdparty, we need to fix our path to include webkitpy.
42         # FIXME: If we're ever run by test-webkitpy we won't need this step.
43         self._add_webkitpy_to_sys_path()
44         # master.cfg expects the buildbot module to be in sys.path.
45         self._add_dependant_modules_to_sys_modules()
46
47         # master.cfg expects a passwords.json file which is not checked in.  Fake it by mocking open().
48         globals()['open'] = self._mock_open
49         # Because the master_cfg_path may have '.' in its name, we can't just use import, we have to use execfile.
50         # We pass globals() as both the globals and locals to mimic exectuting in the global scope, so
51         # that globals defined in master.cfg will be global to this file too.
52         execfile(master_cfg_path, globals(), globals())
53         globals()['open'] = __builtins__.open  # Stop mocking open().
54
55
56 class RunWebKitTestsTest(unittest.TestCase):
57     def test_nrwt_leaks_parsing(self):
58         run_webkit_tests = RunWebKitTests()  # pylint is confused by the way we import the module ... pylint: disable-msg=E0602
59         log_text = """
60 12:44:24.295 77706 13981 total leaks found for a total of 197,936 bytes.
61 12:44:24.295 77706 1 unique leaks found.
62 """
63         expected_incorrect_lines = [
64             '13981 total leaks found for a total of 197,936 bytes.',
65             '1 unique leaks found.',
66         ]
67         run_webkit_tests._parseRunWebKitTestsOutput(log_text)
68         self.assertEqual(run_webkit_tests.incorrectLayoutLines, expected_incorrect_lines)
69
70     def test_nrwt_missing_results(self):
71         run_webkit_tests = RunWebKitTests()  # pylint is confused by the way we import the module ... pylint: disable-msg=E0602
72         log_text = """
73 Expected to fail, but passed: (2)
74   animations/additive-transform-animations.html
75   animations/cross-fade-webkit-mask-box-image.html
76
77 Unexpected flakiness: text-only failures (2)
78   fast/events/touch/touch-inside-iframe.html [ Failure Pass ]
79   http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html [ Failure Pass ]
80
81 Unexpected flakiness: timeouts (1)
82   svg/text/foreignObject-repaint.xml [ Timeout Pass ]
83
84 Regressions: Unexpected missing results (1)
85   svg/custom/zero-path-square-cap-rendering2.svg [ Missing ]
86
87 Regressions: Unexpected text-only failures (1)
88   svg/custom/zero-path-square-cap-rendering2.svg [ Failure ]
89 """
90         run_webkit_tests._parseRunWebKitTestsOutput(log_text)
91         self.assertEqual(set(run_webkit_tests.incorrectLayoutLines),
92             set(['2 new passes', '3 flakes', '1 missing results', '1 failures']))
93
94
95 class StubStdio(object):
96     def __init__(self, stdio):
97         self._stdio = stdio
98
99     def getText(self):
100         return self._stdio
101
102
103 class StubRemoteCommand(object):
104     def __init__(self, rc, stdio):
105         self.rc = rc
106         self.logs = {'stdio': StubStdio(stdio)}
107
108
109 class RunJavaScriptCoreTestsTest(unittest.TestCase):
110     def assertResults(self, expected_result, expected_text, rc, stdio):
111         cmd = StubRemoteCommand(rc, stdio)
112         step = RunJavaScriptCoreTests()
113         step.commandComplete(cmd)
114         actual_results = step.evaluateCommand(cmd)
115         actual_text = step.getText2(cmd, actual_results)
116
117         self.assertEqual(expected_result, actual_results)
118         self.assertEqual(actual_text, expected_text)
119
120     def test_no_regressions_old_output(self):
121         self.assertResults(SUCCESS, ["jscore-test"], 0, """Results for Mozilla tests:
122     0 regressions found.
123     0 tests fixed.
124     OK.""")
125
126     def test_no_failure_new_output(self):
127         self.assertResults(SUCCESS, ["jscore-test"], 0, """Results for JSC stress tests:
128     0 failures found.
129     OK.""")
130
131     def test_mozilla_failure_old_output(self):
132         self.assertResults(FAILURE, ["1 JSC test failed"], 1, """Results for Mozilla tests:
133     1 regression found.
134     0 tests fixed.""")
135
136     def test_mozilla_failures_old_output(self):
137         self.assertResults(FAILURE, ["2 JSC tests failed"], 1, """Results for Mozilla tests:
138     2 regressions found.
139     0 tests fixed.""")
140
141     def test_jsc_stress_failure_new_output(self):
142         self.assertResults(FAILURE, ["1 JSC test failed"], 1,  """Results for JSC stress tests:
143     1 failure found.""")
144
145     def test_jsc_stress_failures_new_output(self):
146         self.assertResults(FAILURE, ["5 JSC tests failed"], 1,  """Results for JSC stress tests:
147     5 failures found.""")
148
149
150 class RunTest262TestsTest(unittest.TestCase):
151     def assertResults(self, expected_result, expected_text, rc, stdio):
152         cmd = StubRemoteCommand(rc, stdio)
153         step = RunTest262Tests()
154         step.commandComplete(cmd)
155         actual_results = step.evaluateCommand(cmd)
156         actual_text = step.getText2(cmd, actual_results)
157
158         self.assertEqual(expected_result, actual_results)
159         self.assertEqual(actual_text, expected_text)
160
161     def test_no_regressions_output(self):
162         self.assertResults(SUCCESS, ["test262-test"], 0, """Using the following jsc path: /WebKitBuild/Release/jsc
163
164 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default
165 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict
166 """)
167
168     def test_failure_output(self):
169         self.assertResults(FAILURE, ["1 Test262 test failed"], 0, """Using the following jsc path: /WebKitBuild/Release/jsc
170
171 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default
172 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict
173 test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict: ERROR: Unexpected exit code: 0
174 FAIL: test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict
175 """)
176
177     def test_failures_output(self):
178         self.assertResults(FAILURE, ["2 Test262 tests failed"], 0, """Using the following jsc path: /WebKitBuild/Release/jsc
179
180 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default
181 test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default: ERROR: Unexpected exit code: 0
182 FAIL: test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default
183 Running test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict
184 test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict: ERROR: Unexpected exit code: 0
185 FAIL: test262.yaml/test262/test/annexB/built-ins/Date/prototype/getYear/length.js.default-strict
186 """)
187
188
189 class RunLLINTCLoopTestsTest(unittest.TestCase):
190     def assertResults(self, expected_result, expected_text, rc, stdio):
191         cmd = StubRemoteCommand(rc, stdio)
192         step = RunLLINTCLoopTests()
193         step.commandComplete(cmd)
194         actual_results = step.evaluateCommand(cmd)
195         actual_text = step.getText2(cmd, actual_results)
196
197         self.assertEqual(expected_result, actual_results)
198         self.assertEqual(actual_text, expected_text)
199
200     def test_failures(self):
201         self.assertResults(FAILURE, ['5 regressions found.'], 1,  '    5 regressions found.')
202
203     def test_failure(self):
204         self.assertResults(FAILURE, ['1 regression found.'], 1,  '    1 regression found.')
205
206     def test_no_failure(self):
207         self.assertResults(SUCCESS, ['webkit-jsc-cloop-test'], 0,  '    0 regressions found.')
208
209
210 class Run32bitJSCTestsTest(unittest.TestCase):
211     def assertResults(self, expected_result, expected_text, rc, stdio):
212         cmd = StubRemoteCommand(rc, stdio)
213         step = Run32bitJSCTests()
214         step.commandComplete(cmd)
215         actual_results = step.evaluateCommand(cmd)
216         actual_text = step.getText2(cmd, actual_results)
217
218         self.assertEqual(expected_result, actual_results)
219         self.assertEqual(actual_text, expected_text)
220
221     def test_failures(self):
222         self.assertResults(FAILURE, ['5 regressions found.'], 1,  '    5 failures found.')
223
224     def test_failure(self):
225         self.assertResults(FAILURE, ['1 regression found.'], 1,  '    1 failure found.')
226
227     def test_no_failure(self):
228         self.assertResults(SUCCESS, ['webkit-32bit-jsc-test'], 0,  '    0 failures found.')
229
230
231 class RunUnitTestsTest(unittest.TestCase):
232     def assertFailures(self, expected_failure_count, stdio):
233         if expected_failure_count:
234             rc = 1
235             expected_results = FAILURE
236             plural_suffix = "" if expected_failure_count == 1 else "s"
237             expected_text = '%d unit test%s failed or timed out' % (expected_failure_count, plural_suffix)
238         else:
239             rc = 0
240             expected_results = SUCCESS
241             expected_text = 'run-api-tests'
242
243         cmd = StubRemoteCommand(rc, stdio)
244         step = RunUnitTests()
245         step.commandComplete(cmd)
246         actual_results = step.evaluateCommand(cmd)
247         actual_failure_count = step.failedTestCount
248         actual_text = step.getText(cmd, actual_results)[0]
249
250         self.assertEqual(expected_results, actual_results)
251         self.assertEqual(expected_failure_count, actual_failure_count)
252         self.assertEqual(expected_text, actual_text)
253
254     def test_no_failures_or_timeouts(self):
255         self.assertFailures(0, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
256 [==========] Running 1 test from 1 test case.
257 [----------] Global test environment set-up.
258 [----------] 1 test from WebViewDestructionWithHostWindow
259 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
260 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
261 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
262
263 [----------] Global test environment tear-down
264 [==========] 1 test from 1 test case ran. (127 ms total)
265 [  PASSED  ] 1 test.
266 """)
267
268     def test_one_failure(self):
269         self.assertFailures(1, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
270 [==========] Running 1 test from 1 test case.
271 [----------] Global test environment set-up.
272 [----------] 1 test from WebViewDestructionWithHostWindow
273 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
274 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
275 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
276
277 [----------] Global test environment tear-down
278 [==========] 1 test from 1 test case ran. (127 ms total)
279 [  PASSED  ] 1 test.
280 Tests that failed:
281   WebKit2.WebKit2.CanHandleRequest
282 """)
283
284     def test_multiple_failures(self):
285         self.assertFailures(4, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
286 [==========] Running 1 test from 1 test case.
287 [----------] Global test environment set-up.
288 [----------] 1 test from WebViewDestructionWithHostWindow
289 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
290 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
291 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
292
293 [----------] Global test environment tear-down
294 [==========] 1 test from 1 test case ran. (127 ms total)
295 [  PASSED  ] 1 test.
296 Tests that failed:
297   WebKit2.WebKit2.CanHandleRequest
298   WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
299   WebKit2.WebKit2.HitTestResultNodeHandle
300   WebKit2.WebKit2.InjectedBundleBasic
301 """)
302
303     def test_one_timeout(self):
304         self.assertFailures(1, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
305 [==========] Running 1 test from 1 test case.
306 [----------] Global test environment set-up.
307 [----------] 1 test from WebViewDestructionWithHostWindow
308 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
309 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
310 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
311
312 [----------] Global test environment tear-down
313 [==========] 1 test from 1 test case ran. (127 ms total)
314 [  PASSED  ] 1 test.
315 Tests that timed out:
316   WebKit2.WebKit2.CanHandleRequest
317 """)
318
319     def test_multiple_timeouts(self):
320         self.assertFailures(4, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
321 [==========] Running 1 test from 1 test case.
322 [----------] Global test environment set-up.
323 [----------] 1 test from WebViewDestructionWithHostWindow
324 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
325 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
326 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
327
328 [----------] Global test environment tear-down
329 [==========] 1 test from 1 test case ran. (127 ms total)
330 [  PASSED  ] 1 test.
331 Tests that timed out:
332   WebKit2.WebKit2.CanHandleRequest
333   WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
334   WebKit2.WebKit2.HitTestResultNodeHandle
335   WebKit2.WebKit2.InjectedBundleBasic
336 """)
337
338     def test_multiple_failures_and_timeouts(self):
339         self.assertFailures(8, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
340 [==========] Running 1 test from 1 test case.
341 [----------] Global test environment set-up.
342 [----------] 1 test from WebViewDestructionWithHostWindow
343 [ RUN      ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
344 [       OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
345 [----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
346
347 [----------] Global test environment tear-down
348 [==========] 1 test from 1 test case ran. (127 ms total)
349 [  PASSED  ] 1 test.
350 Tests that failed:
351   WebKit2.WebKit2.CanHandleRequest
352   WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
353   WebKit2.WebKit2.HitTestResultNodeHandle
354 Tests that timed out:
355   WebKit2.WebKit2.InjectedBundleBasic
356   WebKit2.WebKit2.LoadCanceledNoServerRedirectCallback
357   WebKit2.WebKit2.MouseMoveAfterCrash
358   WebKit2.WebKit2.ResponsivenessTimerDoesntFireEarly
359   WebKit2.WebKit2.WebArchive
360 """)
361
362
363 class SVNMirrorTest(unittest.TestCase):
364     def setUp(self):
365         self.config = json.load(open('config.json'))
366
367     def get_SVNMirrorFromConfig(self, builderName):
368         SVNMirror = None
369         for builder in self.config['builders']:
370             if builder['name'] == builderName:
371                 SVNMirror = builder.pop('SVNMirror', 'https://svn.webkit.org/repository/webkit/')
372         return SVNMirror
373
374     def test_CheckOutSource(self):
375         # SVN mirror feature isn't unittestable now with source.oldsource.SVN(==source.SVN) , only with source.svn.SVN(==SVN)
376         # https://bugs.webkit.org/show_bug.cgi?id=85887
377         if issubclass(CheckOutSource, source.SVN):
378             return
379
380         # Compare CheckOutSource.baseURL with SVNMirror (or with the default URL) in config.json for all builders
381         for builder in c['builders']:
382             for buildStepFactory, kwargs in builder['factory'].steps:
383                 if str(buildStepFactory).split('.')[-1] == 'CheckOutSource':
384                         CheckOutSourceInstance = buildStepFactory(**kwargs)
385                         self.assertEqual(CheckOutSourceInstance.baseURL, self.get_SVNMirrorFromConfig(builder['name']))
386
387
388 class BuildStepsConstructorTest(unittest.TestCase):
389     # "Passing a BuildStep subclass to factory.addStep is deprecated. Please pass a BuildStep instance instead.  Support will be dropped in v0.8.7."
390     # It checks if all builder's all buildsteps can be insantiated after migration.
391     # https://bugs.webkit.org/show_bug.cgi?id=89001
392     # http://buildbot.net/buildbot/docs/0.8.6p1/manual/customization.html#writing-buildstep-constructors
393
394     @staticmethod
395     def generateTests():
396         for builderNumber, builder in enumerate(c['builders']):
397             for stepNumber, step in enumerate(builder['factory'].steps):
398                 builderName = builder['name'].encode('ascii', 'ignore')
399                 setattr(BuildStepsConstructorTest, 'test_builder%02d_step%02d' % (builderNumber, stepNumber), BuildStepsConstructorTest.createTest(builderName, step))
400
401     @staticmethod
402     def createTest(builderName, step):
403         def doTest(self):
404             try:
405                 buildStepFactory, kwargs = step
406                 buildStepFactory(**kwargs)
407             except TypeError as e:
408                 buildStepName = str(buildStepFactory).split('.')[-1]
409                 self.fail("Error during instantiation %s buildstep for %s builder: %s\n" % (buildStepName, builderName, e))
410         return doTest
411
412
413 expected_build_steps = {
414     'Apple Win 7 Debug (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
415     'Apple Win 7 Release (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
416     'Apple Win Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile', 'compile-webkit', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
417     'Apple Win Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile', 'compile-webkit', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
418
419     'Apple El Capitan 32-bit JSC (BuildAndTest)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'webkit-32bit-jsc-test'],
420     'Apple El Capitan CMake Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
421     'Apple El Capitan Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
422     'Apple El Capitan Debug JSC (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'jscore-test'],
423     'Apple El Capitan Debug Test262 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'test262-test'],
424     'Apple El Capitan Debug WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
425     'Apple El Capitan Debug WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
426     'Apple El Capitan LLINT CLoop (BuildAndTest)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'webkit-jsc-cloop-test'],
427     'Apple El Capitan Release (32-bit Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
428     'Apple El Capitan Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
429     'Apple El Capitan Release WK2 (Perf)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'perf-test'],
430     'Apple El Capitan Release JSC (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'jscore-test'],
431     'Apple El Capitan Release Test262 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'test262-test'],
432     'Apple El Capitan Release WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
433     'Apple El Capitan Release WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
434
435     'Apple High Sierra 32-bit JSC (BuildAndTest)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'webkit-32bit-jsc-test'],
436     'Apple High Sierra (Leaks)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'archive-test-results', 'upload', 'MasterShellCommand'],
437     'Apple High Sierra Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
438     'Apple High Sierra Debug JSC (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'jscore-test'],
439     'Apple High Sierra Debug WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
440     'Apple High Sierra Debug WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
441     'Apple High Sierra LLINT CLoop (BuildAndTest)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'webkit-jsc-cloop-test'],
442     'Apple High Sierra Release (32-bit Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
443     'Apple High Sierra Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
444     'Apple High Sierra Release JSC (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'jscore-test'],
445     'Apple High Sierra Release WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
446     'Apple High Sierra Release WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
447
448     'Apple Sierra Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
449     'Apple Sierra Debug WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
450     'Apple Sierra Debug WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
451     'Apple Sierra Release (32-bit Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
452     'Apple Sierra Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
453     'Apple Sierra Release WK1 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
454     'Apple Sierra Release WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
455
456     'Apple iOS 11 Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
457     'Apple iOS 11 Simulator Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
458     'Apple iOS 11 Simulator Release WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
459
460     'Apple iOS 11 Simulator Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'archive-built-product', 'upload', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
461     'Apple iOS 11 Simulator Debug WK2 (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'download-built-product', 'extract-built-product', 'layout-test', 'run-api-tests', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand'],
462
463     'JSCOnly Linux ARMv7 Thumb2 Release': ['configure build', 'wait-for-svn-server', 'svn', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'jscore-test'],
464     'JSCOnly Linux ARMv7 Traditional Release': ['configure build', 'wait-for-svn-server', 'svn', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'jscore-test'],
465     'JSCOnly Linux AArch64 Release': ['configure build', 'wait-for-svn-server', 'svn', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'jscore-test'],
466     'JSCOnly Linux MIPS32el Release': ['configure build', 'svn', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit', 'jscore-test'],
467
468     'GTK Linux 32-bit Release': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'compile-webkit', 'jscore-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'API tests'],
469     'GTK Linux 64-bit Debug (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'compile-webkit', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
470     'GTK Linux 64-bit Debug (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand', 'API tests'],
471     'GTK Linux 64-bit Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'compile-webkit', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
472     'GTK Linux 64-bit Release (Perf)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'download-built-product', 'extract-built-product', 'perf-test', 'benchmark-test'],
473     'GTK Linux 64-bit Release (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand', 'API tests'],
474     'GTK Linux 64-bit Release Wayland (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand', 'API tests'],
475     'GTK Linux 64-bit Release Ubuntu LTS (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
476     'GTK Linux 64-bit Release Debian Stable (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
477     'GTK Linux ARM Release': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'compile-webkit', 'jscore-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'API tests'],
478
479     'WinCairo 64-Bit Release': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'compile-webkit'],
480
481     'WPE Linux 64-bit Release (Build)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'compile-webkit', 'archive-built-product', 'upload', 'transfer-to-s3', 'trigger'],
482     'WPE Linux 64-bit Release (Tests)': ['configure build', 'svn', 'kill old processes', 'delete WebKitBuild directory', 'delete stale build files', 'jhbuild', 'download-built-product', 'extract-built-product', 'jscore-test', 'layout-test', 'webkitpy-test', 'webkitperl-test', 'bindings-generation-tests', 'builtins-generator-tests', 'dashboard-tests', 'archive-test-results', 'upload', 'MasterShellCommand', 'API tests'],
483 }
484
485
486 class BuildStepsTest(unittest.TestCase):
487     @staticmethod
488     def generateTests():
489         for builder in c['builders']:
490             builderName = builder['name'].encode('ascii', 'ignore')
491             setattr(BuildStepsTest, 'test_builder %s' % builderName, BuildStepsTest.createTest(builder))
492
493     @staticmethod
494     def createTest(builder):
495         def doTest(self):
496             buildSteps = []
497             for step in builder['factory'].steps:
498                 buildSteps.append(step[0].name)
499             self.assertTrue(builder['name'] in expected_build_steps, "Missing expected result for builder: %s\n Actual result is %s" % (builder['name'], buildSteps))
500             self.assertListEqual(expected_build_steps[builder['name']], buildSteps)
501
502         return doTest
503
504     def test_unnecessary_expected_results(self):
505         builders = set()
506         for builder in c['builders']:
507             builders.add(builder['name'].encode('ascii', 'ignore'))
508
509         for builder in expected_build_steps:
510             self.assertTrue(builder in builders, "Builder %s doesn't exist, but has unnecessary expected results" % builder)
511
512
513 class RunAndUploadPerfTestsTest(unittest.TestCase):
514     def assertResults(self, rc, expected_text):
515         cmd = StubRemoteCommand(rc, expected_text)
516         step = RunAndUploadPerfTests()
517         step.commandComplete(cmd)
518         actual_results = step.evaluateCommand(cmd)
519         actual_text = str(step.getText2(cmd, actual_results)[0])
520         self.assertEqual(expected_text, actual_text)
521
522     def test_success(self):
523         self.assertResults(0, "perf-test")
524
525     def test_tests_failed(self):
526         self.assertResults(5, "5 perf tests failed")
527
528     def test_build_bad_build(self):
529         self.assertResults(255, "build not up to date")
530
531     def test_build_bad_source_json(self):
532         self.assertResults(254, "slave config JSON error")
533
534     def test_build_bad_marge(self):
535         self.assertResults(253, "output JSON merge error")
536
537     def test_build_bad_failed_uploading(self):
538         self.assertResults(252, "upload error")
539
540     def test_build_bad_preparation(self):
541         self.assertResults(251, "system dependency error")
542
543     def test_buildbot_timeout(self):
544         self.assertResults(-1, "timeout")
545
546
547 class RunBenchmarkTest(unittest.TestCase):
548     def assertResults(self, rc, expected_text):
549         cmd = StubRemoteCommand(rc, expected_text)
550         step = RunBenchmarkTests()
551         step.commandComplete(cmd)
552         actual_results = step.evaluateCommand(cmd)
553         actual_text = str(step.getText2(cmd, actual_results)[0])
554         self.assertEqual(expected_text, actual_text)
555
556     def test_success(self):
557         self.assertResults(0, "benchmark-test")
558
559     def test_tests_failed(self):
560         self.assertResults(7, "7 benchmark tests failed")
561
562
563 # FIXME: We should run this file as part of test-webkitpy.
564 # Unfortunately test-webkitpy currently requires that unittests
565 # be located in a directory with a valid module name.
566 # 'build.webkit.org-config' is not a valid module name (due to '.' and '-')
567 # so for now this is a stand-alone test harness.
568 if __name__ == '__main__':
569     BuildBotConfigLoader().load_config('master.cfg')
570     BuildStepsConstructorTest.generateTests()
571     BuildStepsTest.generateTests()
572     unittest.main()