[ews-build] Do not print worker environment variables in each build step [part 2]
[WebKit-https.git] / Tools / BuildSlaveSupport / ews-build / steps_unittest.py
1 # Copyright (C) 2018-2019 Apple 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
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 import operator
24 import os
25 import shutil
26 import tempfile
27
28 from buildbot.process import remotetransfer
29 from buildbot.process.results import Results, SUCCESS, FAILURE, WARNINGS, SKIPPED, EXCEPTION, RETRY
30 from buildbot.test.fake.remotecommand import Expect, ExpectRemoteRef, ExpectShell
31 from buildbot.test.util.steps import BuildStepMixin
32 from mock import call
33 from twisted.internet import error, reactor
34 from twisted.python import failure, log
35 from twisted.trial import unittest
36
37 from steps import (AnalyzeAPITestsResults, AnalyzeCompileWebKitResults, ApplyPatch, ArchiveBuiltProduct, ArchiveTestResults,
38                    CheckOutSource, CheckOutSpecificRevision, CheckPatchRelevance, CheckStyle, CleanBuild, CleanWorkingDirectory,
39                    CompileJSCOnly, CompileJSCOnlyToT, CompileWebKit, CompileWebKitToT, ConfigureBuild,
40                    DownloadBuiltProduct, ExtractBuiltProduct, ExtractTestResults, KillOldProcesses,
41                    PrintConfiguration, ReRunAPITests, ReRunJavaScriptCoreTests, RunAPITests, RunAPITestsWithoutPatch,
42                    RunBindingsTests, RunJavaScriptCoreTests, RunJavaScriptCoreTestsToT, RunWebKit1Tests, RunWebKitPerlTests,
43                    RunWebKitPyTests, RunWebKitTests, TestWithFailureCount, Trigger, TransferToS3, UnApplyPatchIfRequired,
44                    UploadBuiltProduct, UploadTestResults, ValidatePatch)
45
46 # Workaround for https://github.com/buildbot/buildbot/issues/4669
47 from buildbot.test.fake.fakebuild import FakeBuild
48 FakeBuild.addStepsAfterCurrentStep = lambda FakeBuild, step_factories: None
49
50
51 def mock_step(step, logs='', results=SUCCESS, stopped=False, properties=None):
52     step.logs = logs
53     step.results = results
54     step.stopped = stopped
55     return step
56
57
58 class ExpectMasterShellCommand(object):
59     def __init__(self, command, workdir=None, env=None, usePTY=0):
60         self.args = command
61         self.usePTY = usePTY
62         self.rc = None
63         self.path = None
64         self.logs = []
65
66         if env is not None:
67             self.env = env
68         else:
69             self.env = os.environ
70         if workdir:
71             self.path = os.path.join(os.getcwd(), workdir)
72
73     @classmethod
74     def log(self, name, value):
75         return ('log', name, value)
76
77     def __add__(self, other):
78         if isinstance(other, int):
79             self.rc = other
80         elif isinstance(other, tuple) and other[0] == 'log':
81             self.logs.append((other[1], other[2]))
82         return self
83
84     def __repr__(self):
85         return 'ExpectMasterShellCommand({0})'.format(repr(self.args))
86
87
88 class BuildStepMixinAdditions(BuildStepMixin):
89     def setUpBuildStep(self):
90         self.patch(reactor, 'spawnProcess', lambda *args, **kwargs: self._checkSpawnProcess(*args, **kwargs))
91         self._expected_local_commands = []
92
93         self._temp_directory = tempfile.mkdtemp()
94         os.chdir(self._temp_directory)
95         self._expected_uploaded_files = []
96
97         super(BuildStepMixinAdditions, self).setUpBuildStep()
98
99     def tearDownBuildStep(self):
100         shutil.rmtree(self._temp_directory)
101         super(BuildStepMixinAdditions, self).tearDownBuildStep()
102
103     def fakeBuildFinished(self, text, results):
104         self.build.text = text
105         self.build.results = results
106
107     def setupStep(self, step, *args, **kwargs):
108         self.previous_steps = kwargs.get('previous_steps') or []
109         if self.previous_steps:
110             del kwargs['previous_steps']
111
112         super(BuildStepMixinAdditions, self).setupStep(step, *args, **kwargs)
113         self.build.terminate = False
114         self.build.stopped = False
115         self.build.executedSteps = self.executedSteps
116         self.build.buildFinished = self.fakeBuildFinished
117         self._expected_added_urls = []
118         self._expected_sources = None
119
120     @property
121     def executedSteps(self):
122         return filter(lambda step: not step.stopped, self.previous_steps)
123
124     def setProperty(self, name, value, source='Unknown'):
125         self.properties.setProperty(name, value, source)
126
127     def expectAddedURLs(self, added_urls):
128         self._expected_added_urls = added_urls
129
130     def expectUploadedFile(self, path):
131         self._expected_uploaded_files.append(path)
132
133     def expectLocalCommands(self, *expected_commands):
134         self._expected_local_commands.extend(expected_commands)
135
136     def expectRemoteCommands(self, *expected_commands):
137         self.expectCommands(*expected_commands)
138
139     def expectSources(self, expected_sources):
140         self._expected_sources = expected_sources
141
142     def _checkSpawnProcess(self, processProtocol, executable, args, env, path, usePTY, **kwargs):
143         got = (executable, args, env, path, usePTY)
144         if not self._expected_local_commands:
145             self.fail('got local command {0} when no further commands were expected'.format(got))
146         local_command = self._expected_local_commands.pop(0)
147         try:
148             self.assertEqual(got, (local_command.args[0], local_command.args, local_command.env, local_command.path, local_command.usePTY))
149         except AssertionError:
150             log.err()
151             raise
152         for name, value in local_command.logs:
153             if name == 'stdout':
154                 processProtocol.outReceived(value)
155             elif name == 'stderr':
156                 processProtocol.errReceived(value)
157         if local_command.rc != 0:
158             value = error.ProcessTerminated(exitCode=local_command.rc)
159         else:
160             value = error.ProcessDone(None)
161         processProtocol.processEnded(failure.Failure(value))
162
163     def _added_files(self):
164         results = []
165         for dirpath, dirnames, filenames in os.walk(self._temp_directory):
166             relative_root_path = os.path.relpath(dirpath, start=self._temp_directory)
167             if relative_root_path == '.':
168                 relative_root_path = ''
169             for name in filenames:
170                 results.append(os.path.join(relative_root_path, name))
171         return results
172
173     def runStep(self):
174         def check(result):
175             self.assertEqual(self._expected_local_commands, [], 'assert all expected local commands were run')
176             self.expectAddedURLs(self._expected_added_urls)
177             self.assertEqual(self._added_files(), self._expected_uploaded_files)
178             if self._expected_sources is not None:
179                 # Convert to dictionaries because assertEqual() only knows how to diff Python built-in types.
180                 actual_sources = sorted([source.asDict() for source in self.build.sources], key=operator.itemgetter('codebase'))
181                 expected_sources = sorted([source.asDict() for source in self._expected_sources], key=operator.itemgetter('codebase'))
182                 self.assertEqual(actual_sources, expected_sources)
183         deferred_result = super(BuildStepMixinAdditions, self).runStep()
184         deferred_result.addCallback(check)
185         return deferred_result
186
187
188 def uploadFileWithContentsOfString(string, timestamp=None):
189     def behavior(command):
190         writer = command.args['writer']
191         writer.remote_write(string + '\n')
192         writer.remote_close()
193         if timestamp:
194             writer.remote_utime(timestamp)
195     return behavior
196
197
198 class TestCheckStyle(BuildStepMixinAdditions, unittest.TestCase):
199     def setUp(self):
200         self.longMessage = True
201         return self.setUpBuildStep()
202
203     def tearDown(self):
204         return self.tearDownBuildStep()
205
206     def test_success_internal(self):
207         self.setupStep(CheckStyle())
208         self.setProperty('try-codebase', 'internal')
209         self.setProperty('platform', 'mac')
210         self.setProperty('configuration', 'debug')
211
212         self.expectRemoteCommands(
213             ExpectShell(workdir='wkdir',
214                         command=['Tools/Scripts/check-webkit-style'],
215                         )
216             + 0,
217         )
218         self.expectOutcome(result=SUCCESS, state_string='check-webkit-style')
219         return self.runStep()
220
221     def test_failure_unknown_try_codebase(self):
222         self.setupStep(CheckStyle())
223         self.setProperty('try-codebase', 'foo')
224         self.setProperty('platform', 'mac')
225         self.setProperty('configuration', 'debug')
226
227         self.expectRemoteCommands(
228             ExpectShell(workdir='wkdir',
229                         command=['Tools/Scripts/check-webkit-style'],
230                         )
231             + 2,
232         )
233         self.expectOutcome(result=FAILURE, state_string='check-webkit-style (failure)')
234         return self.runStep()
235
236     def test_failures_with_style_issues(self):
237         self.setupStep(CheckStyle())
238         self.setProperty('try-codebase', 'internal')
239         self.setProperty('platform', 'mac')
240         self.setProperty('configuration', 'debug')
241
242         self.expectRemoteCommands(
243             ExpectShell(workdir='wkdir',
244                         command=['Tools/Scripts/check-webkit-style'],
245                         )
246             + ExpectShell.log('stdio', stdout='''ERROR: Source/WebCore/layout/FloatingContext.cpp:36:  Code inside a namespace should not be indented.  [whitespace/indent] [4]
247 ERROR: Source/WebCore/layout/FormattingContext.h:94:  Weird number of spaces at line-start.  Are you using a 4-space indent?  [whitespace/indent] [3]
248 ERROR: Source/WebCore/layout/LayoutContext.cpp:52:  Place brace on its own line for function definitions.  [whitespace/braces] [4]
249 ERROR: Source/WebCore/layout/LayoutContext.cpp:55:  Extra space before last semicolon. If this should be an empty statement, use { } instead.  [whitespace/semicolon] [5]
250 ERROR: Source/WebCore/layout/LayoutContext.cpp:60:  Tab found; better to use spaces  [whitespace/tab] [1]
251 ERROR: Source/WebCore/layout/Verification.cpp:88:  Missing space before ( in while(  [whitespace/parens] [5]
252 Total errors found: 8 in 48 files''')
253             + 2,
254         )
255         self.expectOutcome(result=FAILURE, state_string='8 style errors (failure)')
256         return self.runStep()
257
258     def test_failures_no_style_issues(self):
259         self.setupStep(CheckStyle())
260         self.setProperty('try-codebase', 'internal')
261         self.setProperty('platform', 'mac')
262         self.setProperty('configuration', 'debug')
263
264         self.expectRemoteCommands(
265             ExpectShell(workdir='wkdir',
266                         command=['Tools/Scripts/check-webkit-style'],
267                         )
268             + ExpectShell.log('stdio', stdout='Total errors found: 0 in 6 files')
269             + 0,
270         )
271         self.expectOutcome(result=SUCCESS, state_string='check-webkit-style')
272         return self.runStep()
273
274     def test_failures_no_changes(self):
275         self.setupStep(CheckStyle())
276         self.setProperty('try-codebase', 'internal')
277         self.setProperty('platform', 'mac')
278         self.setProperty('configuration', 'debug')
279
280         self.expectRemoteCommands(
281             ExpectShell(workdir='wkdir',
282                         command=['Tools/Scripts/check-webkit-style'],
283                         )
284             + ExpectShell.log('stdio', stdout='Total errors found: 0 in 0 files')
285             + 2,
286         )
287         self.expectOutcome(result=FAILURE, state_string='check-webkit-style (failure)')
288         return self.runStep()
289
290
291 class TestRunBindingsTests(BuildStepMixinAdditions, unittest.TestCase):
292     def setUp(self):
293         self.longMessage = True
294         self.jsonFileName = 'bindings_test_results.json'
295         return self.setUpBuildStep()
296
297     def tearDown(self):
298         return self.tearDownBuildStep()
299
300     def test_success(self):
301         self.setupStep(RunBindingsTests())
302         self.expectRemoteCommands(
303             ExpectShell(workdir='wkdir',
304                         timeout=300,
305                         logEnviron=False,
306                         command=['Tools/Scripts/run-bindings-tests', '--json-output={0}'.format(self.jsonFileName)],
307                         logfiles={'json': self.jsonFileName},
308                         )
309             + 0,
310         )
311         self.expectOutcome(result=SUCCESS, state_string='Passed bindings tests')
312         return self.runStep()
313
314     def test_failure(self):
315         self.setupStep(RunBindingsTests())
316         self.expectRemoteCommands(
317             ExpectShell(workdir='wkdir',
318                         timeout=300,
319                         logEnviron=False,
320                         command=['Tools/Scripts/run-bindings-tests', '--json-output={0}'.format(self.jsonFileName)],
321                         logfiles={'json': self.jsonFileName},
322                         )
323             + ExpectShell.log('stdio', stdout='FAIL: (JS) JSTestInterface.cpp')
324             + 2,
325         )
326         self.expectOutcome(result=FAILURE, state_string='bindings-tests (failure)')
327         return self.runStep()
328
329
330 class TestRunWebKitPerlTests(BuildStepMixinAdditions, unittest.TestCase):
331     def setUp(self):
332         self.longMessage = True
333         return self.setUpBuildStep()
334
335     def tearDown(self):
336         return self.tearDownBuildStep()
337
338     def test_success(self):
339         self.setupStep(RunWebKitPerlTests())
340         self.expectRemoteCommands(
341             ExpectShell(workdir='wkdir',
342                         logEnviron=False,
343                         command=['Tools/Scripts/test-webkitperl'],
344                         timeout=120,
345                         )
346             + 0,
347         )
348         self.expectOutcome(result=SUCCESS, state_string='webkitperl-tests')
349         return self.runStep()
350
351     def test_failure(self):
352         self.setupStep(RunWebKitPerlTests())
353         self.expectRemoteCommands(
354             ExpectShell(workdir='wkdir',
355                         logEnviron=False,
356                         command=['Tools/Scripts/test-webkitperl'],
357                         timeout=120,
358                         )
359             + ExpectShell.log('stdio', stdout='''Failed tests:  1-3, 5-7, 9, 11-13
360 Files=40, Tests=630,  4 wallclock secs ( 0.16 usr  0.09 sys +  2.78 cusr  0.64 csys =  3.67 CPU)
361 Result: FAIL
362 Failed 1/40 test programs. 10/630 subtests failed.''')
363             + 2,
364         )
365         self.expectOutcome(result=FAILURE, state_string='webkitperl-tests (failure)')
366         return self.runStep()
367
368
369 class TestWebKitPyTests(BuildStepMixinAdditions, unittest.TestCase):
370     def setUp(self):
371         self.longMessage = True
372         self.jsonFileName = 'webkitpy_test_results.json'
373         return self.setUpBuildStep()
374
375     def tearDown(self):
376         return self.tearDownBuildStep()
377
378     def test_success(self):
379         self.setupStep(RunWebKitPyTests())
380         self.expectRemoteCommands(
381             ExpectShell(workdir='wkdir',
382                         logEnviron=False,
383                         command=['Tools/Scripts/test-webkitpy', '--json-output={0}'.format(self.jsonFileName)],
384                         logfiles={'json': self.jsonFileName},
385                         timeout=120,
386                         )
387             + 0,
388         )
389         self.expectOutcome(result=SUCCESS, state_string='Passed webkitpy tests')
390         return self.runStep()
391
392     def test_failure(self):
393         self.setupStep(RunWebKitPyTests())
394         self.expectRemoteCommands(
395             ExpectShell(workdir='wkdir',
396                         logEnviron=False,
397                         command=['Tools/Scripts/test-webkitpy', '--json-output={0}'.format(self.jsonFileName)],
398                         logfiles={'json': self.jsonFileName},
399                         timeout=120,
400                         )
401             + ExpectShell.log('stdio', stdout='''Ran 1744 tests in 5.913s
402 FAILED (failures=1, errors=0)''')
403             + 2,
404         )
405         self.expectOutcome(result=FAILURE, state_string='webkitpy-tests (failure)')
406         return self.runStep()
407
408
409 class TestKillOldProcesses(BuildStepMixinAdditions, unittest.TestCase):
410     def setUp(self):
411         self.longMessage = True
412         return self.setUpBuildStep()
413
414     def tearDown(self):
415         return self.tearDownBuildStep()
416
417     def test_success(self):
418         self.setupStep(KillOldProcesses())
419         self.expectRemoteCommands(
420             ExpectShell(workdir='wkdir',
421                         command=['python', 'Tools/BuildSlaveSupport/kill-old-processes', 'buildbot'],
422                         logEnviron=False,
423                         timeout=60,
424                         )
425             + 0,
426         )
427         self.expectOutcome(result=SUCCESS, state_string='Killed old processes')
428         return self.runStep()
429
430     def test_failure(self):
431         self.setupStep(KillOldProcesses())
432         self.expectRemoteCommands(
433             ExpectShell(workdir='wkdir',
434                         command=['python', 'Tools/BuildSlaveSupport/kill-old-processes', 'buildbot'],
435                         logEnviron=False,
436                         timeout=60,
437                         )
438             + ExpectShell.log('stdio', stdout='Unexpected error.')
439             + 2,
440         )
441         self.expectOutcome(result=FAILURE, state_string='Killed old processes (failure)')
442         return self.runStep()
443
444
445 class TestCleanBuild(BuildStepMixinAdditions, unittest.TestCase):
446     def setUp(self):
447         self.longMessage = True
448         return self.setUpBuildStep()
449
450     def tearDown(self):
451         return self.tearDownBuildStep()
452
453     def test_success(self):
454         self.setupStep(CleanBuild())
455         self.setProperty('fullPlatform', 'ios-11')
456         self.setProperty('configuration', 'release')
457         self.expectRemoteCommands(
458             ExpectShell(workdir='wkdir',
459                         command=['python', 'Tools/BuildSlaveSupport/clean-build', '--platform=ios-11', '--release'],
460                         )
461             + 0,
462         )
463         self.expectOutcome(result=SUCCESS, state_string='Deleted WebKitBuild directory')
464         return self.runStep()
465
466     def test_failure(self):
467         self.setupStep(CleanBuild())
468         self.setProperty('fullPlatform', 'ios-simulator-11')
469         self.setProperty('configuration', 'debug')
470         self.expectRemoteCommands(
471             ExpectShell(workdir='wkdir',
472                         command=['python', 'Tools/BuildSlaveSupport/clean-build', '--platform=ios-simulator-11', '--debug'],
473                         )
474             + ExpectShell.log('stdio', stdout='Unexpected error.')
475             + 2,
476         )
477         self.expectOutcome(result=FAILURE, state_string='Deleted WebKitBuild directory (failure)')
478         return self.runStep()
479
480
481 class TestCompileWebKit(BuildStepMixinAdditions, unittest.TestCase):
482     def setUp(self):
483         self.longMessage = True
484         return self.setUpBuildStep()
485
486     def tearDown(self):
487         return self.tearDownBuildStep()
488
489     def test_success(self):
490         self.setupStep(CompileWebKit())
491         self.setProperty('fullPlatform', 'ios-simulator-11')
492         self.setProperty('configuration', 'release')
493         self.expectRemoteCommands(
494             ExpectShell(workdir='wkdir',
495                         logEnviron=False,
496                         command=['perl', 'Tools/Scripts/build-webkit', '--release'],
497                         )
498             + 0,
499         )
500         self.expectOutcome(result=SUCCESS, state_string='Compiled WebKit')
501         return self.runStep()
502
503     def test_failure(self):
504         self.setupStep(CompileWebKit())
505         self.setProperty('fullPlatform', 'mac-sierra')
506         self.setProperty('configuration', 'debug')
507         self.expectRemoteCommands(
508             ExpectShell(workdir='wkdir',
509                         logEnviron=False,
510                         command=['perl', 'Tools/Scripts/build-webkit', '--debug'],
511                         )
512             + ExpectShell.log('stdio', stdout='1 error generated.')
513             + 2,
514         )
515         self.expectOutcome(result=FAILURE, state_string='Compiled WebKit (failure)')
516         return self.runStep()
517
518
519 class TestCompileWebKitToT(BuildStepMixinAdditions, unittest.TestCase):
520     def setUp(self):
521         self.longMessage = True
522         return self.setUpBuildStep()
523
524     def tearDown(self):
525         return self.tearDownBuildStep()
526
527     def test_success(self):
528         self.setupStep(CompileWebKitToT())
529         self.setProperty('fullPlatform', 'ios-simulator-11')
530         self.setProperty('configuration', 'release')
531         self.setProperty('patchFailedToBuild', True)
532         self.expectRemoteCommands(
533             ExpectShell(workdir='wkdir',
534                         logEnviron=False,
535                         command=['perl', 'Tools/Scripts/build-webkit', '--release'],
536                         )
537             + 0,
538         )
539         self.expectOutcome(result=SUCCESS, state_string='Compiled WebKit')
540         return self.runStep()
541
542     def test_failure(self):
543         self.setupStep(CompileWebKitToT())
544         self.setProperty('fullPlatform', 'mac-sierra')
545         self.setProperty('configuration', 'debug')
546         self.setProperty('patchFailedTests', True)
547         self.expectRemoteCommands(
548             ExpectShell(workdir='wkdir',
549                         logEnviron=False,
550                         command=['perl', 'Tools/Scripts/build-webkit', '--debug'],
551                         )
552             + ExpectShell.log('stdio', stdout='1 error generated.')
553             + 2,
554         )
555         self.expectOutcome(result=FAILURE, state_string='Compiled WebKit (failure)')
556         return self.runStep()
557
558     def test_skip(self):
559         self.setupStep(CompileWebKitToT())
560         self.setProperty('fullPlatform', 'ios-simulator-11')
561         self.setProperty('configuration', 'release')
562         self.expectHidden(True)
563         self.expectOutcome(result=SKIPPED, state_string='Compiled WebKit (skipped)')
564         return self.runStep()
565
566
567 class TestAnalyzeCompileWebKitResults(BuildStepMixinAdditions, unittest.TestCase):
568     def setUp(self):
569         self.longMessage = True
570         return self.setUpBuildStep()
571
572     def tearDown(self):
573         return self.tearDownBuildStep()
574
575     def test_patch_with_build_failure(self):
576         previous_steps = [
577             mock_step(CompileWebKit(), results=FAILURE),
578             mock_step(CompileWebKitToT(), results=SUCCESS),
579         ]
580         self.setupStep(AnalyzeCompileWebKitResults(), previous_steps=previous_steps)
581         self.expectOutcome(result=FAILURE, state_string='Patch does not build (failure)')
582         return self.runStep()
583
584     def test_patch_with_ToT_failure(self):
585         previous_steps = [
586             mock_step(CompileWebKit(), results=FAILURE),
587             mock_step(CompileWebKitToT(), results=FAILURE),
588         ]
589         self.setupStep(AnalyzeCompileWebKitResults(), previous_steps=previous_steps)
590         self.expectOutcome(result=FAILURE, state_string='Unable to build WebKit without patch, retrying build (failure)')
591         return self.runStep()
592
593
594 class TestCompileJSCOnly(BuildStepMixinAdditions, unittest.TestCase):
595     def setUp(self):
596         self.longMessage = True
597         return self.setUpBuildStep()
598
599     def tearDown(self):
600         return self.tearDownBuildStep()
601
602     def test_success(self):
603         self.setupStep(CompileJSCOnly())
604         self.setProperty('fullPlatform', 'jsc-only')
605         self.setProperty('configuration', 'release')
606         self.expectRemoteCommands(
607             ExpectShell(workdir='wkdir',
608                         logEnviron=False,
609                         command=['perl', 'Tools/Scripts/build-jsc', '--release'],
610                         )
611             + 0,
612         )
613         self.expectOutcome(result=SUCCESS, state_string='Compiled JSC')
614         return self.runStep()
615
616     def test_failure(self):
617         self.setupStep(CompileJSCOnly())
618         self.setProperty('fullPlatform', 'jsc-only')
619         self.setProperty('configuration', 'debug')
620         self.expectRemoteCommands(
621             ExpectShell(workdir='wkdir',
622                         logEnviron=False,
623                         command=['perl', 'Tools/Scripts/build-jsc', '--debug'],
624                         )
625             + ExpectShell.log('stdio', stdout='1 error generated.')
626             + 2,
627         )
628         self.expectOutcome(result=FAILURE, state_string='Compiled JSC (failure)')
629         return self.runStep()
630
631
632 class TestCompileJSCOnlyToT(BuildStepMixinAdditions, unittest.TestCase):
633     def setUp(self):
634         self.longMessage = True
635         return self.setUpBuildStep()
636
637     def tearDown(self):
638         return self.tearDownBuildStep()
639
640     def test_success(self):
641         self.setupStep(CompileJSCOnlyToT())
642         self.setProperty('fullPlatform', 'jsc-only')
643         self.setProperty('configuration', 'release')
644         self.setProperty('patchFailedToBuild', 'True')
645         self.expectRemoteCommands(
646             ExpectShell(workdir='wkdir',
647                         logEnviron=False,
648                         command=['perl', 'Tools/Scripts/build-jsc', '--release'],
649                         )
650             + 0,
651         )
652         self.expectOutcome(result=SUCCESS, state_string='Compiled JSC')
653         return self.runStep()
654
655     def test_failure(self):
656         self.setupStep(CompileJSCOnlyToT())
657         self.setProperty('fullPlatform', 'jsc-only')
658         self.setProperty('configuration', 'debug')
659         self.setProperty('patchFailedToBuild', 'True')
660         self.expectRemoteCommands(
661             ExpectShell(workdir='wkdir',
662                         logEnviron=False,
663                         command=['perl', 'Tools/Scripts/build-jsc', '--debug'],
664                         )
665             + ExpectShell.log('stdio', stdout='1 error generated.')
666             + 2,
667         )
668         self.expectOutcome(result=FAILURE, state_string='Compiled JSC (failure)')
669         return self.runStep()
670
671     def test_skip(self):
672         self.setupStep(CompileJSCOnlyToT())
673         self.setProperty('fullPlatform', 'jsc-only')
674         self.setProperty('configuration', 'debug')
675         self.expectHidden(True)
676         self.expectOutcome(result=SKIPPED, state_string='Compiled JSC (skipped)')
677         return self.runStep()
678
679
680 class TestRunJavaScriptCoreTests(BuildStepMixinAdditions, unittest.TestCase):
681     def setUp(self):
682         self.longMessage = True
683         self.jsonFileName = 'jsc_results.json'
684         return self.setUpBuildStep()
685
686     def tearDown(self):
687         return self.tearDownBuildStep()
688
689     def test_success(self):
690         self.setupStep(RunJavaScriptCoreTests())
691         self.setProperty('fullPlatform', 'jsc-only')
692         self.setProperty('configuration', 'release')
693         self.expectRemoteCommands(
694             ExpectShell(workdir='wkdir',
695                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-build', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--release'],
696                         logfiles={'json': self.jsonFileName},
697                         )
698             + 0,
699         )
700         self.expectOutcome(result=SUCCESS, state_string='jscore-tests')
701         return self.runStep()
702
703     def test_failure(self):
704         self.setupStep(RunJavaScriptCoreTests())
705         self.setProperty('fullPlatform', 'jsc-only')
706         self.setProperty('configuration', 'debug')
707         self.expectRemoteCommands(
708             ExpectShell(workdir='wkdir',
709                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-build', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--debug'],
710                         logfiles={'json': self.jsonFileName},
711                         )
712             + ExpectShell.log('stdio', stdout='9 failures found.')
713             + 2,
714         )
715         self.expectOutcome(result=FAILURE, state_string='jscore-tests (failure)')
716         return self.runStep()
717
718
719 class TestReRunJavaScriptCoreTests(BuildStepMixinAdditions, unittest.TestCase):
720     def setUp(self):
721         self.longMessage = True
722         self.jsonFileName = 'jsc_results.json'
723         return self.setUpBuildStep()
724
725     def tearDown(self):
726         return self.tearDownBuildStep()
727
728     def test_success(self):
729         self.setupStep(ReRunJavaScriptCoreTests())
730         self.setProperty('fullPlatform', 'jsc-only')
731         self.setProperty('configuration', 'release')
732         self.setProperty('patchFailedTests', 'True')
733         self.expectRemoteCommands(
734             ExpectShell(workdir='wkdir',
735                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-build', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--release'],
736                         logfiles={'json': self.jsonFileName},
737                         )
738             + 0,
739         )
740         self.expectOutcome(result=SUCCESS, state_string='jscore-tests')
741         return self.runStep()
742
743     def test_failure(self):
744         self.setupStep(ReRunJavaScriptCoreTests())
745         self.setProperty('fullPlatform', 'jsc-only')
746         self.setProperty('configuration', 'debug')
747         self.setProperty('patchFailedTests', 'True')
748         self.expectRemoteCommands(
749             ExpectShell(workdir='wkdir',
750                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-build', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--debug'],
751                         logfiles={'json': self.jsonFileName},
752                         )
753             + ExpectShell.log('stdio', stdout='9 failures found.')
754             + 2,
755         )
756         self.expectOutcome(result=FAILURE, state_string='jscore-tests (failure)')
757         return self.runStep()
758
759     def test_skip(self):
760         self.setupStep(ReRunJavaScriptCoreTests())
761         self.setProperty('fullPlatform', 'jsc-only')
762         self.setProperty('configuration', 'debug')
763         self.expectHidden(True)
764         self.expectOutcome(result=SKIPPED, state_string='jscore-tests (skipped)')
765         return self.runStep()
766
767
768 class TestRunJavaScriptCoreTestsToT(BuildStepMixinAdditions, unittest.TestCase):
769     def setUp(self):
770         self.longMessage = True
771         self.jsonFileName = 'jsc_results.json'
772         return self.setUpBuildStep()
773
774     def tearDown(self):
775         return self.tearDownBuildStep()
776
777     def test_success(self):
778         self.setupStep(RunJavaScriptCoreTestsToT())
779         self.setProperty('fullPlatform', 'jsc-only')
780         self.setProperty('configuration', 'release')
781         self.setProperty('patchFailedTests', 'True')
782         self.expectRemoteCommands(
783             ExpectShell(workdir='wkdir',
784                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--release'],
785                         logfiles={'json': self.jsonFileName},
786                         )
787             + 0,
788         )
789         self.expectOutcome(result=SUCCESS, state_string='jscore-tests')
790         return self.runStep()
791
792     def test_failure(self):
793         self.setupStep(RunJavaScriptCoreTestsToT())
794         self.setProperty('fullPlatform', 'jsc-only')
795         self.setProperty('configuration', 'debug')
796         self.setProperty('patchFailedTests', 'True')
797         self.expectRemoteCommands(
798             ExpectShell(workdir='wkdir',
799                         command=['perl', 'Tools/Scripts/run-javascriptcore-tests', '--no-fail-fast', '--json-output={0}'.format(self.jsonFileName), '--debug'],
800                         logfiles={'json': self.jsonFileName},
801                         )
802             + ExpectShell.log('stdio', stdout='9 failures found.')
803             + 2,
804         )
805         self.expectOutcome(result=FAILURE, state_string='jscore-tests (failure)')
806         return self.runStep()
807
808     def test_skip(self):
809         self.setupStep(RunJavaScriptCoreTestsToT())
810         self.setProperty('fullPlatform', 'jsc-only')
811         self.setProperty('configuration', 'debug')
812         self.expectHidden(True)
813         self.expectOutcome(result=SKIPPED, state_string='jscore-tests (skipped)')
814         return self.runStep()
815
816
817 class TestRunWebKitTests(BuildStepMixinAdditions, unittest.TestCase):
818     def setUp(self):
819         self.longMessage = True
820         return self.setUpBuildStep()
821
822     def tearDown(self):
823         return self.tearDownBuildStep()
824
825     def test_success(self):
826         self.setupStep(RunWebKitTests())
827         self.setProperty('fullPlatform', 'ios-simulator')
828         self.setProperty('configuration', 'release')
829         self.expectRemoteCommands(
830             ExpectShell(workdir='wkdir',
831                         command=['python', 'Tools/Scripts/run-webkit-tests', '--no-build', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures', '30', '--skip-failing-tests', '--release', '--results-directory', 'layout-test-results', '--debug-rwt-logging'],
832                         )
833             + 0,
834         )
835         self.expectOutcome(result=SUCCESS, state_string='Passed layout tests')
836         return self.runStep()
837
838     def test_failure(self):
839         self.setupStep(RunWebKitTests())
840         self.setProperty('fullPlatform', 'ios-simulator')
841         self.setProperty('configuration', 'release')
842         self.expectRemoteCommands(
843             ExpectShell(workdir='wkdir',
844                         command=['python', 'Tools/Scripts/run-webkit-tests', '--no-build', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures', '30', '--skip-failing-tests', '--release', '--results-directory', 'layout-test-results', '--debug-rwt-logging'],
845                         )
846             + ExpectShell.log('stdio', stdout='9 failures found.')
847             + 2,
848         )
849         self.expectOutcome(result=FAILURE, state_string='layout-tests (failure)')
850         return self.runStep()
851
852
853 class TestRunWebKit1Tests(BuildStepMixinAdditions, unittest.TestCase):
854     def setUp(self):
855         self.longMessage = True
856         return self.setUpBuildStep()
857
858     def tearDown(self):
859         return self.tearDownBuildStep()
860
861     def test_success(self):
862         self.setupStep(RunWebKit1Tests())
863         self.setProperty('fullPlatform', 'ios-11')
864         self.setProperty('configuration', 'debug')
865         self.expectRemoteCommands(
866             ExpectShell(workdir='wkdir',
867                         command=['python', 'Tools/Scripts/run-webkit-tests', '--no-build', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures', '30', '--skip-failing-tests', '--debug', '--dump-render-tree', '--results-directory', 'layout-test-results', '--debug-rwt-logging'],
868                         )
869             + 0,
870         )
871         self.expectOutcome(result=SUCCESS, state_string='Passed layout tests')
872         return self.runStep()
873
874     def test_failure(self):
875         self.setupStep(RunWebKit1Tests())
876         self.setProperty('fullPlatform', 'ios-11')
877         self.setProperty('configuration', 'release')
878         self.expectRemoteCommands(
879             ExpectShell(workdir='wkdir',
880                         command=['python', 'Tools/Scripts/run-webkit-tests', '--no-build', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures', '30', '--skip-failing-tests', '--release', '--dump-render-tree', '--results-directory', 'layout-test-results', '--debug-rwt-logging'],
881                         )
882             + ExpectShell.log('stdio', stdout='9 failures found.')
883             + 2,
884         )
885         self.expectOutcome(result=FAILURE, state_string='layout-tests (failure)')
886         return self.runStep()
887
888
889 class TestCheckOutSpecificRevision(BuildStepMixinAdditions, unittest.TestCase):
890     def setUp(self):
891         self.longMessage = True
892         return self.setUpBuildStep()
893
894     def tearDown(self):
895         return self.tearDownBuildStep()
896
897     def test_success(self):
898         self.setupStep(CheckOutSpecificRevision())
899         self.setProperty('ews_revision', '1a3425cb92dbcbca12a10aa9514f1b77c76dc26')
900         self.expectHidden(False)
901         self.expectRemoteCommands(
902             ExpectShell(workdir='wkdir',
903                         timeout=1200,
904                         logEnviron=False,
905                         command=['git', 'checkout', '1a3425cb92dbcbca12a10aa9514f1b77c76dc26'],
906                         )
907             + 0,
908         )
909         self.expectOutcome(result=SUCCESS, state_string='Checked out required revision')
910         return self.runStep()
911
912     def test_failure(self):
913         self.setupStep(CheckOutSpecificRevision())
914         self.setProperty('ews_revision', '1a3425cb92dbcbca12a10aa9514f1b77c76dc26')
915         self.expectHidden(False)
916         self.expectRemoteCommands(
917             ExpectShell(workdir='wkdir',
918                         timeout=1200,
919                         logEnviron=False,
920                         command=['git', 'checkout', '1a3425cb92dbcbca12a10aa9514f1b77c76dc26'],
921                         )
922             + ExpectShell.log('stdio', stdout='Unexpected failure')
923             + 2,
924         )
925         self.expectOutcome(result=FAILURE, state_string='Checked out required revision (failure)')
926         return self.runStep()
927
928     def test_skip(self):
929         self.setupStep(CheckOutSpecificRevision())
930         self.expectHidden(True)
931         self.expectOutcome(result=SKIPPED, state_string='Checked out required revision (skipped)')
932         return self.runStep()
933
934
935 class TestCleanWorkingDirectory(BuildStepMixinAdditions, unittest.TestCase):
936     def setUp(self):
937         self.longMessage = True
938         return self.setUpBuildStep()
939
940     def tearDown(self):
941         return self.tearDownBuildStep()
942
943     def test_success(self):
944         self.setupStep(CleanWorkingDirectory())
945         self.expectRemoteCommands(
946             ExpectShell(workdir='wkdir',
947                         logEnviron=False,
948                         command=['Tools/Scripts/clean-webkit'],
949                         )
950             + 0,
951         )
952         self.expectOutcome(result=SUCCESS, state_string='Cleaned working directory')
953         return self.runStep()
954
955     def test_failure(self):
956         self.setupStep(CleanWorkingDirectory())
957         self.expectRemoteCommands(
958             ExpectShell(workdir='wkdir',
959                         logEnviron=False,
960                         command=['Tools/Scripts/clean-webkit'],
961                         )
962             + ExpectShell.log('stdio', stdout='Unexpected failure.')
963             + 2,
964         )
965         self.expectOutcome(result=FAILURE, state_string='Cleaned working directory (failure)')
966         return self.runStep()
967
968
969 class TestUnApplyPatchIfRequired(BuildStepMixinAdditions, unittest.TestCase):
970     def setUp(self):
971         self.longMessage = True
972         return self.setUpBuildStep()
973
974     def tearDown(self):
975         return self.tearDownBuildStep()
976
977     def test_success(self):
978         self.setupStep(UnApplyPatchIfRequired())
979         self.setProperty('patchFailedToBuild', True)
980         self.expectHidden(False)
981         self.expectRemoteCommands(
982             ExpectShell(workdir='wkdir',
983                         logEnviron=False,
984                         command=['Tools/Scripts/clean-webkit'],
985                         )
986             + 0,
987         )
988         self.expectOutcome(result=SUCCESS, state_string='Unapplied patch')
989         return self.runStep()
990
991     def test_failure(self):
992         self.setupStep(UnApplyPatchIfRequired())
993         self.setProperty('patchFailedTests', True)
994         self.expectHidden(False)
995         self.expectRemoteCommands(
996             ExpectShell(workdir='wkdir',
997                         logEnviron=False,
998                         command=['Tools/Scripts/clean-webkit'],
999                         )
1000             + ExpectShell.log('stdio', stdout='Unexpected failure.')
1001             + 2,
1002         )
1003         self.expectOutcome(result=FAILURE, state_string='Unapplied patch (failure)')
1004         return self.runStep()
1005
1006     def test_skip(self):
1007         self.setupStep(UnApplyPatchIfRequired())
1008         self.expectHidden(True)
1009         self.expectOutcome(result=SKIPPED, state_string='Unapplied patch (skipped)')
1010         return self.runStep()
1011
1012
1013 class TestArchiveBuiltProduct(BuildStepMixinAdditions, unittest.TestCase):
1014     def setUp(self):
1015         self.longMessage = True
1016         return self.setUpBuildStep()
1017
1018     def tearDown(self):
1019         return self.tearDownBuildStep()
1020
1021     def test_success(self):
1022         self.setupStep(ArchiveBuiltProduct())
1023         self.setProperty('fullPlatform', 'ios-simulator')
1024         self.setProperty('configuration', 'release')
1025         self.expectRemoteCommands(
1026             ExpectShell(workdir='wkdir',
1027                         logEnviron=False,
1028                         command=['python', 'Tools/BuildSlaveSupport/built-product-archive', '--platform=ios-simulator',  '--release', 'archive'],
1029                         )
1030             + 0,
1031         )
1032         self.expectOutcome(result=SUCCESS, state_string='Archived built product')
1033         return self.runStep()
1034
1035     def test_failure(self):
1036         self.setupStep(ArchiveBuiltProduct())
1037         self.setProperty('fullPlatform', 'mac-sierra')
1038         self.setProperty('configuration', 'debug')
1039         self.expectRemoteCommands(
1040             ExpectShell(workdir='wkdir',
1041                         logEnviron=False,
1042                         command=['python', 'Tools/BuildSlaveSupport/built-product-archive', '--platform=mac-sierra',  '--debug', 'archive'],
1043                         )
1044             + ExpectShell.log('stdio', stdout='Unexpected failure.')
1045             + 2,
1046         )
1047         self.expectOutcome(result=FAILURE, state_string='Archived built product (failure)')
1048         return self.runStep()
1049
1050
1051 class TestUploadBuiltProduct(BuildStepMixinAdditions, unittest.TestCase):
1052     def setUp(self):
1053         self.longMessage = True
1054         return self.setUpBuildStep()
1055
1056     def tearDown(self):
1057         return self.tearDownBuildStep()
1058
1059     def test_success(self):
1060         self.setupStep(UploadBuiltProduct())
1061         self.setProperty('fullPlatform', 'mac-sierra')
1062         self.setProperty('configuration', 'release')
1063         self.setProperty('architecture', 'x86_64')
1064         self.setProperty('patch_id', '1234')
1065         self.expectHidden(False)
1066         self.expectRemoteCommands(
1067             Expect('uploadFile', dict(
1068                                         workersrc='WebKitBuild/release.zip', workdir='wkdir',
1069                                         blocksize=1024 * 256, maxsize=None, keepstamp=False,
1070                                         writer=ExpectRemoteRef(remotetransfer.FileWriter),
1071                                      ))
1072             + Expect.behavior(uploadFileWithContentsOfString('Dummy zip file content.'))
1073             + 0,
1074         )
1075         self.expectUploadedFile('public_html/archives/mac-sierra-x86_64-release/1234.zip')
1076
1077         self.expectOutcome(result=SUCCESS, state_string='Uploaded built product')
1078         return self.runStep()
1079
1080     def test_failure(self):
1081         self.setupStep(UploadBuiltProduct())
1082         self.setProperty('fullPlatform', 'mac-sierra')
1083         self.setProperty('configuration', 'release')
1084         self.setProperty('architecture', 'x86_64')
1085         self.setProperty('patch_id', '1234')
1086         self.expectHidden(False)
1087         self.expectRemoteCommands(
1088             Expect('uploadFile', dict(
1089                                         workersrc='WebKitBuild/release.zip', workdir='wkdir',
1090                                         blocksize=1024 * 256, maxsize=None, keepstamp=False,
1091                                         writer=ExpectRemoteRef(remotetransfer.FileWriter),
1092                                      ))
1093             + Expect.behavior(uploadFileWithContentsOfString('Dummy zip file content.'))
1094             + 1,
1095         )
1096         self.expectUploadedFile('public_html/archives/mac-sierra-x86_64-release/1234.zip')
1097
1098         self.expectOutcome(result=FAILURE, state_string='Failed to upload built product')
1099         return self.runStep()
1100
1101
1102 class TestDownloadBuiltProduct(BuildStepMixinAdditions, unittest.TestCase):
1103     def setUp(self):
1104         self.longMessage = True
1105         return self.setUpBuildStep()
1106
1107     def tearDown(self):
1108         return self.tearDownBuildStep()
1109
1110     def test_success(self):
1111         self.setupStep(DownloadBuiltProduct())
1112         self.setProperty('fullPlatform', 'ios-simulator-12')
1113         self.setProperty('configuration', 'release')
1114         self.setProperty('architecture', 'x86_64')
1115         self.setProperty('patch_id', '1234')
1116         self.expectRemoteCommands(
1117             ExpectShell(workdir='wkdir',
1118                         logEnviron=False,
1119                         command=['python', 'Tools/BuildSlaveSupport/download-built-product', '--release', 'https://s3-us-west-2.amazonaws.com/ews-archives.webkit.org/ios-simulator-12-x86_64-release/1234.zip'],
1120                         )
1121             + 0,
1122         )
1123         self.expectOutcome(result=SUCCESS, state_string='Downloaded built product')
1124         return self.runStep()
1125
1126     def test_failure(self):
1127         self.setupStep(DownloadBuiltProduct())
1128         self.setProperty('fullPlatform', 'mac-sierra')
1129         self.setProperty('configuration', 'debug')
1130         self.setProperty('architecture', 'x86_64')
1131         self.setProperty('patch_id', '123456')
1132         self.expectRemoteCommands(
1133             ExpectShell(workdir='wkdir',
1134                         logEnviron=False,
1135                         command=['python', 'Tools/BuildSlaveSupport/download-built-product', '--debug', 'https://s3-us-west-2.amazonaws.com/ews-archives.webkit.org/mac-sierra-x86_64-debug/123456.zip'],
1136                         )
1137             + ExpectShell.log('stdio', stdout='Unexpected failure.')
1138             + 2,
1139         )
1140         self.expectOutcome(result=FAILURE, state_string='Failed to download built product from S3')
1141         return self.runStep()
1142
1143
1144 class TestExtractBuiltProduct(BuildStepMixinAdditions, unittest.TestCase):
1145     def setUp(self):
1146         self.longMessage = True
1147         return self.setUpBuildStep()
1148
1149     def tearDown(self):
1150         return self.tearDownBuildStep()
1151
1152     def test_success(self):
1153         self.setupStep(ExtractBuiltProduct())
1154         self.setProperty('fullPlatform', 'ios-simulator')
1155         self.setProperty('configuration', 'release')
1156         self.expectRemoteCommands(
1157             ExpectShell(workdir='wkdir',
1158                         logEnviron=False,
1159                         command=['python', 'Tools/BuildSlaveSupport/built-product-archive', '--platform=ios-simulator',  '--release', 'extract'],
1160                         )
1161             + 0,
1162         )
1163         self.expectOutcome(result=SUCCESS, state_string='Extracted built product')
1164         return self.runStep()
1165
1166     def test_failure(self):
1167         self.setupStep(ExtractBuiltProduct())
1168         self.setProperty('fullPlatform', 'mac-sierra')
1169         self.setProperty('configuration', 'debug')
1170         self.expectRemoteCommands(
1171             ExpectShell(workdir='wkdir',
1172                         logEnviron=False,
1173                         command=['python', 'Tools/BuildSlaveSupport/built-product-archive', '--platform=mac-sierra',  '--debug', 'extract'],
1174                         )
1175             + ExpectShell.log('stdio', stdout='Unexpected failure.')
1176             + 2,
1177         )
1178         self.expectOutcome(result=FAILURE, state_string='Extracted built product (failure)')
1179         return self.runStep()
1180
1181
1182 class TestTransferToS3(BuildStepMixinAdditions, unittest.TestCase):
1183     def setUp(self):
1184         self.longMessage = True
1185         return self.setUpBuildStep()
1186
1187     def tearDown(self):
1188         return self.tearDownBuildStep()
1189
1190     def test_success(self):
1191         self.setupStep(TransferToS3())
1192         self.setProperty('fullPlatform', 'mac-highsierra')
1193         self.setProperty('configuration', 'release')
1194         self.setProperty('architecture', 'x86_64')
1195         self.setProperty('patch_id', '1234')
1196         self.expectLocalCommands(
1197             ExpectMasterShellCommand(command=['python',
1198                                               '../Shared/transfer-archive-to-s3',
1199                                               '--patch_id', '1234',
1200                                               '--identifier', 'mac-highsierra-x86_64-release',
1201                                               '--archive', 'public_html/archives/mac-highsierra-x86_64-release/1234.zip',
1202                                              ])
1203             + 0,
1204         )
1205         self.expectOutcome(result=SUCCESS, state_string='Transferred archive to S3')
1206         return self.runStep()
1207
1208     def test_failure(self):
1209         self.setupStep(TransferToS3())
1210         self.setProperty('fullPlatform', 'ios-simulator-12')
1211         self.setProperty('configuration', 'debug')
1212         self.setProperty('architecture', 'x86_64')
1213         self.setProperty('patch_id', '1234')
1214         self.expectLocalCommands(
1215             ExpectMasterShellCommand(command=['python',
1216                                               '../Shared/transfer-archive-to-s3',
1217                                               '--patch_id', '1234',
1218                                               '--identifier', 'ios-simulator-12-x86_64-debug',
1219                                               '--archive', 'public_html/archives/ios-simulator-12-x86_64-debug/1234.zip',
1220                                              ])
1221             + 2,
1222         )
1223         self.expectOutcome(result=FAILURE, state_string='Failed to transfer archive to S3')
1224         return self.runStep()
1225
1226
1227 class TestRunAPITests(BuildStepMixinAdditions, unittest.TestCase):
1228     def setUp(self):
1229         self.longMessage = True
1230         self.jsonFileName = 'api_test_results.json'
1231         return self.setUpBuildStep()
1232
1233     def tearDown(self):
1234         return self.tearDownBuildStep()
1235
1236     def test_success_mac(self):
1237         self.setupStep(RunAPITests())
1238         self.setProperty('fullPlatform', 'mac-mojave')
1239         self.setProperty('platform', 'mac')
1240         self.setProperty('configuration', 'release')
1241
1242         self.expectRemoteCommands(
1243             ExpectShell(workdir='wkdir',
1244                         logEnviron=False,
1245                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--release', '--verbose', '--json-output={0}'.format(self.jsonFileName)],
1246                         logfiles={'json': self.jsonFileName},
1247                         )
1248             + ExpectShell.log('stdio', stdout='''...
1249 worker/0 TestWTF.WTF_Variant.OperatorAmpersand Passed
1250 worker/0 TestWTF.WTF_Variant.Ref Passed
1251 worker/0 TestWTF.WTF_Variant.RefPtr Passed
1252 worker/0 TestWTF.WTF_Variant.RetainPtr Passed
1253 worker/0 TestWTF.WTF_Variant.VisitorUsingMakeVisitor Passed
1254 worker/0 TestWTF.WTF_Variant.VisitorUsingSwitchOn Passed
1255 Ran 1888 tests of 1888 with 1888 successful
1256 ------------------------------
1257 All tests successfully passed!
1258 ''')
1259             + 0,
1260         )
1261         self.expectOutcome(result=SUCCESS, state_string='run-api-tests')
1262         return self.runStep()
1263
1264     def test_success_ios_simulator(self):
1265         self.setupStep(RunAPITests())
1266         self.setProperty('fullPlatform', 'ios-simulator-11')
1267         self.setProperty('platform', 'ios')
1268         self.setProperty('configuration', 'debug')
1269
1270         self.expectRemoteCommands(
1271             ExpectShell(workdir='wkdir',
1272                         logEnviron=False,
1273                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--debug', '--verbose', '--json-output={0}'.format(self.jsonFileName), '--ios-simulator'],
1274                         logfiles={'json': self.jsonFileName},
1275                         )
1276             + ExpectShell.log('stdio', stdout='''...
1277 worker/0 TestWTF.WTF_Variant.OperatorAmpersand Passed
1278 worker/0 TestWTF.WTF_Variant.Ref Passed
1279 worker/0 TestWTF.WTF_Variant.RefPtr Passed
1280 worker/0 TestWTF.WTF_Variant.RetainPtr Passed
1281 worker/0 TestWTF.WTF_Variant.VisitorUsingMakeVisitor Passed
1282 worker/0 TestWTF.WTF_Variant.VisitorUsingSwitchOn Passed
1283 Ran 1888 tests of 1888 with 1888 successful
1284 ------------------------------
1285 All tests successfully passed!
1286 ''')
1287             + 0,
1288         )
1289         self.expectOutcome(result=SUCCESS, state_string='run-api-tests')
1290         return self.runStep()
1291
1292     def test_one_failure(self):
1293         self.setupStep(RunAPITests())
1294         self.setProperty('fullPlatform', 'mac-mojave')
1295         self.setProperty('platform', 'mac')
1296         self.setProperty('configuration', 'debug')
1297
1298         self.expectRemoteCommands(
1299             ExpectShell(workdir='wkdir',
1300                         logEnviron=False,
1301                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--debug', '--verbose', '--json-output={0}'.format(self.jsonFileName)],
1302                         logfiles={'json': self.jsonFileName},
1303                         )
1304             + ExpectShell.log('stdio', stdout='''
1305 worker/0 TestWTF.WTF_Variant.OperatorAmpersand Passed
1306 worker/0 TestWTF.WTF_Variant.Ref Passed
1307 worker/0 TestWTF.WTF_Variant.RefPtr Passed
1308 worker/0 TestWTF.WTF_Variant.RetainPtr Passed
1309 worker/0 TestWTF.WTF_Variant.VisitorUsingMakeVisitor Passed
1310 worker/0 TestWTF.WTF_Variant.VisitorUsingSwitchOn Passed
1311 worker/0 exiting
1312 Ran 1888 tests of 1888 with 1887 successful
1313 ------------------------------
1314 Test suite failed
1315
1316 Crashed
1317
1318     TestWTF.WTF.StringConcatenate_Unsigned
1319         **FAIL** WTF.StringConcatenate_Unsigned
1320
1321         Tools\\TestWebKitAPI\\Tests\\WTF\\StringConcatenate.cpp:84
1322         Value of: makeString('hello ', static_cast<unsigned short>(42) , ' world')
1323           Actual: hello 42 world
1324         Expected: 'hello * world'
1325         Which is: 74B00C9C
1326
1327 Testing completed, Exit status: 3
1328 ''')
1329             + 1,
1330         )
1331         self.expectOutcome(result=FAILURE, state_string='1 api test failed or timed out (failure)')
1332         return self.runStep()
1333
1334     def test_multiple_failures_and_timeouts(self):
1335         self.setupStep(RunAPITests())
1336         self.setProperty('fullPlatform', 'mac-mojave')
1337         self.setProperty('platform', 'mac')
1338         self.setProperty('configuration', 'debug')
1339
1340         self.expectRemoteCommands(
1341             ExpectShell(workdir='wkdir',
1342                         logEnviron=False,
1343                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--debug', '--verbose', '--json-output={0}'.format(self.jsonFileName)],
1344                         logfiles={'json': self.jsonFileName},
1345                         )
1346             + ExpectShell.log('stdio', stdout='''...
1347 worker/0 TestWTF.WTF_Variant.OperatorAmpersand Passed
1348 worker/0 TestWTF.WTF_Variant.Ref Passed
1349 worker/0 TestWTF.WTF_Variant.RefPtr Passed
1350 worker/0 TestWTF.WTF_Variant.RetainPtr Passed
1351 worker/0 TestWTF.WTF_Variant.VisitorUsingMakeVisitor Passed
1352 worker/0 TestWTF.WTF_Variant.VisitorUsingSwitchOn Passed
1353 worker/0 exiting
1354 Ran 1888 tests of 1888 with 1884 successful
1355 ------------------------------
1356 Test suite failed
1357
1358 Failed
1359
1360     TestWTF.WTF.StringConcatenate_Unsigned
1361         **FAIL** WTF.StringConcatenate_Unsigned
1362
1363         Tools\\TestWebKitAPI\\Tests\\WTF\\StringConcatenate.cpp:84
1364         Value of: makeString('hello ', static_cast<unsigned short>(42) , ' world')
1365           Actual: hello 42 world
1366         Expected: 'hello * world'
1367         Which is: 74B00C9C
1368
1369     TestWTF.WTF_Expected.Unexpected
1370         **FAIL** WTF_Expected.Unexpected
1371
1372         Tools\TestWebKitAPI\Tests\WTF\Expected.cpp:96
1373         Value of: s1
1374           Actual: oops
1375         Expected: s0
1376         Which is: oops
1377
1378 Timeout
1379
1380     TestWTF.WTF_PoisonedUniquePtrForTriviallyDestructibleArrays.Assignment
1381     TestWTF.WTF_Lock.ContendedShortSection
1382
1383 Testing completed, Exit status: 3
1384 ''')
1385             + 4,
1386         )
1387         self.expectOutcome(result=FAILURE, state_string='4 api tests failed or timed out (failure)')
1388         return self.runStep()
1389
1390     def test_unexpected_failure(self):
1391         self.setupStep(RunAPITests())
1392         self.setProperty('fullPlatform', 'mac-mojave')
1393         self.setProperty('platform', 'mac')
1394         self.setProperty('configuration', 'debug')
1395
1396         self.expectRemoteCommands(
1397             ExpectShell(workdir='wkdir',
1398                         logEnviron=False,
1399                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--debug', '--verbose', '--json-output={0}'.format(self.jsonFileName)],
1400                         logfiles={'json': self.jsonFileName},
1401                         )
1402             + ExpectShell.log('stdio', stdout='Unexpected failure. Failed to run api tests.')
1403             + 2,
1404         )
1405         self.expectOutcome(result=FAILURE, state_string='run-api-tests (failure)')
1406         return self.runStep()
1407
1408     def test_no_failures_or_timeouts_with_disabled(self):
1409         self.setupStep(RunAPITests())
1410         self.setProperty('fullPlatform', 'mac-mojave')
1411         self.setProperty('platform', 'mac')
1412         self.setProperty('configuration', 'debug')
1413
1414         self.expectRemoteCommands(
1415             ExpectShell(workdir='wkdir',
1416                         logEnviron=False,
1417                         command=['python', 'Tools/Scripts/run-api-tests', '--no-build', '--debug', '--verbose', '--json-output={0}'.format(self.jsonFileName)],
1418                         logfiles={'json': self.jsonFileName},
1419                         )
1420             + ExpectShell.log('stdio', stdout='''...
1421 worker/0 TestWTF.WTF_Variant.OperatorAmpersand Passed
1422 worker/0 TestWTF.WTF_Variant.Ref Passed
1423 worker/0 TestWTF.WTF_Variant.RefPtr Passed
1424 worker/0 TestWTF.WTF_Variant.RetainPtr Passed
1425 worker/0 TestWTF.WTF_Variant.VisitorUsingMakeVisitor Passed
1426 worker/0 TestWTF.WTF_Variant.VisitorUsingSwitchOn Passed
1427 worker/0 exiting
1428 Ran 1881 tests of 1888 with 1881 successful
1429 ------------------------------
1430 All tests successfully passed!
1431 ''')
1432             + 0,
1433         )
1434         self.expectOutcome(result=SUCCESS, state_string='run-api-tests')
1435         return self.runStep()
1436
1437
1438 class TestArchiveTestResults(BuildStepMixinAdditions, unittest.TestCase):
1439     def setUp(self):
1440         self.longMessage = True
1441         return self.setUpBuildStep()
1442
1443     def tearDown(self):
1444         return self.tearDownBuildStep()
1445
1446     def test_success(self):
1447         self.setupStep(ArchiveTestResults())
1448         self.setProperty('fullPlatform', 'ios-simulator')
1449         self.setProperty('platform', 'ios-simulator')
1450         self.setProperty('configuration', 'release')
1451         self.expectRemoteCommands(
1452             ExpectShell(workdir='wkdir',
1453                         logEnviron=False,
1454                         command=['python', 'Tools/BuildSlaveSupport/test-result-archive', '--platform=ios-simulator',  '--release', 'archive'],
1455                         )
1456             + 0,
1457         )
1458         self.expectOutcome(result=SUCCESS, state_string='Archived test results')
1459         return self.runStep()
1460
1461     def test_failure(self):
1462         self.setupStep(ArchiveTestResults())
1463         self.setProperty('fullPlatform', 'mac-mojave')
1464         self.setProperty('platform', 'mac')
1465         self.setProperty('configuration', 'debug')
1466         self.expectRemoteCommands(
1467             ExpectShell(workdir='wkdir',
1468                         logEnviron=False,
1469                         command=['python', 'Tools/BuildSlaveSupport/test-result-archive', '--platform=mac',  '--debug', 'archive'],
1470                         )
1471             + ExpectShell.log('stdio', stdout='Unexpected failure.')
1472             + 2,
1473         )
1474         self.expectOutcome(result=FAILURE, state_string='Archived test results (failure)')
1475         return self.runStep()
1476
1477
1478 class TestUploadTestResults(BuildStepMixinAdditions, unittest.TestCase):
1479     def setUp(self):
1480         self.longMessage = True
1481         return self.setUpBuildStep()
1482
1483     def tearDown(self):
1484         return self.tearDownBuildStep()
1485
1486     def test_success(self):
1487         self.setupStep(UploadTestResults())
1488         self.setProperty('configuration', 'release')
1489         self.setProperty('architecture', 'x86_64')
1490         self.setProperty('patch_id', '1234')
1491         self.setProperty('buildername', 'macOS-Sierra-Release-WK2-Tests-EWS')
1492         self.setProperty('buildnumber', '12')
1493         self.expectHidden(False)
1494         self.expectRemoteCommands(
1495             Expect('uploadFile', dict(
1496                                         workersrc='layout-test-results.zip', workdir='wkdir',
1497                                         blocksize=1024 * 256, maxsize=None, keepstamp=False,
1498                                         writer=ExpectRemoteRef(remotetransfer.FileWriter),
1499                                      ))
1500             + Expect.behavior(uploadFileWithContentsOfString('Dummy zip file content.'))
1501             + 0,
1502         )
1503         self.expectUploadedFile('public_html/results/macOS-Sierra-Release-WK2-Tests-EWS/r1234-12.zip')
1504
1505         self.expectOutcome(result=SUCCESS, state_string='Uploaded test results')
1506         return self.runStep()
1507
1508     def test_success_with_identifier(self):
1509         self.setupStep(UploadTestResults(identifier='clean-tree'))
1510         self.setProperty('configuration', 'release')
1511         self.setProperty('architecture', 'x86_64')
1512         self.setProperty('patch_id', '271211')
1513         self.setProperty('buildername', 'iOS-12-Simulator-WK2-Tests-EWS')
1514         self.setProperty('buildnumber', '120')
1515         self.expectHidden(False)
1516         self.expectRemoteCommands(
1517             Expect('uploadFile', dict(
1518                                         workersrc='layout-test-results.zip', workdir='wkdir',
1519                                         blocksize=1024 * 256, maxsize=None, keepstamp=False,
1520                                         writer=ExpectRemoteRef(remotetransfer.FileWriter),
1521                                      ))
1522             + Expect.behavior(uploadFileWithContentsOfString('Dummy zip file content.'))
1523             + 0,
1524         )
1525         self.expectUploadedFile('public_html/results/iOS-12-Simulator-WK2-Tests-EWS/r271211-120-clean-tree.zip')
1526
1527         self.expectOutcome(result=SUCCESS, state_string='Uploaded test results')
1528         return self.runStep()
1529
1530
1531 class TestExtractTestResults(BuildStepMixinAdditions, unittest.TestCase):
1532     def setUp(self):
1533         self.longMessage = True
1534         return self.setUpBuildStep()
1535
1536     def tearDown(self):
1537         return self.tearDownBuildStep()
1538
1539     def test_success(self):
1540         self.setupStep(ExtractTestResults())
1541         self.setProperty('configuration', 'release')
1542         self.setProperty('patch_id', '1234')
1543         self.setProperty('buildername', 'macOS-Sierra-Release-WK2-Tests-EWS')
1544         self.setProperty('buildnumber', '12')
1545         self.expectLocalCommands(
1546             ExpectMasterShellCommand(command=['unzip',
1547                                               'public_html/results/macOS-Sierra-Release-WK2-Tests-EWS/r1234-12.zip',
1548                                               '-d',
1549                                               'public_html/results/macOS-Sierra-Release-WK2-Tests-EWS/r1234-12',
1550                                              ])
1551             + 0,
1552         )
1553         self.expectOutcome(result=SUCCESS, state_string='Extracted test results')
1554         self.expectAddedURLs([call('view layout test results', '/results/test/r2468_ab1a28b4feee0d42973c7c05335b35bca927e974 (1)/results.html')])
1555         return self.runStep()
1556
1557     def test_success_with_identifier(self):
1558         self.setupStep(ExtractTestResults(identifier='rerun'))
1559         self.setProperty('configuration', 'release')
1560         self.setProperty('patch_id', '1234')
1561         self.setProperty('buildername', 'iOS-12-Simulator-WK2-Tests-EWS')
1562         self.setProperty('buildnumber', '12')
1563         self.expectLocalCommands(
1564             ExpectMasterShellCommand(command=['unzip',
1565                                               'public_html/results/iOS-12-Simulator-WK2-Tests-EWS/r1234-12-rerun.zip',
1566                                               '-d',
1567                                               'public_html/results/iOS-12-Simulator-WK2-Tests-EWS/r1234-12-rerun',
1568                                              ])
1569             + 0,
1570         )
1571         self.expectOutcome(result=SUCCESS, state_string='Extracted test results')
1572         self.expectAddedURLs([call('view layout test results', '/results/test/r2468_ab1a28b4feee0d42973c7c05335b35bca927e974 (1)/results.html')])
1573         return self.runStep()
1574
1575     def test_failure(self):
1576         self.setupStep(ExtractTestResults())
1577         self.setProperty('configuration', 'debug')
1578         self.setProperty('patch_id', '1234')
1579         self.setProperty('buildername', 'macOS-Sierra-Release-WK2-Tests-EWS')
1580         self.setProperty('buildnumber', '12')
1581         self.expectLocalCommands(
1582             ExpectMasterShellCommand(command=['unzip',
1583                                               'public_html/results/macOS-Sierra-Release-WK2-Tests-EWS/r1234-12.zip',
1584                                               '-d',
1585                                               'public_html/results/macOS-Sierra-Release-WK2-Tests-EWS/r1234-12',
1586                                              ])
1587             + 2,
1588         )
1589         self.expectOutcome(result=FAILURE, state_string='failed (2) (failure)')
1590         self.expectAddedURLs([call('view layout test results', '/results/test/r2468_ab1a28b4feee0d42973c7c05335b35bca927e974 (1)/results.html')])
1591         return self.runStep()
1592
1593
1594 class TestPrintConfiguration(BuildStepMixinAdditions, unittest.TestCase):
1595     def setUp(self):
1596         self.longMessage = True
1597         return self.setUpBuildStep()
1598
1599     def tearDown(self):
1600         return self.tearDownBuildStep()
1601
1602     def test_success_mac(self):
1603         self.setupStep(PrintConfiguration())
1604         self.setProperty('buildername', 'macOS-High-Sierra-Release-WK2-Tests-EWS')
1605         self.setProperty('platform', 'mac-highsierra')
1606
1607         self.expectRemoteCommands(
1608             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1609             + ExpectShell.log('stdio', stdout='ews150.apple.com'),
1610             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1611             + ExpectShell.log('stdio', stdout='''Filesystem     Size   Used  Avail Capacity iused  ifree %iused  Mounted on
1612 /dev/disk1s1  119Gi   95Gi   23Gi    81%  937959 9223372036853837848    0%   /
1613 /dev/disk1s4  119Gi   20Ki   23Gi     1%       0 9223372036854775807    0%   /private/var/vm
1614 /dev/disk0s3  119Gi   22Gi   97Gi    19%  337595          4294629684    0%   /Volumes/Data'''),
1615             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1616             + ExpectShell.log('stdio', stdout='Tue Apr  9 15:30:52 PDT 2019'),
1617             ExpectShell(command=['sw_vers'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1618             + ExpectShell.log('stdio', stdout='''ProductName:   Mac OS X
1619 ProductVersion: 10.13.4
1620 BuildVersion:   17E199'''),
1621             ExpectShell(command=['xcodebuild', '-sdk', '-version'], workdir='wkdir', timeout=60, logEnviron=False)
1622             + ExpectShell.log('stdio', stdout='''MacOSX10.13.sdk - macOS 10.13 (macosx10.13)
1623 SDKVersion: 10.13
1624 Path: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk
1625 PlatformVersion: 1.1
1626 PlatformPath: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform
1627 ProductBuildVersion: 17E189
1628 ProductCopyright: 1983-2018 Apple Inc.
1629 ProductName: Mac OS X
1630 ProductUserVisibleVersion: 10.13.4
1631 ProductVersion: 10.13.4
1632
1633 Xcode 9.4.1
1634 Build version 9F2000''')
1635             + 0,
1636         )
1637         self.expectOutcome(result=SUCCESS, state_string='OS: High Sierra (10.13.4), Xcode: 9.4.1')
1638         return self.runStep()
1639
1640     def test_success_ios_simulator(self):
1641         self.setupStep(PrintConfiguration())
1642         self.setProperty('buildername', 'macOS-Sierra-Release-WK2-Tests-EWS')
1643         self.setProperty('platform', 'ios-simulator-12')
1644
1645         self.expectRemoteCommands(
1646             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1647             + ExpectShell.log('stdio', stdout='ews152.apple.com'),
1648             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1649             + ExpectShell.log('stdio', stdout='''Filesystem     Size   Used  Avail Capacity iused  ifree %iused  Mounted on
1650 /dev/disk1s1  119Gi   95Gi   23Gi    81%  937959 9223372036853837848    0%   /
1651 /dev/disk1s4  119Gi   20Ki   23Gi     1%       0 9223372036854775807    0%   /private/var/vm
1652 /dev/disk0s3  119Gi   22Gi   97Gi    19%  337595          4294629684    0%   /Volumes/Data'''),
1653             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1654             + ExpectShell.log('stdio', stdout='Tue Apr  9 15:30:52 PDT 2019'),
1655             ExpectShell(command=['sw_vers'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1656             + ExpectShell.log('stdio', stdout='''ProductName:   Mac OS X
1657 ProductVersion: 10.14.5
1658 BuildVersion:   18F132'''),
1659             ExpectShell(command=['xcodebuild', '-sdk', '-version'], workdir='wkdir', timeout=60, logEnviron=False)
1660             + ExpectShell.log('stdio', stdout='''iPhoneSimulator12.2.sdk - Simulator - iOS 12.2 (iphonesimulator12.2)
1661 SDKVersion: 12.2
1662 Path: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.2.sdk
1663 PlatformVersion: 12.2
1664 PlatformPath: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform
1665 BuildID: 15C4BAF8-4632-11E9-86EB-BA47F1FFAC3C
1666 ProductBuildVersion: 16E226
1667 ProductCopyright: 1983-2019 Apple Inc.
1668 ProductName: iPhone OS
1669 ProductVersion: 12.2
1670
1671 Xcode 10.2
1672 Build version 10E125''')
1673             + 0,
1674         )
1675         self.expectOutcome(result=SUCCESS, state_string='OS: Mojave (10.14.5), Xcode: 10.2')
1676         return self.runStep()
1677
1678     def test_success_webkitpy(self):
1679         self.setupStep(PrintConfiguration())
1680         self.setProperty('platform', '*')
1681
1682         self.expectRemoteCommands(
1683             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1684             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1685             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1686             ExpectShell(command=['sw_vers'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1687             + ExpectShell.log('stdio', stdout='''ProductName:   Mac OS X
1688 ProductVersion: 10.13.6
1689 BuildVersion:   17G7024'''),
1690             ExpectShell(command=['xcodebuild', '-sdk', '-version'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1691             + ExpectShell.log('stdio', stdout='''Xcode 10.2\nBuild version 10E125'''),
1692         )
1693         self.expectOutcome(result=SUCCESS, state_string='OS: High Sierra (10.13.6), Xcode: 10.2')
1694         return self.runStep()
1695
1696     def test_success_linux_wpe(self):
1697         self.setupStep(PrintConfiguration())
1698         self.setProperty('platform', 'wpe')
1699
1700         self.expectRemoteCommands(
1701             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1702             + ExpectShell.log('stdio', stdout='ews190'),
1703             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1704             + ExpectShell.log('stdio', stdout='''Filesystem     Size   Used  Avail Capacity iused  ifree %iused  Mounted on
1705 /dev/disk0s3  119Gi   22Gi   97Gi    19%  337595          4294629684    0%   /'''),
1706             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1707             + ExpectShell.log('stdio', stdout='Tue Apr  9 15:30:52 PDT 2019'),
1708             ExpectShell(command=['uname', '-a'], workdir='wkdir', timeout=60, logEnviron=False) + 0
1709             + ExpectShell.log('stdio', stdout='''Linux kodama-ews 5.0.4-arch1-1-ARCH #1 SMP PREEMPT Sat Mar 23 21:00:33 UTC 2019 x86_64 GNU/Linux'''),
1710         )
1711         self.expectOutcome(result=SUCCESS, state_string='Printed configuration')
1712         return self.runStep()
1713
1714     def test_success_linux_gtk(self):
1715         self.setupStep(PrintConfiguration())
1716         self.setProperty('platform', 'gtk')
1717
1718         self.expectRemoteCommands(
1719             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1720             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1721             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1722             ExpectShell(command=['uname', '-a'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1723         )
1724         self.expectOutcome(result=SUCCESS, state_string='Printed configuration')
1725         return self.runStep()
1726
1727     def test_success_win(self):
1728         self.setupStep(PrintConfiguration())
1729         self.setProperty('platform', 'win')
1730
1731         self.expectRemoteCommands(
1732             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1733             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1734             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1735         )
1736         self.expectOutcome(result=SUCCESS, state_string='Printed configuration')
1737         return self.runStep()
1738
1739     def test_failure(self):
1740         self.setupStep(PrintConfiguration())
1741         self.setProperty('platform', 'ios-12')
1742         self.expectRemoteCommands(
1743             ExpectShell(command=['hostname'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1744             ExpectShell(command=['df', '-hl'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1745             ExpectShell(command=['date'], workdir='wkdir', timeout=60, logEnviron=False) + 0,
1746             ExpectShell(command=['sw_vers'], workdir='wkdir', timeout=60, logEnviron=False) + 1
1747             + ExpectShell.log('stdio', stdout='''Upon execvpe sw_vers ['sw_vers'] in environment id 7696545650400
1748 :Traceback (most recent call last):
1749   File "/usr/lib/python2.7/site-packages/twisted/internet/process.py", line 445, in _fork
1750     environment)
1751   File "/usr/lib/python2.7/site-packages/twisted/internet/process.py", line 523, in _execChild
1752     os.execvpe(executable, args, environment)
1753   File "/usr/lib/python2.7/os.py", line 355, in execvpe
1754     _execvpe(file, args, env)
1755   File "/usr/lib/python2.7/os.py", line 382, in _execvpe
1756     func(fullname, *argrest)
1757 OSError: [Errno 2] No such file or directory'''),
1758             ExpectShell(command=['xcodebuild', '-sdk', '-version'], workdir='wkdir', timeout=60, logEnviron=False)
1759             + ExpectShell.log('stdio', stdout='''Upon execvpe xcodebuild ['xcodebuild', '-sdk', '-version'] in environment id 7696545612416
1760 :Traceback (most recent call last):
1761   File "/usr/lib/python2.7/site-packages/twisted/internet/process.py", line 445, in _fork
1762     environment)
1763   File "/usr/lib/python2.7/site-packages/twisted/internet/process.py", line 523, in _execChild
1764     os.execvpe(executable, args, environment)
1765   File "/usr/lib/python2.7/os.py", line 355, in execvpe
1766     _execvpe(file, args, env)
1767   File "/usr/lib/python2.7/os.py", line 382, in _execvpe
1768     func(fullname, *argrest)
1769 OSError: [Errno 2] No such file or directory''')
1770             + 1,
1771         )
1772         self.expectOutcome(result=FAILURE, state_string='Failed to print configuration')
1773         return self.runStep()
1774
1775
1776 if __name__ == '__main__':
1777     unittest.main()