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 |