| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # This a simple script to make building/testing Mojo components easier. | 6 # This a simple script to make building/testing Mojo components easier. |
| 7 | 7 |
| 8 import argparse | 8 import argparse |
| 9 import os | 9 import os |
| 10 import platform | 10 import platform |
| 11 import re | 11 import re |
| 12 import subprocess | 12 import subprocess |
| 13 import sys | 13 import sys |
| 14 | 14 |
| 15 from mopy.config import Config | 15 from mopy.config import Config |
| 16 from mopy.paths import Paths | 16 from mopy.paths import Paths |
| 17 | 17 |
| 18 | 18 |
| 19 def args_to_config(args): | 19 def args_to_config(args): |
| 20 # Default to host OS. | 20 # Default to host OS. |
| 21 target_os = None | 21 target_os = None |
| 22 if args.android: | 22 if args.android: |
| 23 target_os = Config.OS_ANDROID | 23 target_os = Config.OS_ANDROID |
| 24 elif args.chromeos: | 24 elif args.chromeos: |
| 25 target_os = Config.OS_CHROMEOS | 25 target_os = Config.OS_CHROMEOS |
| 26 return Config(target_os=target_os, is_debug=args.debug) | 26 |
| 27 additional_args = {} |
| 28 |
| 29 if 'clang' in args: |
| 30 if args.clang is not None: |
| 31 # If --clang/--gcc is specified, use that. |
| 32 additional_args['is_clang'] = args.clang |
| 33 else: |
| 34 # Otherwise, use the default (use clang for everything except Android and |
| 35 # Windows). |
| 36 additional_args['is_clang'] = (target_os not in (Config.OS_ANDROID, |
| 37 Config.OS_WINDOWS)) |
| 38 |
| 39 if 'asan' in args and args.asan: |
| 40 additional_args['sanitizer'] = Config.SANITIZER_ASAN |
| 41 |
| 42 # Additional non-standard config entries: |
| 43 |
| 44 if 'goma' in args: |
| 45 goma_dir = os.environ.get('GOMA_DIR') |
| 46 goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma') |
| 47 if args.goma and goma_dir: |
| 48 additional_args['use_goma'] = True |
| 49 additional_args['goma_dir'] = goma_dir |
| 50 elif args.goma and os.path.exists(goma_home_dir): |
| 51 additional_args['use_goma'] = True |
| 52 additional_args['goma_dir'] = goma_home_dir |
| 53 else: |
| 54 additional_args['use_goma'] = False |
| 55 additional_args['goma_dir'] = None |
| 56 |
| 57 if 'with_dart' in args: |
| 58 additional_args['with_dart'] = args.with_dart |
| 59 |
| 60 if 'builder_name' in args: |
| 61 additional_args['builder_name'] = args.builder_name |
| 62 if 'build_number' in args: |
| 63 additional_args['build_number'] = args.build_number |
| 64 if 'master_name' in args: |
| 65 additional_args['master_name'] = args.master_name |
| 66 if 'test_results_server' in args: |
| 67 additional_args['test_results_server'] = args.test_results_server |
| 68 |
| 69 return Config(target_os=target_os, is_debug=args.debug, **additional_args) |
| 27 | 70 |
| 28 | 71 |
| 29 def get_out_dir(args): | 72 def get_out_dir(config): |
| 30 paths = Paths(config=args_to_config(args)) | 73 paths = Paths(config) |
| 31 return paths.SrcRelPath(paths.build_dir) | 74 return paths.SrcRelPath(paths.build_dir) |
| 32 | 75 |
| 33 | 76 |
| 34 def sync(args): | 77 def sync(config): |
| 35 # pylint: disable=W0613 | 78 # pylint: disable=W0613 |
| 36 return subprocess.call(['gclient', 'sync']) | 79 return subprocess.call(['gclient', 'sync']) |
| 37 | 80 |
| 38 | 81 |
| 39 def gn(args): | 82 def gn(config): |
| 40 command = ['gn', 'gen'] | 83 command = ['gn', 'gen'] |
| 41 | 84 |
| 42 gn_args = [] | 85 gn_args = [] |
| 43 gn_args.append('is_debug=' + ('true' if args.debug else 'false')) | 86 gn_args.append('is_debug=' + ('true' if config.is_debug else 'false')) |
| 44 gn_args.append('is_asan=' + ('true' if args.asan else 'false')) | 87 gn_args.append('is_asan=' + ('true' if config.sanitizer == |
| 45 gn_args.append('is_clang=' + ('true' if args.clang else 'false')) | 88 Config.SANITIZER_ASAN else 'false')) |
| 89 gn_args.append('is_clang=' + ('true' if config.is_clang else 'false')) |
| 46 | 90 |
| 47 goma_dir = os.environ.get('GOMA_DIR') | 91 if config.values["use_goma"]: |
| 48 goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma') | |
| 49 if args.goma and goma_dir: | |
| 50 gn_args.append('use_goma=true') | 92 gn_args.append('use_goma=true') |
| 51 gn_args.append(r'''goma_dir=\"%s\"''' % goma_dir) | 93 gn_args.append(r'''goma_dir=\"%s\"''' % config.values["goma_dir"]) |
| 52 elif args.goma and os.path.exists(goma_home_dir): | |
| 53 gn_args.append('use_goma=true') | |
| 54 gn_args.append(r'''goma_dir=\"%s\"''' % goma_home_dir) | |
| 55 else: | 94 else: |
| 56 gn_args.append('use_goma=false') | 95 gn_args.append('use_goma=false') |
| 57 | 96 |
| 58 if args.with_dart: | 97 if config.values["with_dart"]: |
| 59 gn_args.append('mojo_use_dart=true') | 98 gn_args.append('mojo_use_dart=true') |
| 60 | 99 |
| 61 if args.android: | 100 if config.target_os == Config.OS_ANDROID: |
| 62 gn_args.append(r'''os=\"android\" cpu_arch=\"arm\"''') | 101 gn_args.append(r'''os=\"android\" cpu_arch=\"arm\"''') |
| 63 elif args.chromeos: | 102 elif config.target_os == Config.OS_CHROMEOS: |
| 64 gn_args.append(r'''os=\"chromeos\" ui_base_build_ime=false | 103 gn_args.append(r'''os=\"chromeos\" ui_base_build_ime=false |
| 65 use_system_harfbuzz=false''') | 104 use_system_harfbuzz=false''') |
| 66 | 105 |
| 67 out_dir = get_out_dir(args) | 106 out_dir = get_out_dir(config) |
| 68 command.append(out_dir) | 107 command.append(out_dir) |
| 69 command.append('--args="%s"' % ' '.join(gn_args)) | 108 command.append('--args="%s"' % ' '.join(gn_args)) |
| 70 | 109 |
| 71 print 'Running %s ...' % ' '.join(command) | 110 print 'Running %s ...' % ' '.join(command) |
| 72 return subprocess.call(' '.join(command), shell=True) | 111 return subprocess.call(' '.join(command), shell=True) |
| 73 | 112 |
| 74 | 113 |
| 75 def get_gn_arg_value(out_dir, arg): | 114 def get_gn_arg_value(out_dir, arg): |
| 76 args_file_path = os.path.join(out_dir, "args.gn") | 115 args_file_path = os.path.join(out_dir, "args.gn") |
| 77 if os.path.isfile(args_file_path): | 116 if os.path.isfile(args_file_path): |
| 78 key_value_regex = re.compile(r'^%s = (.+)$' % arg) | 117 key_value_regex = re.compile(r'^%s = (.+)$' % arg) |
| 79 with open(args_file_path, "r") as args_file: | 118 with open(args_file_path, "r") as args_file: |
| 80 for line in args_file.readlines(): | 119 for line in args_file.readlines(): |
| 81 m = key_value_regex.search(line) | 120 m = key_value_regex.search(line) |
| 82 if m: | 121 if m: |
| 83 return m.group(1).strip('"') | 122 return m.group(1).strip('"') |
| 84 return '' | 123 return '' |
| 85 | 124 |
| 86 | 125 |
| 87 def build(args): | 126 def build(config): |
| 88 out_dir = get_out_dir(args) | 127 out_dir = get_out_dir(config) |
| 89 print 'Building in %s ...' % out_dir | 128 print 'Building in %s ...' % out_dir |
| 90 if get_gn_arg_value(out_dir, 'use_goma') == 'true': | 129 if get_gn_arg_value(out_dir, 'use_goma') == 'true': |
| 91 # Use the configured goma directory. | 130 # Use the configured goma directory. |
| 92 local_goma_dir = get_gn_arg_value(out_dir, 'goma_dir') | 131 local_goma_dir = get_gn_arg_value(out_dir, 'goma_dir') |
| 93 print 'Ensuring goma (in %s) started ...' % local_goma_dir | 132 print 'Ensuring goma (in %s) started ...' % local_goma_dir |
| 94 command = ['python', | 133 command = ['python', |
| 95 os.path.join(local_goma_dir, 'goma_ctl.py'), | 134 os.path.join(local_goma_dir, 'goma_ctl.py'), |
| 96 'ensure_start'] | 135 'ensure_start'] |
| 97 exit_code = subprocess.call(command) | 136 exit_code = subprocess.call(command) |
| 98 if exit_code: | 137 if exit_code: |
| 99 return exit_code | 138 return exit_code |
| 100 | 139 |
| 101 return subprocess.call(['ninja', '-j', '1000', '-l', '100', '-C', out_dir, | 140 return subprocess.call(['ninja', '-j', '1000', '-l', '100', '-C', out_dir, |
| 102 'root']) | 141 'root']) |
| 103 else: | 142 else: |
| 104 return subprocess.call(['ninja', '-C', out_dir, 'root']) | 143 return subprocess.call(['ninja', '-C', out_dir, 'root']) |
| 105 | 144 |
| 106 | 145 |
| 107 def run_unittests(args): | 146 def run_unittests(config): |
| 108 out_dir = get_out_dir(args) | 147 out_dir = get_out_dir(config) |
| 109 print 'Running unit tests in %s ...' % out_dir | 148 print 'Running unit tests in %s ...' % out_dir |
| 110 command = ['python'] | 149 command = ['python'] |
| 111 if platform.system() == 'Linux': | 150 if platform.system() == 'Linux': |
| 112 command.append('./testing/xvfb.py') | 151 command.append('./testing/xvfb.py') |
| 113 command.append(out_dir) | 152 command.append(out_dir) |
| 114 | 153 |
| 115 command.append(os.path.join('mojo', 'tools', 'test_runner.py')) | 154 command.append(os.path.join('mojo', 'tools', 'test_runner.py')) |
| 116 command.append(os.path.join('mojo', 'tools', 'data', 'unittests')) | 155 command.append(os.path.join('mojo', 'tools', 'data', 'unittests')) |
| 117 command.append(out_dir) | 156 command.append(out_dir) |
| 118 command.append('mojob_test_successes') | 157 command.append('mojob_test_successes') |
| 119 return subprocess.call(command) | 158 return subprocess.call(command) |
| 120 | 159 |
| 121 def run_apptests(args): | 160 def run_apptests(config): |
| 122 out_dir = get_out_dir(args) | 161 out_dir = get_out_dir(config) |
| 123 print 'Running application tests in %s ...' % out_dir | 162 print 'Running application tests in %s ...' % out_dir |
| 124 command = ['python'] | 163 command = ['python'] |
| 125 if platform.system() == 'Linux': | 164 if platform.system() == 'Linux': |
| 126 command.append('./testing/xvfb.py') | 165 command.append('./testing/xvfb.py') |
| 127 command.append(out_dir) | 166 command.append(out_dir) |
| 128 | 167 |
| 129 command.append(os.path.join('mojo', 'tools', 'apptest_runner.py')) | 168 command.append(os.path.join('mojo', 'tools', 'apptest_runner.py')) |
| 130 command.append(os.path.join('mojo', 'tools', 'data', 'apptests')) | 169 command.append(os.path.join('mojo', 'tools', 'data', 'apptests')) |
| 131 command.append(out_dir) | 170 command.append(out_dir) |
| 132 return subprocess.call(command) | 171 return subprocess.call(command) |
| 133 | 172 |
| 134 def run_skytests(args): | 173 def run_skytests(config): |
| 135 out_dir = get_out_dir(args) | 174 out_dir = get_out_dir(config) |
| 136 if platform.system() != 'Linux': | 175 if platform.system() != 'Linux': |
| 137 return 0 | 176 return 0 |
| 138 | 177 |
| 139 command = [] | 178 command = [] |
| 140 command.append('./testing/xvfb.py') | 179 command.append('./testing/xvfb.py') |
| 141 command.append(out_dir) | 180 command.append(out_dir) |
| 142 command.append('sky/tools/test_sky') | 181 command.append('sky/tools/test_sky') |
| 143 command.append('-t') | 182 command.append('-t') |
| 144 command.append('Debug' if args.debug else 'Release') | 183 command.append('Debug' if config.is_debug else 'Release') |
| 145 command.append('--no-new-test-results') | 184 command.append('--no-new-test-results') |
| 146 command.append('--no-show-results') | 185 command.append('--no-show-results') |
| 147 command.append('--verbose') | 186 command.append('--verbose') |
| 148 | 187 |
| 149 if args.builder_name: | 188 if config.values["builder_name"]: |
| 150 command.append('--builder-name') | 189 command.append('--builder-name') |
| 151 command.append(args.builder_name) | 190 command.append(config.values["builder_name"]) |
| 152 | 191 |
| 153 if args.build_number: | 192 if config.values["build_number"]: |
| 154 command.append('--build-number') | 193 command.append('--build-number') |
| 155 command.append(args.build_number) | 194 command.append(config.values["build_number"]) |
| 156 | 195 |
| 157 if args.master_name: | 196 if config.values["master_name"]: |
| 158 command.append('--master-name') | 197 command.append('--master-name') |
| 159 command.append(args.master_name) | 198 command.append(config.values["master_name"]) |
| 160 | 199 |
| 161 if args.test_results_server: | 200 if config.values["test_results_server"]: |
| 162 command.append('--test-results-server') | 201 command.append('--test-results-server') |
| 163 command.append(args.test_results_server) | 202 command.append(config.values["test_results_server"]) |
| 164 | 203 |
| 165 subprocess.call(command) | 204 subprocess.call(command) |
| 166 # Sky tests are currently really unstable, so make the step green even if | 205 # Sky tests are currently really unstable, so make the step green even if |
| 167 # tests actually fail. | 206 # tests actually fail. |
| 168 return 0 | 207 return 0 |
| 169 | 208 |
| 170 | 209 |
| 171 def run_pytests(args): | 210 def run_pytests(config): |
| 172 out_dir = get_out_dir(args) | 211 out_dir = get_out_dir(config) |
| 173 print 'Running python tests in %s ...' % out_dir | 212 print 'Running python tests in %s ...' % out_dir |
| 174 command = ['python'] | 213 command = ['python'] |
| 175 command.append(os.path.join('mojo', 'tools', 'run_mojo_python_tests.py')) | 214 command.append(os.path.join('mojo', 'tools', 'run_mojo_python_tests.py')) |
| 176 exit_code = subprocess.call(command) | 215 exit_code = subprocess.call(command) |
| 177 if exit_code: | 216 if exit_code: |
| 178 return exit_code | 217 return exit_code |
| 179 | 218 |
| 180 if platform.system() != 'Linux': | 219 if platform.system() != 'Linux': |
| 181 print ('Python bindings tests are only supported on Linux.') | 220 print ('Python bindings tests are only supported on Linux.') |
| 182 return | 221 return |
| 183 | 222 |
| 184 command = ['python'] | 223 command = ['python'] |
| 185 command.append(os.path.join('mojo', 'tools', | 224 command.append(os.path.join('mojo', 'tools', |
| 186 'run_mojo_python_bindings_tests.py')) | 225 'run_mojo_python_bindings_tests.py')) |
| 187 command.append('--build-dir=' + out_dir) | 226 command.append('--build-dir=' + out_dir) |
| 188 return subprocess.call(command) | 227 return subprocess.call(command) |
| 189 | 228 |
| 190 | 229 |
| 191 def test(args): | 230 def test(config): |
| 192 test_suites = [run_unittests, run_apptests, run_pytests, run_skytests] | 231 test_suites = [run_unittests, run_apptests, run_pytests, run_skytests] |
| 193 final_exit_code = 0 | 232 final_exit_code = 0 |
| 194 | 233 |
| 195 for test_suite in test_suites: | 234 for test_suite in test_suites: |
| 196 exit_code = test_suite(args) | 235 exit_code = test_suite(config) |
| 197 # TODO(ojan): Find a better way to do this. We want to run all the tests | 236 # TODO(ojan): Find a better way to do this. We want to run all the tests |
| 198 # so we get coverage even if an early test suite fails, but we only have | 237 # so we get coverage even if an early test suite fails, but we only have |
| 199 # one exit code. | 238 # one exit code. |
| 200 if not final_exit_code: | 239 if not final_exit_code: |
| 201 final_exit_code = exit_code | 240 final_exit_code = exit_code |
| 202 | 241 |
| 203 return final_exit_code | 242 return final_exit_code |
| 204 | 243 |
| 205 def perftest(args): | 244 def perftest(config): |
| 206 out_dir = get_out_dir(args) | 245 out_dir = get_out_dir(config) |
| 207 print 'Running perf tests in %s ...' % out_dir | 246 print 'Running perf tests in %s ...' % out_dir |
| 208 command = [] | 247 command = [] |
| 209 command.append(os.path.join(out_dir, 'mojo_public_system_perftests')) | 248 command.append(os.path.join(out_dir, 'mojo_public_system_perftests')) |
| 210 return subprocess.call(command) | 249 return subprocess.call(command) |
| 211 | 250 |
| 212 | 251 |
| 213 def pytest(args): | 252 def pytest(config): |
| 214 return run_pytests(args) | 253 return run_pytests(config) |
| 215 | 254 |
| 216 | 255 |
| 217 def darttest(args): | 256 def darttest(config): |
| 218 out_dir = get_out_dir(args) | 257 out_dir = get_out_dir(config) |
| 219 print 'Running Dart tests in %s ...' % out_dir | 258 print 'Running Dart tests in %s ...' % out_dir |
| 220 command = [] | 259 command = [] |
| 221 command.append('dart') | 260 command.append('dart') |
| 222 command.append('--checked') | 261 command.append('--checked') |
| 223 command.append('--enable-async') | 262 command.append('--enable-async') |
| 224 command.append(os.path.join('mojo', 'tools', 'dart_test_runner.dart')) | 263 command.append(os.path.join('mojo', 'tools', 'dart_test_runner.dart')) |
| 225 command.append(os.path.join(out_dir, 'gen')) | 264 command.append(os.path.join(out_dir, 'gen')) |
| 226 return subprocess.call(command) | 265 return subprocess.call(command) |
| 227 | 266 |
| 228 | 267 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 252 sync_parser.set_defaults(func=sync) | 291 sync_parser.set_defaults(func=sync) |
| 253 | 292 |
| 254 gn_parser = subparsers.add_parser('gn', parents=[parent_parser], | 293 gn_parser = subparsers.add_parser('gn', parents=[parent_parser], |
| 255 help='Run gn for mojo (does not sync).') | 294 help='Run gn for mojo (does not sync).') |
| 256 gn_parser.set_defaults(func=gn) | 295 gn_parser.set_defaults(func=gn) |
| 257 gn_parser.add_argument('--asan', help='Uses Address Sanitizer', | 296 gn_parser.add_argument('--asan', help='Uses Address Sanitizer', |
| 258 action='store_true') | 297 action='store_true') |
| 259 gn_parser.add_argument('--with-dart', help='Configure the Dart bindings', | 298 gn_parser.add_argument('--with-dart', help='Configure the Dart bindings', |
| 260 action='store_true') | 299 action='store_true') |
| 261 clang_group = gn_parser.add_mutually_exclusive_group() | 300 clang_group = gn_parser.add_mutually_exclusive_group() |
| 262 clang_group.add_argument('--clang', help='Use Clang (default)', default=True, | 301 clang_group.add_argument('--clang', help='Use Clang (default)', default=None, |
| 263 action='store_true') | 302 action='store_true') |
| 264 clang_group.add_argument('--gcc', help='Use GCC', default=False, | 303 clang_group.add_argument('--gcc', help='Use GCC', |
| 265 dest='clang', action='store_false') | 304 dest='clang', action='store_false') |
| 266 goma_group = gn_parser.add_mutually_exclusive_group() | 305 goma_group = gn_parser.add_mutually_exclusive_group() |
| 267 goma_group.add_argument('--goma', | 306 goma_group.add_argument('--goma', |
| 268 help='Use Goma (if $GOMA_DIR is set or $HOME/goma ' | 307 help='Use Goma (if $GOMA_DIR is set or $HOME/goma ' |
| 269 'exists;default)', | 308 'exists;default)', |
| 270 default=True, | 309 default=True, |
| 271 action='store_true') | 310 action='store_true') |
| 272 goma_group.add_argument('--no-goma', help='Don\'t use Goma', default=False, | 311 goma_group.add_argument('--no-goma', help='Don\'t use Goma', default=False, |
| 273 dest='goma', action='store_false') | 312 dest='goma', action='store_false') |
| 274 | 313 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 297 | 336 |
| 298 pytest_parser = subparsers.add_parser('pytest', parents=[parent_parser], | 337 pytest_parser = subparsers.add_parser('pytest', parents=[parent_parser], |
| 299 help='Run Python unit tests (does not build).') | 338 help='Run Python unit tests (does not build).') |
| 300 pytest_parser.set_defaults(func=pytest) | 339 pytest_parser.set_defaults(func=pytest) |
| 301 | 340 |
| 302 darttest_parser = subparsers.add_parser('darttest', parents=[parent_parser], | 341 darttest_parser = subparsers.add_parser('darttest', parents=[parent_parser], |
| 303 help='Run Dart unit tests (does not build).') | 342 help='Run Dart unit tests (does not build).') |
| 304 darttest_parser.set_defaults(func=darttest) | 343 darttest_parser.set_defaults(func=darttest) |
| 305 | 344 |
| 306 args = parser.parse_args() | 345 args = parser.parse_args() |
| 307 | 346 config = args_to_config(args) |
| 308 # TODO(vtl): Pass a Config through to everything, instead of args. | 347 return args.func(config) |
| 309 | |
| 310 # Android always wants GCC. | |
| 311 if args.android: | |
| 312 args.clang = False | |
| 313 | |
| 314 if platform.system() == 'Windows': | |
| 315 args.clang = False | |
| 316 | |
| 317 return args.func(args) | |
| 318 | 348 |
| 319 | 349 |
| 320 if __name__ == '__main__': | 350 if __name__ == '__main__': |
| 321 sys.exit(main()) | 351 sys.exit(main()) |
| OLD | NEW |