OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 | |
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
4 # for details. All rights reserved. Use of this source code is governed by a | |
5 # BSD-style license that can be found in the LICENSE file. | |
6 | |
7 """ | |
8 Dart2js buildbot steps | |
9 | |
10 Runs tests for the dart2js compiler. | |
11 """ | |
12 | |
13 import os | |
14 import platform | |
15 import re | |
16 import shutil | |
17 import socket | |
18 import string | |
19 import subprocess | |
20 import sys | |
21 | |
22 import bot | |
23 | |
24 DARTIUM_BUILDER = r'none-dartium-(linux|mac|windows)' | |
25 DART2JS_BUILDER = ( | |
26 r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-ch
ecked))?(-(host-checked))?(-(minified))?(-(x64))?(-(cps))?-?(\d*)-?(\d*)') | |
27 DART2JS_FULL_BUILDER = r'full-(linux|mac|win7|win8)(-(ie10|ie11))?(-checked)?(-m
inified)?-(\d+)-(\d+)' | |
28 WEB_BUILDER = ( | |
29 r'dart2js-(ie9|ie10|ie11|ff|safari|chrome|chromeOnAndroid|safarimobilesim|op
era|drt)-(win7|win8|mac10\.7|mac10\.8|mac10\.9|linux)(-(all|html))?(-(csp))?(-(\
d+)-(\d+))?') | |
30 | |
31 IE_VERSIONS = ['ie10', 'ie11'] | |
32 | |
33 DART2JS_FULL_CONFIGURATIONS = { | |
34 'linux' : [ | |
35 {'runtime' : 'ff'}, | |
36 {'runtime' : 'chrome'}, | |
37 ], | |
38 'mac' : [ ], | |
39 'windows-ie10' : [ | |
40 {'runtime' : 'ie10'}, | |
41 {'runtime' : 'chrome'}, | |
42 ], | |
43 'windows-ie11' : [ | |
44 {'runtime' : 'ie11'}, | |
45 {'runtime' : 'ff'}, | |
46 ], | |
47 } | |
48 | |
49 | |
50 def GetBuildInfo(builder_name, is_buildbot): | |
51 """Returns a BuildInfo object for the current buildbot based on the | |
52 name of the builder. | |
53 """ | |
54 compiler = None | |
55 runtime = None | |
56 mode = None | |
57 system = None | |
58 checked = False | |
59 host_checked = False | |
60 minified = False | |
61 shard_index = None | |
62 total_shards = None | |
63 test_set = None | |
64 csp = None | |
65 arch = None | |
66 dart2js_full = False | |
67 batch = True | |
68 builder_tag = None | |
69 cps_ir = None | |
70 | |
71 dart2js_pattern = re.match(DART2JS_BUILDER, builder_name) | |
72 dart2js_full_pattern = re.match(DART2JS_FULL_BUILDER, builder_name) | |
73 web_pattern = re.match(WEB_BUILDER, builder_name) | |
74 dartium_pattern = re.match(DARTIUM_BUILDER, builder_name) | |
75 | |
76 if web_pattern: | |
77 compiler = 'dart2js' | |
78 runtime = web_pattern.group(1) | |
79 system = web_pattern.group(2) | |
80 mode = 'release' | |
81 test_set = web_pattern.group(4) | |
82 if web_pattern.group(6) == 'csp': | |
83 csp = True | |
84 # Always run csp mode minified | |
85 minified = True | |
86 shard_index = web_pattern.group(8) | |
87 total_shards = web_pattern.group(9) | |
88 elif dart2js_full_pattern: | |
89 mode = 'release' | |
90 compiler = 'dart2js' | |
91 dart2js_full = True | |
92 system = dart2js_full_pattern.group(1) | |
93 # windows-ie10 or windows-ie11 means a windows machine with that respective | |
94 # version of ie installed. There is no difference in how we handle testing. | |
95 # We use the builder tag to pass along this information. | |
96 if system.startswith('win'): | |
97 ie = dart2js_full_pattern.group(3) | |
98 assert ie in IE_VERSIONS | |
99 builder_tag = 'windows-%s' % ie | |
100 system = 'windows' | |
101 if dart2js_full_pattern.group(4): | |
102 checked = True | |
103 if dart2js_full_pattern.group(5): | |
104 minified = True | |
105 shard_index = dart2js_full_pattern.group(6) | |
106 total_shards = dart2js_full_pattern.group(7) | |
107 elif dart2js_pattern: | |
108 compiler = 'dart2js' | |
109 system = dart2js_pattern.group(1) | |
110 runtime = 'd8' | |
111 arch = 'ia32' | |
112 if dart2js_pattern.group(3) == 'jsshell': | |
113 runtime = 'jsshell' | |
114 mode = dart2js_pattern.group(4) | |
115 # The valid naming parts for checked and host-checked are: | |
116 # Empty: checked=False, host_checked=False | |
117 # -checked: checked=True, host_checked=False | |
118 # -host-checked: checked=False, host_checked=True | |
119 # -checked-host-checked: checked=True, host_checked=True | |
120 if dart2js_pattern.group(6) == 'checked': | |
121 checked = True | |
122 if dart2js_pattern.group(6) == 'host-checked': | |
123 host_checked = True | |
124 if dart2js_pattern.group(8) == 'host-checked': | |
125 host_checked = True | |
126 if dart2js_pattern.group(10) == 'minified': | |
127 minified = True | |
128 if dart2js_pattern.group(12) == 'x64': | |
129 arch = 'x64' | |
130 if dart2js_pattern.group(14) == 'cps': | |
131 cps_ir = True | |
132 shard_index = dart2js_pattern.group(15) | |
133 total_shards = dart2js_pattern.group(16) | |
134 elif dartium_pattern: | |
135 compiler = 'none' | |
136 runtime = 'dartium' | |
137 mode = 'release' | |
138 system = dartium_pattern.group(1) | |
139 else : | |
140 return None | |
141 | |
142 # We have both win7 and win8 bots, functionality is the same. | |
143 if system.startswith('win'): | |
144 system = 'windows' | |
145 | |
146 # We have both 10.8 and 10.9 bots, functionality is the same. | |
147 if system == 'mac10.8' or system == 'mac10.9': | |
148 system = 'mac' | |
149 | |
150 if (system == 'windows' and platform.system() != 'Windows') or ( | |
151 system == 'mac' and platform.system() != 'Darwin') or ( | |
152 system == 'linux' and platform.system() != 'Linux'): | |
153 print ('Error: You cannot emulate a buildbot with a platform different ' | |
154 'from your own.') | |
155 return None | |
156 return bot.BuildInfo(compiler, runtime, mode, system, checked, host_checked, | |
157 minified, shard_index, total_shards, is_buildbot, | |
158 test_set, csp, arch, dart2js_full, batch=batch, | |
159 builder_tag=builder_tag, cps_ir=cps_ir) | |
160 | |
161 | |
162 def NeedsXterm(compiler, runtime): | |
163 return runtime in ['ie9', 'ie10', 'ie11', 'chrome', 'safari', 'opera', | |
164 'ff', 'drt', 'dartium'] | |
165 | |
166 | |
167 def TestStepName(name, runtime, flags): | |
168 # Filter out flags with '=' as this breaks the /stats feature of the | |
169 # build bot. | |
170 flags = [x for x in flags if not '=' in x] | |
171 step_name = '%s-%s tests %s' % (name, runtime, ' '.join(flags)) | |
172 return step_name.strip() | |
173 | |
174 | |
175 IsFirstTestStepCall = True | |
176 def TestStep(name, mode, system, compiler, runtime, targets, flags, arch): | |
177 step_name = TestStepName(name, runtime, flags) | |
178 with bot.BuildStep(step_name, swallow_error=True): | |
179 sys.stdout.flush() | |
180 if NeedsXterm(compiler, runtime) and system == 'linux': | |
181 cmd = ['xvfb-run', '-a', '--server-args=-screen 0 1024x768x24'] | |
182 else: | |
183 cmd = [] | |
184 | |
185 user_test = os.environ.get('USER_TEST', 'no') | |
186 | |
187 cmd.extend([sys.executable, | |
188 os.path.join(os.curdir, 'tools', 'test.py'), | |
189 '--step_name=' + step_name, | |
190 '--mode=' + mode, | |
191 '--compiler=' + compiler, | |
192 '--runtime=' + runtime, | |
193 '--arch=' + arch, | |
194 '--time', | |
195 '--use-sdk', | |
196 '--report', | |
197 '--write-debug-log', | |
198 '--write-test-outcome-log']) | |
199 | |
200 if user_test == 'yes': | |
201 cmd.append('--progress=color') | |
202 else: | |
203 cmd.extend(['--progress=buildbot', '-v']) | |
204 | |
205 cmd.append('--reset-browser-configuration') | |
206 | |
207 global IsFirstTestStepCall | |
208 if IsFirstTestStepCall: | |
209 IsFirstTestStepCall = False | |
210 else: | |
211 cmd.append('--append_logs') | |
212 | |
213 if flags: | |
214 cmd.extend(flags) | |
215 cmd.extend(targets) | |
216 | |
217 print 'Running: %s' % (' '.join(map(lambda arg: '"%s"' % arg, cmd))) | |
218 sys.stdout.flush() | |
219 bot.RunProcess(cmd) | |
220 | |
221 | |
222 def TestCompiler(runtime, mode, system, flags, is_buildbot, arch, | |
223 compiler=None, dart2js_full=False): | |
224 """ test the compiler. | |
225 Args: | |
226 - runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo | |
227 - mode: either 'debug' or 'release' | |
228 - system: either 'linux', 'mac', 'windows' | |
229 - flags: extra flags to pass to test.dart | |
230 - is_buildbot: true if we are running on a real buildbot instead of | |
231 emulating one. | |
232 - arch: The architecture to run on. | |
233 - compiler: The compiler to use for test.py (default is 'dart2js'). | |
234 """ | |
235 | |
236 if not compiler: | |
237 compiler = 'dart2js' | |
238 | |
239 def GetPath(runtime): | |
240 """ Helper to get the path to the Chrome or Firefox executable for a | |
241 particular platform on the buildbot. Throws a KeyError if runtime is not | |
242 either 'chrome' or 'ff'.""" | |
243 if system == 'mac': | |
244 partDict = {'chrome': 'Google\\ Chrome', 'ff': 'Firefox'} | |
245 mac_path = '/Applications/%s.app/Contents/MacOS/%s' | |
246 path_dict = {'chrome': mac_path % (partDict[runtime], partDict[runtime]), | |
247 'ff': mac_path % (partDict[runtime], partDict[runtime].lower())} | |
248 elif system == 'linux': | |
249 path_dict = {'ff': 'firefox', 'chrome': 'google-chrome'} | |
250 else: | |
251 # Windows. | |
252 path_dict = {'ff': os.path.join('C:/', 'Program Files (x86)', | |
253 'Mozilla Firefox', 'firefox.exe'), | |
254 'chrome': os.path.join('C:/', 'Users', 'chrome-bot', 'AppData', | |
255 'Local', 'Google', 'Chrome', 'Application', 'chrome.exe')} | |
256 return path_dict[runtime] | |
257 | |
258 if (compiler == 'dart2js' and (runtime == 'ff' or runtime == 'chrome') | |
259 and is_buildbot): | |
260 # Print out browser version numbers if we're running on the buildbot (where | |
261 # we know the paths to these browser installations). | |
262 version_query_string = '"%s" --version' % GetPath(runtime) | |
263 if runtime == 'ff' and system == 'windows': | |
264 version_query_string += '| more' | |
265 elif runtime == 'chrome' and system == 'windows': | |
266 version_query_string = ('''reg query "HKCU\\Software\\Microsoft\\''' + | |
267 '''Windows\\CurrentVersion\\Uninstall\\Google Chrome" /v Version''') | |
268 p = subprocess.Popen(version_query_string, | |
269 stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) | |
270 output, stderr = p.communicate() | |
271 output = output.split() | |
272 try: | |
273 print 'Version of %s: %s' % (runtime, output[-1]) | |
274 except IndexError: | |
275 # Failed to obtain version information. Continue running tests. | |
276 pass | |
277 | |
278 unit_test_flags = [flag for flag in flags if flag.startswith('--shard')] | |
279 # Run the unit tests in checked mode (the VM's checked mode). | |
280 unit_test_flags.append('--checked') | |
281 if runtime == 'd8': | |
282 # The dart2js compiler isn't self-hosted (yet) so we run its | |
283 # unit tests on the VM. We avoid doing this on the builders | |
284 # that run the browser tests to cut down on the cycle time. | |
285 TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js', 'try'], | |
286 unit_test_flags, arch) | |
287 | |
288 if compiler == 'dart2js' and runtime == 'drt': | |
289 # Ensure that we run the "try" tests on Content Shell. | |
290 TestStep("incremental_compilation", mode, system, 'none', runtime, | |
291 ['try'], unit_test_flags, arch) | |
292 | |
293 if compiler == 'dart2js' and runtime in ['ie10', 'ie11']: | |
294 TestStep(compiler, mode, system, compiler, runtime, | |
295 ['html', 'pkg', 'samples', 'co19'], flags, arch) | |
296 else: | |
297 # Run the default set of test suites. | |
298 TestStep(compiler, mode, system, compiler, | |
299 runtime, [], flags, arch) | |
300 | |
301 if compiler == 'dart2js': | |
302 # TODO(kasperl): Consider running peg and css tests too. | |
303 extras = ['dart2js_extra', 'dart2js_native'] | |
304 extras_flags = flags | |
305 if (system == 'linux' | |
306 and runtime == 'd8' | |
307 and not '--host-checked' in extras_flags): | |
308 # Run the extra tests in checked mode, but only on linux/d8. | |
309 # Other systems have less resources and tend to time out. | |
310 extras_flags = extras_flags + ['--host-checked'] | |
311 TestStep('dart2js_extra', mode, system, 'dart2js', runtime, extras, | |
312 extras_flags, arch) | |
313 if mode == 'release': | |
314 TestStep('try_dart', mode, system, 'dart2js', runtime, ['try'], | |
315 extras_flags, arch) | |
316 | |
317 | |
318 def GetHasHardCodedCheckedMode(build_info): | |
319 # TODO(ricow): We currently run checked mode tests on chrome on linux and | |
320 # on the slow (all) IE windows bots. This is a hack and we should use the | |
321 # normal sharding and checked splitting functionality when we get more | |
322 # vms for testing this. | |
323 if (build_info.system == 'linux' and build_info.runtime == 'drt'): | |
324 return True | |
325 if build_info.runtime.startswith('ie') and build_info.test_set == 'all': | |
326 return True | |
327 return False | |
328 | |
329 | |
330 def GetLocalIPAddress(): | |
331 hostname = socket.gethostname() | |
332 # '$ host chromeperf02' results for example in | |
333 # 'chromeperf02.perf.chromium.org has address 172.22.28.55' | |
334 output = subprocess.check_output(["host", hostname]) | |
335 match = re.match(r'.*\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s+.*', output) | |
336 if not match: | |
337 raise Exception("Could not determine local ip address " | |
338 "(hostname: '%s', host command output: '%s')." | |
339 % (hostname, output)) | |
340 return match.group(1) | |
341 | |
342 def AddAndroidToolsToPath(): | |
343 par_dir = os.path.pardir | |
344 join = os.path.join | |
345 | |
346 dart_dir = join(os.path.dirname(__file__), par_dir, par_dir) | |
347 android_sdk = join(dart_dir, 'third_party', 'android_tools', 'sdk') | |
348 tools_dir = os.path.abspath(join(android_sdk, 'tools')) | |
349 platform_tools_dir = os.path.abspath(join(android_sdk, 'platform-tools')) | |
350 os.environ['PATH'] = os.pathsep.join( | |
351 [os.environ['PATH'], tools_dir, platform_tools_dir]) | |
352 | |
353 def RunCompilerTests(build_info): | |
354 test_flags = [] | |
355 if build_info.shard_index: | |
356 test_flags = ['--shards=%s' % build_info.total_shards, | |
357 '--shard=%s' % build_info.shard_index] | |
358 if build_info.checked: test_flags += ['--checked'] | |
359 if build_info.minified: test_flags += ['--minified'] | |
360 if build_info.host_checked: test_flags += ['--host-checked'] | |
361 if build_info.batch: test_flags += ['--dart2js-batch'] | |
362 if build_info.builder_tag: test_flags += ['--builder-tag=' + | |
363 build_info.builder_tag] | |
364 if build_info.cps_ir: test_flags += ['--cps-ir'] | |
365 | |
366 if build_info.dart2js_full: | |
367 compiler = build_info.compiler | |
368 assert compiler == 'dart2js' | |
369 system = build_info.system | |
370 arch = build_info.arch | |
371 mode = build_info.mode | |
372 is_buildbot = build_info.is_buildbot | |
373 | |
374 config = build_info.builder_tag if system == 'windows' else system | |
375 for configuration in DART2JS_FULL_CONFIGURATIONS[config]: | |
376 additional_flags = configuration.get('additional_flags', []) | |
377 TestCompiler(configuration['runtime'], mode, system, | |
378 test_flags + additional_flags, is_buildbot, arch, | |
379 compiler=compiler, dart2js_full=True) | |
380 else: | |
381 if build_info.csp: test_flags += ['--csp'] | |
382 | |
383 if build_info.runtime == 'chromeOnAndroid': | |
384 test_flags.append('--local_ip=%s' % GetLocalIPAddress()) | |
385 # test.py expects the android tools directories to be in PATH | |
386 # (they contain for example 'adb') | |
387 AddAndroidToolsToPath() | |
388 | |
389 TestCompiler(build_info.runtime, build_info.mode, build_info.system, | |
390 list(test_flags), build_info.is_buildbot, | |
391 build_info.arch, compiler=build_info.compiler) | |
392 | |
393 # See comment in GetHasHardCodedCheckedMode, this is a hack. | |
394 if (GetHasHardCodedCheckedMode(build_info)): | |
395 TestCompiler(build_info.runtime, build_info.mode, build_info.system, | |
396 test_flags + ['--checked'], build_info.is_buildbot, | |
397 build_info.arch, compiler=build_info.compiler) | |
398 | |
399 | |
400 def BuildCompiler(build_info): | |
401 """ | |
402 Builds the SDK. | |
403 | |
404 - build_info: the buildInfo object, containing information about what sort of | |
405 build and test to be run. | |
406 """ | |
407 with bot.BuildStep('Build SDK'): | |
408 target = 'dart2js_bot' | |
409 # Try-dart takes more than 20 min in debug mode and makes the bot time out. | |
410 # We use the debug target which does not include try | |
411 if build_info.mode == 'debug': | |
412 target = 'dart2js_bot_debug' | |
413 args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode, | |
414 '--arch=' + build_info.arch, target] | |
415 print 'Build SDK and d8: %s' % (' '.join(args)) | |
416 bot.RunProcess(args) | |
417 | |
418 | |
419 if __name__ == '__main__': | |
420 bot.RunBot(GetBuildInfo, RunCompilerTests, build_step=BuildCompiler) | |
OLD | NEW |