| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python | |
| 2 | |
| 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 4 # Use of this source code is governed by a BSD-style license that can be | |
| 5 # found in the LICENSE file. | |
| 6 | |
| 7 """Dart frog buildbot steps | |
| 8 | |
| 9 Runs tests for the frog or dart2js compiler. | |
| 10 """ | |
| 11 | |
| 12 import platform | |
| 13 import optparse | |
| 14 import os | |
| 15 import re | |
| 16 import shutil | |
| 17 import subprocess | |
| 18 import sys | |
| 19 | |
| 20 BUILDER_NAME = 'BUILDBOT_BUILDERNAME' | |
| 21 | |
| 22 DART_PATH = os.path.dirname( | |
| 23 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| 24 | |
| 25 DART2JS_BUILDER = ( | |
| 26 r'dart2js-(linux|mac|windows)-(debug|release)(-([a-z]+))?-?(\d*)-?(\d*)') | |
| 27 FROG_BUILDER = r'(frog)-(linux|mac|windows)-(debug|release)' | |
| 28 WEB_BUILDER = r'web-(ie|ff|safari|chrome|opera)-(win7|win8|mac|linux)(-(\d+))?' | |
| 29 | |
| 30 NO_COLOR_ENV = dict(os.environ) | |
| 31 NO_COLOR_ENV['TERM'] = 'nocolor' | |
| 32 | |
| 33 def GetBuildInfo(): | |
| 34 """Returns a tuple (compiler, runtime, mode, system, option) where: | |
| 35 - compiler: 'dart2js', 'frog', or None when the builder has an | |
| 36 incorrect name | |
| 37 - runtime: 'd8', 'ie', 'ff', 'safari', 'chrome', 'opera' | |
| 38 - mode: 'debug' or 'release' | |
| 39 - system: 'linux', 'mac', or 'win7' | |
| 40 - option: 'checked' | |
| 41 """ | |
| 42 parser = optparse.OptionParser() | |
| 43 parser.add_option('-n', '--name', dest='name', help='The name of the build' | |
| 44 'bot you would like to emulate (ex: web-chrome-win7)', default=None) | |
| 45 args, _ = parser.parse_args() | |
| 46 | |
| 47 compiler = None | |
| 48 runtime = None | |
| 49 mode = None | |
| 50 system = None | |
| 51 builder_name = os.environ.get(BUILDER_NAME) | |
| 52 option = None | |
| 53 shard_index = None | |
| 54 total_shards = None | |
| 55 number = None | |
| 56 if not builder_name: | |
| 57 # We are not running on a buildbot. | |
| 58 if args.name: | |
| 59 builder_name = args.name | |
| 60 else: | |
| 61 print 'Use -n $BUILDBOT_NAME for the bot you would like to emulate.' | |
| 62 sys.exit(1) | |
| 63 | |
| 64 if builder_name: | |
| 65 | |
| 66 dart2js_pattern = re.match(DART2JS_BUILDER, builder_name) | |
| 67 frog_pattern = re.match(FROG_BUILDER, builder_name) | |
| 68 web_pattern = re.match(WEB_BUILDER, builder_name) | |
| 69 | |
| 70 if dart2js_pattern: | |
| 71 compiler = 'dart2js' | |
| 72 runtime = 'd8' | |
| 73 system = dart2js_pattern.group(1) | |
| 74 mode = dart2js_pattern.group(2) | |
| 75 option = dart2js_pattern.group(4) | |
| 76 shard_index = dart2js_pattern.group(5) | |
| 77 total_shards = dart2js_pattern.group(6) | |
| 78 | |
| 79 elif frog_pattern: | |
| 80 compiler = frog_pattern.group(1) | |
| 81 runtime = 'd8' | |
| 82 system = frog_pattern.group(2) | |
| 83 mode = frog_pattern.group(3) | |
| 84 | |
| 85 elif web_pattern: | |
| 86 compiler = 'frog' | |
| 87 runtime = web_pattern.group(1) | |
| 88 mode = 'release' | |
| 89 system = web_pattern.group(2) | |
| 90 | |
| 91 # TODO(jmesserly): do we want to do anything different for the second IE | |
| 92 # bot? For now we're using it to track down flakiness. | |
| 93 number = web_pattern.group(4) | |
| 94 | |
| 95 if system == 'windows': | |
| 96 system = 'win7' | |
| 97 | |
| 98 if (system == 'win7' and platform.system() != 'Windows') or ( | |
| 99 system == 'mac' and platform.system() != 'Darwin') or ( | |
| 100 system == 'linux' and platform.system() != 'Linux'): | |
| 101 print ('Error: You cannot emulate a buildbot with a platform different ' | |
| 102 'from your own.') | |
| 103 sys.exit(1) | |
| 104 return (compiler, runtime, mode, system, option, shard_index, total_shards, | |
| 105 number) | |
| 106 | |
| 107 | |
| 108 def NeedsXterm(compiler, runtime): | |
| 109 return runtime in ['ie', 'chrome', 'safari', 'opera', 'ff', 'drt'] | |
| 110 | |
| 111 def TestStep(name, mode, system, compiler, runtime, targets, flags): | |
| 112 print '@@@BUILD_STEP %s %s tests: %s %s@@@' % (name, compiler, runtime, | |
| 113 ' '.join(flags)) | |
| 114 sys.stdout.flush() | |
| 115 if NeedsXterm(compiler, runtime) and system == 'linux': | |
| 116 cmd = ['xvfb-run', '-a'] | |
| 117 else: | |
| 118 cmd = [] | |
| 119 | |
| 120 user_test = os.environ.get('USER_TEST', 'no') | |
| 121 | |
| 122 cmd.extend([sys.executable, | |
| 123 os.path.join(os.curdir, 'tools', 'test.py'), | |
| 124 '--mode=' + mode, | |
| 125 '--compiler=' + compiler, | |
| 126 '--runtime=' + runtime, | |
| 127 '--time', | |
| 128 '--use-sdk', | |
| 129 '--report']) | |
| 130 | |
| 131 if user_test == 'yes': | |
| 132 cmd.append('--progress=color') | |
| 133 else: | |
| 134 cmd.extend(['--progress=buildbot', '-v']) | |
| 135 | |
| 136 if flags: | |
| 137 cmd.extend(flags) | |
| 138 cmd.extend(targets) | |
| 139 | |
| 140 print 'running %s' % (' '.join(cmd)) | |
| 141 exit_code = subprocess.call(cmd, env=NO_COLOR_ENV) | |
| 142 if exit_code != 0: | |
| 143 print '@@@STEP_FAILURE@@@' | |
| 144 return exit_code | |
| 145 | |
| 146 | |
| 147 def BuildFrog(compiler, mode, system): | |
| 148 """ build frog. | |
| 149 Args: | |
| 150 - compiler: either 'dart2js' or 'frog' | |
| 151 - mode: either 'debug' or 'release' | |
| 152 - system: either 'linux', 'mac', or 'win7' | |
| 153 """ | |
| 154 # TODO(efortuna): Currently we always clobber Windows builds. The VM | |
| 155 # team thinks there's a problem with dependency tracking on Windows that | |
| 156 # is leading to occasional build failures. Remove when this gyp issue has | |
| 157 # been ironed out. | |
| 158 if system == 'win7': | |
| 159 for build in ['Release_', 'Debug_']: | |
| 160 for arch in ['ia32', 'x64']: | |
| 161 outdir = build + arch | |
| 162 shutil.rmtree(outdir, ignore_errors=True) | |
| 163 shutil.rmtree('frog/%s' % outdir, ignore_errors=True) | |
| 164 shutil.rmtree('runtime/%s' % outdir, ignore_errors=True) | |
| 165 | |
| 166 os.chdir(DART_PATH) | |
| 167 | |
| 168 print '@@@BUILD_STEP build frog@@@' | |
| 169 | |
| 170 args = [sys.executable, './tools/build.py', '--mode=' + mode, 'create_sdk'] | |
| 171 print 'running %s' % (' '.join(args)) | |
| 172 return subprocess.call(args, env=NO_COLOR_ENV) | |
| 173 | |
| 174 | |
| 175 def TestFrog(compiler, runtime, mode, system, option, flags, bot_number=None): | |
| 176 """ test frog. | |
| 177 Args: | |
| 178 - compiler: either 'dart2js' or 'frog' | |
| 179 - runtime: either 'd8', or one of the browsers, see GetBuildInfo | |
| 180 - mode: either 'debug' or 'release' | |
| 181 - system: either 'linux', 'mac', or 'win7' | |
| 182 - option: 'checked' | |
| 183 - flags: extra flags to pass to test.dart | |
| 184 - bot_number: (optional) Number of the buildbot. Used for dividing test | |
| 185 sets between bots. | |
| 186 """ | |
| 187 | |
| 188 # Make sure we are in the frog directory | |
| 189 os.chdir(DART_PATH) | |
| 190 | |
| 191 if compiler == 'dart2js': | |
| 192 if (option == 'checked'): | |
| 193 flags.append('--host-checked') | |
| 194 # Leg isn't self-hosted (yet) so we run the leg unit tests on the VM. | |
| 195 TestStep("dart2js_unit", mode, system, 'none', 'vm', ['leg'], ['--checked']) | |
| 196 | |
| 197 extra_suites = ['leg_only', 'frog_native'] | |
| 198 TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extra_suites, | |
| 199 flags) | |
| 200 | |
| 201 TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags) | |
| 202 | |
| 203 elif runtime == 'd8' and compiler in ['frog']: | |
| 204 TestStep("frog", mode, system, compiler, runtime, [], flags) | |
| 205 TestStep("frog_extra", mode, system, compiler, runtime, | |
| 206 ['frog', 'frog_native', 'peg', 'css'], flags) | |
| 207 TestStep("sdk", mode, system, 'none', 'vm', ['dartdoc'], flags) | |
| 208 | |
| 209 else: | |
| 210 tests = ['dom', 'html', 'json', 'benchmark_smoke', | |
| 211 'isolate', 'frog', 'css', 'corelib', 'language', | |
| 212 'frog_native', 'peg'] | |
| 213 | |
| 214 # TODO(efortuna): Move Mac back to DumpRenderTree when we have a more stable | |
| 215 # solution for DRT. Right now DRT is flakier than regular Chrome for the | |
| 216 # isolate tests, so we're switching to use Chrome in the short term. | |
| 217 if runtime == 'chrome' and system == 'linux': | |
| 218 TestStep('browser', mode, system, 'frog', 'drt', tests, flags) | |
| 219 | |
| 220 # TODO(ngeoffray): Enable checked mode once dart2js supports type | |
| 221 # variables. | |
| 222 if not ('--checked' in flags): | |
| 223 TestStep('browser_dart2js', mode, system, 'dart2js', 'drt', [], flags) | |
| 224 TestStep('browser_dart2js_extra', mode, system, 'dart2js', 'drt', | |
| 225 ['leg_only', 'frog_native'], flags) | |
| 226 | |
| 227 else: | |
| 228 additional_flags = [] | |
| 229 if system.startswith('win') and runtime == 'ie': | |
| 230 # There should not be more than one InternetExplorerDriver instance | |
| 231 # running at a time. For details, see | |
| 232 # http://code.google.com/p/selenium/wiki/InternetExplorerDriver. | |
| 233 additional_flags += ['-j1'] | |
| 234 # The IE bots are slow lately. Split up the tests they do. | |
| 235 if bot_number == '2': | |
| 236 tests = ['language'] | |
| 237 else: | |
| 238 tests = ['dom', 'html', 'json', 'benchmark_smoke', | |
| 239 'isolate', 'frog', 'css', 'frog_native', 'peg', 'corelib'] | |
| 240 TestStep(runtime, mode, system, compiler, runtime, tests, | |
| 241 flags + additional_flags) | |
| 242 | |
| 243 return 0 | |
| 244 | |
| 245 def _DeleteFirefoxProfiles(directory): | |
| 246 """Find all the firefox profiles in a particular directory and delete them.""" | |
| 247 for f in os.listdir(directory): | |
| 248 item = os.path.join(directory, f) | |
| 249 if os.path.isdir(item) and f.startswith('tmp'): | |
| 250 subprocess.Popen('rm -rf %s' % item, shell=True) | |
| 251 | |
| 252 def CleanUpTemporaryFiles(system, browser): | |
| 253 """For some browser (selenium) tests, the browser creates a temporary profile | |
| 254 on each browser session start. On Windows, generally these files are | |
| 255 automatically deleted when all python processes complete. However, since our | |
| 256 buildbot slave script also runs on python, we never get the opportunity to | |
| 257 clear out the temp files, so we do so explicitly here. Our batch browser | |
| 258 testing will make this problem occur much less frequently, but will still | |
| 259 happen eventually unless we do this. | |
| 260 | |
| 261 This problem also occurs with batch tests in Firefox. For some reason selenium | |
| 262 automatically deletes the temporary profiles for Firefox for one browser, | |
| 263 but not multiple ones when we have many open batch tasks running. This | |
| 264 behavior has not been reproduced outside of the buildbots. | |
| 265 | |
| 266 Args: | |
| 267 - system: either 'linux', 'mac', or 'win7' | |
| 268 - browser: one of the browsers, see GetBuildInfo | |
| 269 """ | |
| 270 if system == 'win7': | |
| 271 shutil.rmtree('C:\\Users\\chrome-bot\\AppData\\Local\\Temp', | |
| 272 ignore_errors=True) | |
| 273 elif browser == 'ff': | |
| 274 # Note: the buildbots run as root, so we can do this without requiring a | |
| 275 # password. The command won't actually work on regular machines without | |
| 276 # root permissions. | |
| 277 _DeleteFirefoxProfiles('/tmp') | |
| 278 _DeleteFirefoxProfiles('/var/tmp') | |
| 279 | |
| 280 def main(): | |
| 281 if len(sys.argv) == 0: | |
| 282 print 'Script pathname not known, giving up.' | |
| 283 return 1 | |
| 284 | |
| 285 compiler, runtime, mode, system, option, shard_index, total_shards, number = ( | |
| 286 GetBuildInfo()) | |
| 287 shard_description = "" | |
| 288 if shard_index: | |
| 289 shard_description = " shard %s of %s" % (shard_index, total_shards) | |
| 290 print "compiler: %s, runtime: %s mode: %s, system: %s, option: %s%s" % ( | |
| 291 compiler, runtime, mode, system, option, shard_description) | |
| 292 if compiler is None: | |
| 293 return 1 | |
| 294 | |
| 295 status = BuildFrog(compiler, mode, system) | |
| 296 if status != 0: | |
| 297 print '@@@STEP_FAILURE@@@' | |
| 298 return status | |
| 299 test_flags = [] | |
| 300 if shard_index: | |
| 301 test_flags = ['--shards=%s' % total_shards, '--shard=%s' % shard_index] | |
| 302 if compiler == 'dart2js': | |
| 303 status = TestFrog(compiler, runtime, mode, system, option, test_flags, | |
| 304 number) | |
| 305 if status != 0: | |
| 306 print '@@@STEP_FAILURE@@@' | |
| 307 return status # Return unconditionally for dart2js. | |
| 308 | |
| 309 if runtime == 'd8' or (system == 'linux' and runtime == 'chrome'): | |
| 310 status = TestFrog(compiler, runtime, mode, system, option, test_flags, | |
| 311 number) | |
| 312 if status != 0: | |
| 313 print '@@@STEP_FAILURE@@@' | |
| 314 return status | |
| 315 | |
| 316 status = TestFrog(compiler, runtime, mode, system, option, | |
| 317 test_flags + ['--checked'], number) | |
| 318 if status != 0: | |
| 319 print '@@@STEP_FAILURE@@@' | |
| 320 | |
| 321 if compiler == 'frog' and runtime in ['ff', 'chrome', 'safari', 'opera', | |
| 322 'ie', 'drt']: | |
| 323 CleanUpTemporaryFiles(system, runtime) | |
| 324 return status | |
| 325 | |
| 326 | |
| 327 if __name__ == '__main__': | |
| 328 sys.exit(main()) | |
| OLD | NEW |