| 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 |