OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
4 # for details. All rights reserved. Use of this source code is governed by a | 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. | 5 # BSD-style license that can be found in the LICENSE file. |
6 | 6 |
7 import imp | 7 import imp |
8 import os | 8 import os |
9 import re | 9 import re |
10 import shutil | 10 import shutil |
11 import shlex | |
11 import subprocess | 12 import subprocess |
12 import sys | 13 import sys |
13 import tempfile | 14 import tempfile |
14 import zipfile | 15 import zipfile |
15 | 16 |
16 import config_parser | 17 import config_parser |
17 | 18 |
18 # We expect the tools directory from the dart repo to be checked out into: | 19 # We expect the tools directory from the dart repo to be checked out into: |
19 # ../../tools | 20 # ../../tools |
20 DART_DIR = os.path.abspath( | 21 DART_DIR = os.path.abspath( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 builder_pattern.group(4), | 75 builder_pattern.group(4), |
75 is_repo, | 76 is_repo, |
76 is_sample) | 77 is_sample) |
77 | 78 |
78 class BuildStep(object): | 79 class BuildStep(object): |
79 """ | 80 """ |
80 A context manager for handling build steps. | 81 A context manager for handling build steps. |
81 | 82 |
82 When the context manager is entered, it prints the "@@@BUILD_STEP __@@@" | 83 When the context manager is entered, it prints the "@@@BUILD_STEP __@@@" |
83 message. If it exits from an error being raised it displays the | 84 message. If it exits from an error being raised it displays the |
84 "@@@STEP_FAILURE@@@" message. | 85 "@@@STEP_FAILURE __@@@" message. |
85 | 86 |
86 If swallow_error is True, then this will catch and discard any OSError that | 87 If swallow_error is True, then this will catch and discard any OSError that |
87 is thrown. This lets you run later BuildSteps if the current one fails. | 88 is thrown. This lets you run later BuildSteps if the current one fails. |
88 """ | 89 """ |
89 def __init__(self, name, swallow_error=False): | 90 def __init__(self, name, swallow_error=False): |
90 self.name = name | 91 self.name = name |
91 self.swallow_error = swallow_error | 92 self.swallow_error = swallow_error |
92 | 93 |
93 def __enter__(self): | 94 def __enter__(self): |
94 print '@@@BUILD_STEP %s@@@' % self.name | 95 print '@@@BUILD_STEP %s@@@' % self.name |
95 sys.stdout.flush() | 96 sys.stdout.flush() |
96 | 97 |
97 def __exit__(self, type, value, traceback): | 98 def __exit__(self, type, value, traceback): |
98 if value: | 99 if value: |
99 print '@@@STEP_FAILURE@@@' | 100 print '@@@STEP_FAILURE %s@@@' % self.name |
100 sys.stdout.flush() | 101 sys.stdout.flush() |
101 if self.swallow_error and isinstance(value, OSError): | 102 if self.swallow_error and isinstance(value, OSError): |
102 return True | 103 return True |
103 | 104 |
104 class TempDir(object): | 105 class TempDir(object): |
105 def __init__(self, prefix=''): | 106 def __init__(self, prefix=''): |
106 self._temp_dir = None | 107 self._temp_dir = None |
107 self._prefix = prefix | 108 self._prefix = prefix |
108 | 109 |
109 def __enter__(self): | 110 def __enter__(self): |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 args = [sys.executable, 'tools/build.py', | 152 args = [sys.executable, 'tools/build.py', |
152 '-mrelease,debug', '--arch=ia32', | 153 '-mrelease,debug', '--arch=ia32', |
153 'create_sdk'] | 154 'create_sdk'] |
154 RunProcess(args) | 155 RunProcess(args) |
155 | 156 |
156 def GetSDK(bot_info): | 157 def GetSDK(bot_info): |
157 with BuildStep('Get sdk'): | 158 with BuildStep('Get sdk'): |
158 namer = bot_utils.GCSNamer(channel=bot_utils.Channel.DEV) | 159 namer = bot_utils.GCSNamer(channel=bot_utils.Channel.DEV) |
159 # TODO(ricow): Be smarter here, only download if new. | 160 # TODO(ricow): Be smarter here, only download if new. |
160 build_root = GetBuildRoot(bot_info) | 161 build_root = GetBuildRoot(bot_info) |
161 SafeDelete(os.path.join(build_root, 'dart-sdk')) | 162 SafeDelete(os.path.join(build_root, 'dart-sdk'), bot_info) |
162 if not os.path.exists(build_root): | 163 if not os.path.exists(build_root): |
163 os.makedirs(build_root) | 164 os.makedirs(build_root) |
164 local_zip = os.path.join(build_root, 'sdk.zip') | 165 local_zip = os.path.join(build_root, 'sdk.zip') |
165 gsutils = bot_utils.GSUtil() | 166 gsutils = bot_utils.GSUtil() |
166 gsutils.execute(['cp', | 167 gsutils.execute(['cp', |
167 namer.sdk_zipfilepath('latest', bot_info.system, | 168 namer.sdk_zipfilepath('latest', bot_info.system, |
168 'ia32', 'release'), | 169 'ia32', 'release'), |
169 local_zip]) | 170 local_zip]) |
170 if bot_info.system == 'windows': | 171 if bot_info.system == 'windows': |
171 with zipfile.ZipFile(local_zip, 'r') as zip_file: | 172 with zipfile.ZipFile(local_zip, 'r') as zip_file: |
172 zip_file.extractall(path=build_root) | 173 zip_file.extractall(path=build_root) |
173 else: | 174 else: |
174 # We don't keep the execution bit if we use python's zipfile on possix. | 175 # We don't keep the execution bit if we use python's zipfile on possix. |
175 RunProcess(['unzip', local_zip, '-d', build_root]) | 176 RunProcess(['unzip', local_zip, '-d', build_root]) |
176 | 177 |
177 def GetPackagePath(bot_info): | 178 def GetPackagePath(bot_info): |
178 if bot_info.is_repo: | 179 if bot_info.is_repo: |
179 return os.path.join('pkg', bot_info.package_name) | 180 return os.path.join('pkg', bot_info.package_name) |
180 return os.path.join('third_party', 'pkg', bot_info.package_name) | 181 return os.path.join('third_party', 'pkg', bot_info.package_name) |
181 | 182 |
182 def GetBuildRoot(bot_info): | 183 def GetBuildRoot(bot_info): |
183 system = bot_info.system | 184 system = bot_info.system |
184 if system == 'windows': | 185 if system == 'windows': |
185 system = 'win32' | 186 system = 'win32' |
186 if system == 'mac': | 187 if system == 'mac': |
187 system = 'macos' | 188 system = 'macos' |
188 return utils.GetBuildRoot(system, mode='release', arch='ia32', | 189 return utils.GetBuildRoot(system, mode='release', arch='ia32', |
189 target_os=system) | 190 target_os=system) |
190 | 191 |
191 def SafeDelete(path): | 192 def SafeDelete(path, bot_info): |
192 if bot_info.system == 'windows': | 193 if bot_info.system == 'windows': |
193 if os.path.exists(path): | 194 if os.path.exists(path): |
194 args = ['cmd.exe', '/c', 'rmdir', '/q', '/s', path] | 195 args = ['cmd.exe', '/c', 'rmdir', '/q', '/s', path] |
195 RunProcess(args) | 196 RunProcess(args) |
196 else: | 197 else: |
197 shutil.rmtree(path, ignore_errors=True) | 198 shutil.rmtree(path, ignore_errors=True) |
198 | 199 |
199 | 200 |
200 def GetPackageCopy(bot_info): | 201 def GetPackageCopy(bot_info): |
201 build_root = GetBuildRoot(bot_info) | 202 build_root = GetBuildRoot(bot_info) |
202 package_copy = os.path.join(build_root, 'package_copy') | 203 package_copy = os.path.join(build_root, 'package_copy') |
203 package_path = GetPackagePath(bot_info) | 204 package_path = GetPackagePath(bot_info) |
204 copy_path = os.path.join(package_copy, bot_info.package_name) | 205 copy_path = os.path.join(package_copy, bot_info.package_name) |
205 SafeDelete(package_copy) | 206 SafeDelete(package_copy, bot_info) |
206 no_git = shutil.ignore_patterns('.git') | 207 no_git = shutil.ignore_patterns('.git') |
207 shutil.copytree(package_path, copy_path, symlinks=False, ignore=no_git) | 208 shutil.copytree(package_path, copy_path, symlinks=False, ignore=no_git) |
208 return copy_path | 209 return copy_path |
209 | 210 |
210 def GetSdkBin(): | 211 def GetSdkBin(bot_info): |
211 return os.path.join(os.getcwd(), GetBuildRoot(bot_info), | 212 return os.path.join(os.getcwd(), GetBuildRoot(bot_info), |
212 'dart-sdk', 'bin') | 213 'dart-sdk', 'bin') |
213 | 214 |
214 def GetVM(): | 215 def GetVM(bot_info): |
215 executable = 'dart.exe' if bot_info.system == 'windows' else 'dart' | 216 executable = 'dart.exe' if bot_info.system == 'windows' else 'dart' |
216 return os.path.join(GetSdkBin(), executable) | 217 return os.path.join(DART_DIR, 'tools/testing/bin', bot_info.system, executable ) |
ricow1
2015/05/19 13:38:09
long line
sigurdm
2015/05/19 13:39:50
Done.
| |
217 | 218 |
218 def GetPub(bot_info): | 219 def GetPub(bot_info): |
219 executable = 'pub.bat' if bot_info.system == 'windows' else 'pub' | 220 executable = 'pub.bat' if bot_info.system == 'windows' else 'pub' |
220 return os.path.join(GetSdkBin(), executable) | 221 return os.path.join(GetSdkBin(bot_info), executable) |
221 | 222 |
222 def GetPubEnv(bot_info): | 223 def GetPubEnv(bot_info): |
223 return {'PUB_CACHE' : os.path.join(os.getcwd(), | 224 return {'PUB_CACHE' : os.path.join(os.getcwd(), |
224 GetBuildRoot(bot_info), 'pub_cache') } | 225 GetBuildRoot(bot_info), 'pub_cache') } |
225 | 226 |
226 # _RunPubCacheRepair and _CheckPubCacheCorruption are not used right now, but we | 227 # _RunPubCacheRepair and _CheckPubCacheCorruption are not used right now, but we |
227 # keep them around because they provide an easy way to diagnose and fix issues | 228 # keep them around because they provide an easy way to diagnose and fix issues |
228 # in the bots. | 229 # in the bots. |
229 def _RunPubCacheRepair(bot_info, path): | 230 def _RunPubCacheRepair(bot_info, path): |
230 pub = GetPub(bot_info) | 231 pub = GetPub(bot_info) |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 system = bot_info.system | 334 system = bot_info.system |
334 xvfb_command = ['xvfb-run', '-a', '--server-args=-screen 0 1024x768x24'] | 335 xvfb_command = ['xvfb-run', '-a', '--server-args=-screen 0 1024x768x24'] |
335 xvfb_args = xvfb_command if system == 'linux' else [] | 336 xvfb_args = xvfb_command if system == 'linux' else [] |
336 suffix = ' under build' if folder == 'build/test' else '' | 337 suffix = ' under build' if folder == 'build/test' else '' |
337 with BuildStep('Test vm release mode%s' % suffix, swallow_error=True): | 338 with BuildStep('Test vm release mode%s' % suffix, swallow_error=True): |
338 args = [sys.executable, 'tools/test.py', | 339 args = [sys.executable, 'tools/test.py', |
339 '-mrelease', '-rvm', '-cnone'] + standard_args | 340 '-mrelease', '-rvm', '-cnone'] + standard_args |
340 args.extend(LogsArgument()) | 341 args.extend(LogsArgument()) |
341 # For easy integration testing we give access to the sdk bin directory. | 342 # For easy integration testing we give access to the sdk bin directory. |
342 # This only makes sense on vm testing. | 343 # This only makes sense on vm testing. |
343 extra_env = { 'DART_SDK_BIN' : GetSdkBin() } | 344 extra_env = { 'DART_SDK_BIN' : GetSdkBin(bot_info) } |
344 RunProcess(args, extra_env=extra_env) | 345 RunProcess(args, extra_env=extra_env) |
345 with BuildStep('Test analyzer%s' % suffix, swallow_error=True): | 346 with BuildStep('Test analyzer%s' % suffix, swallow_error=True): |
346 args = [sys.executable, 'tools/test.py', | 347 args = [sys.executable, 'tools/test.py', |
347 '-mrelease', '-rnone', '-cdart2analyzer'] + standard_args | 348 '-mrelease', '-rnone', '-cdart2analyzer'] + standard_args |
348 args.extend(LogsArgument()) | 349 args.extend(LogsArgument()) |
349 RunProcess(args) | 350 RunProcess(args) |
350 if bot_info.system != 'windows': | 351 if bot_info.system != 'windows': |
351 with BuildStep('Test dartium%s' % suffix, swallow_error=True): | 352 with BuildStep('Test dartium%s' % suffix, swallow_error=True): |
352 test_args = [sys.executable, 'tools/test.py', | 353 test_args = [sys.executable, 'tools/test.py', |
353 '-mrelease', '-rdartium', '-cnone', '-j4'] | 354 '-mrelease', '-rdartium', '-cnone', '-j4'] |
354 args = xvfb_args + test_args + standard_args | 355 args = xvfb_args + test_args + standard_args |
355 args.extend(LogsArgument()) | 356 args.extend(LogsArgument()) |
356 RunProcess(args) | 357 RunProcess(args) |
357 | 358 |
358 for runtime in JS_RUNTIMES[system]: | 359 for runtime in JS_RUNTIMES[system]: |
359 with BuildStep('dart2js-%s%s' % (runtime, suffix), swallow_error=True): | 360 with BuildStep('dart2js-%s%s' % (runtime, suffix), swallow_error=True): |
360 test_args = [sys.executable, 'tools/test.py', | 361 test_args = [sys.executable, 'tools/test.py', |
361 '-mrelease', '-r%s' % runtime, '-cdart2js', '-j4', | 362 '-mrelease', '-r%s' % runtime, '-cdart2js', '-j4', |
362 '--dart2js-batch'] | 363 '--dart2js-batch'] |
363 args = xvfb_args + test_args + standard_args | 364 args = xvfb_args + test_args + standard_args |
364 args.extend(LogsArgument()) | 365 args.extend(LogsArgument()) |
365 RunProcess(args) | 366 RunProcess(args) |
366 | 367 |
368 def FillMagicMarkers(v, replacements): | |
369 def replace(match): | |
370 word = match.group(1) | |
371 if not word in replacements: | |
372 raise Exception("Unknown magic marker %s. Known mappings are: %s" % | |
373 (word, replacements)) | |
374 return replacements[word] | |
375 return re.sub(r"\$(\w+)", replace, v) | |
367 | 376 |
368 def RunHooks(hooks, section_name): | 377 # Runs the script given by test_config.get_config if it exists, does nothing |
378 # otherwise. | |
379 # Returns `True` if the script was run. | |
380 def RunCustomScript(test_config): | |
381 custom_script = test_config.get_custom_script() | |
382 if custom_script: | |
383 command_string = FillMagicMarkers(custom_script, test_config.replacements) | |
384 with BuildStep('Running custom script %s' % command_string, | |
385 swallow_error=True): | |
386 args = shlex.split(command_string, posix=True) | |
387 sys.stdout.flush() | |
388 exit_code = subprocess.call(args) | |
389 if exit_code != 0: | |
390 print "Custom script failed" | |
391 return True | |
392 else: | |
393 return False | |
394 | |
395 | |
396 def RunHooks(hooks, section_name, replacements): | |
369 for name, command in hooks.iteritems(): | 397 for name, command in hooks.iteritems(): |
398 command = FillMagicMarkers(command, replacements) | |
370 with BuildStep('%s: %s' % (section_name, name), swallow_error=True): | 399 with BuildStep('%s: %s' % (section_name, name), swallow_error=True): |
371 RunProcess(command, shell=True) | 400 RunProcess(command, shell=True) |
372 | 401 |
373 def RunPrePubUpgradeHooks(test_config): | 402 def RunPrePubUpgradeHooks(test_config): |
374 RunHooks(test_config.get_pre_pub_upgrade_hooks(), "Pre pub upgrade hooks") | 403 RunHooks(test_config.get_pre_pub_upgrade_hooks(), "Pre pub upgrade hooks", |
404 test_config.replacements) | |
375 | 405 |
376 def RunPrePubBuildHooks(test_config): | 406 def RunPrePubBuildHooks(test_config): |
377 RunHooks(test_config.get_pre_pub_build_hooks(), "Pre pub build hooks") | 407 RunHooks(test_config.get_pre_pub_build_hooks(), "Pre pub build hooks", |
408 test_config.replacements) | |
378 | 409 |
379 def RunPostPubBuildHooks(test_config): | 410 def RunPostPubBuildHooks(test_config): |
380 RunHooks(test_config.get_post_pub_build_hooks(), "Pre pub build hooks") | 411 RunHooks(test_config.get_post_pub_build_hooks(), "Pre pub build hooks", |
412 test_config.replacements) | |
381 | 413 |
382 def RunPreTestHooks(test_config): | 414 def RunPreTestHooks(test_config): |
383 RunHooks(test_config.get_pre_test_hooks(), "Pre test hooks") | 415 RunHooks(test_config.get_pre_test_hooks(), "Pre test hooks", |
416 test_config.replacements) | |
384 | 417 |
385 def RunPostTestHooks(test_config): | 418 def RunPostTestHooks(test_config): |
386 RunHooks(test_config.get_post_test_hooks(), "Post test hooks") | 419 RunHooks(test_config.get_post_test_hooks(), "Post test hooks") |
387 | 420 |
388 if __name__ == '__main__': | 421 def main(): |
389 bot_info = GetBotInfo() | 422 bot_info = GetBotInfo() |
423 | |
390 print 'Bot info: %s' % bot_info | 424 print 'Bot info: %s' % bot_info |
391 copy_path = GetPackageCopy(bot_info) | 425 copy_path = GetPackageCopy(bot_info) |
392 config_file = os.path.join(copy_path, '.test_config') | 426 config_file = os.path.join(copy_path, '.test_config') |
393 test_config = config_parser.ConfigParser(config_file, | 427 test_config = config_parser.ConfigParser(config_file) |
394 GetVM(), | 428 test_config.replacements = { |
395 copy_path) | 429 'dart': GetVM(bot_info), |
396 GetSDK(bot_info) | 430 'project_root': copy_path, |
397 print 'Running testing in copy of package in %s' % copy_path | 431 'python': sys.executable |
398 RunPrePubUpgradeHooks(test_config) | 432 } |
399 RunPubUpgrade(bot_info, copy_path) | |
400 | 433 |
401 RunPrePubBuildHooks(test_config) | 434 if not RunCustomScript(test_config): |
402 RunPubBuild(bot_info, copy_path, 'web') | 435 print "No custom script found, running default steps." |
403 RunPubBuild(bot_info, copy_path, 'test', 'debug') | |
404 RunPostPubBuildHooks(test_config) | |
405 FixupTestControllerJS(copy_path) | |
406 | 436 |
407 RunPreTestHooks(test_config) | 437 GetSDK(bot_info) |
408 RunPackageTesting(bot_info, copy_path, 'test') | 438 print 'Running testing in copy of package in %s' % copy_path |
409 RunPackageTesting(bot_info, copy_path, 'build/test') | 439 RunPrePubUpgradeHooks(test_config) |
410 RunPostTestHooks(test_config) | 440 RunPubUpgrade(bot_info, copy_path) |
441 | |
442 RunPrePubBuildHooks(test_config) | |
443 RunPubBuild(bot_info, copy_path, 'web') | |
444 RunPubBuild(bot_info, copy_path, 'test', 'debug') | |
445 RunPostPubBuildHooks(test_config) | |
446 FixupTestControllerJS(copy_path) | |
447 | |
448 RunPreTestHooks(test_config) | |
449 RunPackageTesting(bot_info, copy_path, 'test') | |
450 RunPackageTesting(bot_info, copy_path, 'build/test') | |
451 RunPostTestHooks(test_config) | |
452 | |
453 if __name__ == '__main__': | |
454 main() | |
OLD | NEW |