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