Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 2 | |
Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 3 | # Copyright 2017 The Chromium Authors |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 7 | """Runs a gtest-based test on Swarming, optionally many times, collecting the |
| 8 | output of the runs into a directory. Useful for flake checking, and faster than |
| 9 | using trybots by avoiding repeated bot_update, compile, archive, etc. and |
| 10 | allowing greater parallelism. |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 11 | |
| 12 | To use, run in a new shell (it blocks until all Swarming jobs complete): |
| 13 | |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 14 | tools/run-swarmed.py out/rel base_unittests |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 15 | |
| 16 | The logs of the runs will be stored in results/ (or specify a results directory |
| 17 | with --results=some_dir). You can then do something like `grep -L SUCCESS |
| 18 | results/*` to find the tests that failed or otherwise process the log files. |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 19 | |
| 20 | See //docs/workflow/debugging-with-swarming.md for more details. |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 21 | """ |
| 22 | |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 23 | |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 24 | |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 25 | import argparse |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 26 | import hashlib |
| 27 | import json |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 28 | import multiprocessing.dummy |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 29 | import os |
| 30 | import shutil |
| 31 | import subprocess |
| 32 | import sys |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 33 | import traceback |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 34 | |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 35 | CHROMIUM_ROOT = os.path.join(os.path.dirname(__file__), os.pardir) |
| 36 | BUILD_DIR = os.path.join(CHROMIUM_ROOT, 'build') |
| 37 | |
| 38 | if BUILD_DIR not in sys.path: |
| 39 | sys.path.insert(0, BUILD_DIR) |
| 40 | import gn_helpers |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 41 | |
| 42 | INTERNAL_ERROR_EXIT_CODE = -1000 |
| 43 | |
Jeffrey Cohen | f128b51c | 2020-04-24 18:23:07 | [diff] [blame] | 44 | DEFAULT_ANDROID_DEVICE_TYPE = "walleye" |
| 45 | |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 46 | |
| 47 | def _Spawn(args): |
| 48 | """Triggers a swarming job. The arguments passed are: |
| 49 | - The index of the job; |
| 50 | - The command line arguments object; |
Junji Watanabe | 927cbe8f | 2021-01-12 21:04:26 | [diff] [blame] | 51 | - The digest of test files. |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 52 | |
| 53 | The return value is passed to a collect-style map() and consists of: |
| 54 | - The index of the job; |
| 55 | - The json file created by triggering and used to collect results; |
| 56 | - The command line arguments object. |
| 57 | """ |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 58 | try: |
| 59 | return _DoSpawn(args) |
| 60 | except Exception as e: |
| 61 | traceback.print_exc() |
| 62 | return None |
| 63 | |
| 64 | |
| 65 | def _DoSpawn(args): |
Junji Watanabe | 927cbe8f | 2021-01-12 21:04:26 | [diff] [blame] | 66 | index, args, cas_digest, swarming_command = args |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 67 | runner_args = [] |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 68 | json_file = os.path.join(args.results, '%d.json' % index) |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 69 | trigger_args = [ |
| 70 | 'tools/luci-go/swarming', |
| 71 | 'trigger', |
| 72 | '-S', |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 73 | f'https://{args.swarming_instance}.appspot.com', |
Junji Watanabe | 927cbe8f | 2021-01-12 21:04:26 | [diff] [blame] | 74 | '-digest', |
| 75 | cas_digest, |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 76 | '-dump-json', |
| 77 | json_file, |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 78 | '-tag=purpose:user-debug-run-swarmed', |
Max Ihlenfeldt | d77fbd2 | 2024-08-06 16:28:53 | [diff] [blame] | 79 | # 30 is try level. So use the same here. |
| 80 | '-priority', |
| 81 | '30', |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 82 | ] |
| 83 | if args.target_os == 'fuchsia': |
| 84 | trigger_args += [ |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 85 | '-d', |
| 86 | 'kvm=1', |
Ben Pastene | 9721f0c389 | 2020-06-15 18:50:00 | [diff] [blame] | 87 | ] |
kylechar | 97370f30 | 2023-02-01 21:32:09 | [diff] [blame] | 88 | if args.gpu is None: |
| 89 | trigger_args += [ |
| 90 | '-d', |
| 91 | 'gpu=none', |
| 92 | ] |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 93 | elif args.target_os == 'android': |
| 94 | if args.arch == 'x86': |
| 95 | # No x86 Android devices are available in swarming. So assume we want to |
| 96 | # run on emulators when building for x86 on Android. |
| 97 | args.swarming_os = 'Linux' |
| 98 | args.pool = 'chromium.tests.avd' |
Haiyang Pan | 56581b3 | 2024-07-03 20:46:40 | [diff] [blame] | 99 | # android_28_google_apis_x86 == Android P emulator. |
| 100 | # See //tools/android/avd/proto/ for other options. |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 101 | runner_args.append( |
Haiyang Pan | 56581b3 | 2024-07-03 20:46:40 | [diff] [blame] | 102 | '--avd-config=../../tools/android/avd/proto/android_28_google_apis_x86.textpb' |
| 103 | ) |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 104 | elif args.device_type is None and args.device_os is None: |
| 105 | # The aliases for device type are stored here: |
| 106 | # luci/appengine/swarming/ui2/modules/alias.js |
| 107 | # for example 'blueline' = 'Pixel 3' |
| 108 | trigger_args += ['-d', 'device_type=' + DEFAULT_ANDROID_DEVICE_TYPE] |
Victor Hugo Vianna Silva | b1a40ce | 2023-07-25 02:05:19 | [diff] [blame] | 109 | elif args.target_os == 'ios': |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 110 | runner_args.append(f'--xcode-build-version={args.ios_xcode_build_version}') |
Victor Hugo Vianna Silva | b1a40ce | 2023-07-25 02:05:19 | [diff] [blame] | 111 | runner_args.append('--xctest') |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 112 | runner_args.append('--out-dir=${ISOLATED_OUTDIR}') |
| 113 | |
| 114 | if args.ios_sim_version and args.ios_sim_platform: |
| 115 | # simulator test runner and trigger args |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 116 | runner_args.append(f'--version={args.ios_sim_version}') |
| 117 | runner_args.extend(['--platform', args.ios_sim_platform]) |
| 118 | |
| 119 | version_with_underscore = args.ios_sim_version.replace('.', '_') |
| 120 | trigger_args.extend([ |
| 121 | '-named-cache', f'runtime_ios_{version_with_underscore}' |
| 122 | f'=Runtime-ios-{args.ios_sim_version}' |
| 123 | ]) |
| 124 | elif args.ios_device: |
Will Yeager | 330009ca | 2024-04-16 15:30:20 | [diff] [blame] | 125 | # device trigger args |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 126 | trigger_args.extend(['-d', f'device={args.ios_device}']) |
| 127 | trigger_args.extend(['-d', 'device_status=available']) |
| 128 | else: |
| 129 | raise Exception('Either both of --ios-sim-version and --ios-sim-platform ' |
| 130 | 'or --ios-device is required') |
| 131 | |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 132 | trigger_args.extend( |
| 133 | ['-named-cache', f'xcode_ios_{args.ios_xcode_build_version}=Xcode.app']) |
| 134 | trigger_args.extend( |
| 135 | ['-cipd-package', '.:infra/tools/mac_toolchain/${platform}=latest']) |
Victor Hugo Vianna Silva | b1a40ce | 2023-07-25 02:05:19 | [diff] [blame] | 136 | |
Haiyang Pan | a05cb2e | 2024-04-17 20:27:26 | [diff] [blame] | 137 | if args.service_account: |
| 138 | account = args.service_account |
| 139 | elif args.swarming_instance == 'chromium-swarm': |
| 140 | account = '[email protected]' |
| 141 | elif args.swarming_instance == 'chrome-swarming': |
| 142 | account = '[email protected]' |
| 143 | trigger_args.extend(['-service-account', account]) |
| 144 | |
Victor Hugo Vianna Silva | b1a40ce | 2023-07-25 02:05:19 | [diff] [blame] | 145 | if args.arch != 'detect': |
Ben Pastene | 9721f0c389 | 2020-06-15 18:50:00 | [diff] [blame] | 146 | trigger_args += [ |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 147 | '-d', |
| 148 | 'cpu=' + args.arch, |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 149 | ] |
Jeffrey Cohen | f128b51c | 2020-04-24 18:23:07 | [diff] [blame] | 150 | |
Jeffrey Cohen | f128b51c | 2020-04-24 18:23:07 | [diff] [blame] | 151 | if args.device_type: |
| 152 | trigger_args += ['-d', 'device_type=' + args.device_type] |
| 153 | |
| 154 | if args.device_os: |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 155 | trigger_args += ['-d', 'device_os=' + args.device_os] |
Jeffrey Cohen | f128b51c | 2020-04-24 18:23:07 | [diff] [blame] | 156 | |
kylechar | 97370f30 | 2023-02-01 21:32:09 | [diff] [blame] | 157 | if args.gpu: |
| 158 | trigger_args += ['-d', 'gpu=' + args.gpu] |
| 159 | |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 160 | if not args.no_test_flags: |
| 161 | # These flags are recognized by our test runners, but do not work |
| 162 | # when running custom scripts. |
John Budorick | 2fb152e2 | 2020-06-23 04:44:54 | [diff] [blame] | 163 | runner_args += [ |
Andrew Grieve | 37370d0 | 2022-06-03 19:27:59 | [diff] [blame] | 164 | '--test-launcher-summary-output=${ISOLATED_OUTDIR}/output.json' |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 165 | ] |
Andrew Grieve | 37370d0 | 2022-06-03 19:27:59 | [diff] [blame] | 166 | if 'junit' not in args.target_name: |
| 167 | runner_args += ['--system-log-file=${ISOLATED_OUTDIR}/system_log'] |
Peter Collingbourne | 426ef6f | 2019-02-15 04:13:45 | [diff] [blame] | 168 | if args.gtest_filter: |
John Budorick | 2fb152e2 | 2020-06-23 04:44:54 | [diff] [blame] | 169 | runner_args.append('--gtest_filter=' + args.gtest_filter) |
Cammie Smith Barnes | 773a7564 | 2020-09-08 20:17:44 | [diff] [blame] | 170 | if args.gtest_repeat: |
| 171 | runner_args.append('--gtest_repeat=' + args.gtest_repeat) |
ckitagawa | 3251d62 | 2021-03-09 15:10:30 | [diff] [blame] | 172 | if args.test_launcher_shard_index and args.test_launcher_total_shards: |
| 173 | runner_args.append('--test-launcher-shard-index=' + |
| 174 | args.test_launcher_shard_index) |
| 175 | runner_args.append('--test-launcher-total-shards=' + |
| 176 | args.test_launcher_total_shards) |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 177 | elif args.target_os == 'fuchsia': |
Scott Graham | 682f1b4 | 2017-10-18 23:35:13 | [diff] [blame] | 178 | filter_file = \ |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 179 | 'testing/buildbot/filters/fuchsia.' + args.target_name + '.filter' |
Scott Graham | 682f1b4 | 2017-10-18 23:35:13 | [diff] [blame] | 180 | if os.path.isfile(filter_file): |
John Budorick | 2fb152e2 | 2020-06-23 04:44:54 | [diff] [blame] | 181 | runner_args.append('--test-launcher-filter-file=../../' + filter_file) |
| 182 | |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 183 | runner_args.extend(args.runner_args) |
| 184 | |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 185 | trigger_args.extend(['-d', 'os=' + args.swarming_os]) |
| 186 | trigger_args.extend(['-d', 'pool=' + args.pool]) |
Takuto Ikuta | b2c765b9 | 2020-12-07 23:06:22 | [diff] [blame] | 187 | trigger_args.extend(['--relative-cwd', args.out_dir, '--']) |
Dirk Pranke | a7e791a | 2020-10-26 22:18:52 | [diff] [blame] | 188 | trigger_args.extend(swarming_command) |
| 189 | trigger_args.extend(runner_args) |
John Budorick | 2fb152e2 | 2020-06-23 04:44:54 | [diff] [blame] | 190 | |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 191 | with open(os.devnull, 'w') as nul: |
| 192 | subprocess.check_call(trigger_args, stdout=nul) |
| 193 | return (index, json_file, args) |
| 194 | |
| 195 | |
| 196 | def _Collect(spawn_result): |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 197 | if spawn_result is None: |
| 198 | return 1 |
| 199 | |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 200 | index, json_file, args = spawn_result |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 201 | with open(json_file) as f: |
| 202 | task_json = json.load(f) |
| 203 | task_ids = [task['task_id'] for task in task_json['tasks']] |
Andrew Grieve | a8dedf13 | 2020-03-20 16:13:53 | [diff] [blame] | 204 | |
| 205 | for t in task_ids: |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 206 | print('Task {}: https://{}.appspot.com/task?id={}'.format( |
| 207 | index, args.swarming_instance, t)) |
| 208 | p = subprocess.Popen([ |
| 209 | 'tools/luci-go/swarming', |
| 210 | 'collect', |
| 211 | '-S', |
| 212 | f'https://{args.swarming_instance}.appspot.com', |
| 213 | '--task-output-stdout=console', |
| 214 | ] + task_ids, |
| 215 | stdout=subprocess.PIPE, |
| 216 | stderr=subprocess.STDOUT) |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 217 | stdout = p.communicate()[0] |
| 218 | if p.returncode != 0 and len(stdout) < 2**10 and 'Internal error!' in stdout: |
| 219 | exit_code = INTERNAL_ERROR_EXIT_CODE |
| 220 | file_suffix = '.INTERNAL_ERROR' |
| 221 | else: |
| 222 | exit_code = p.returncode |
| 223 | file_suffix = '' if exit_code == 0 else '.FAILED' |
| 224 | filename = '%d%s.stdout.txt' % (index, file_suffix) |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 225 | with open(os.path.join(args.results, filename), 'wb') as f: |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 226 | f.write(stdout) |
| 227 | return exit_code |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 228 | |
| 229 | |
| 230 | def main(): |
| 231 | parser = argparse.ArgumentParser() |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 232 | parser.add_argument( |
| 233 | '--swarming-instance', |
| 234 | choices=['chromium-swarm', 'chrome-swarming'], |
| 235 | default='chromium-swarm', |
| 236 | help='The swarming instance where the task(s) will be run.') |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 237 | parser.add_argument('--swarming-os', help='OS specifier for Swarming.') |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 238 | parser.add_argument('--target-os', default='detect', help='gn target_os') |
Wez | 1fcb2d12 | 2018-01-18 02:34:30 | [diff] [blame] | 239 | parser.add_argument('--arch', '-a', default='detect', |
| 240 | help='CPU architecture of the test binary.') |
Dan McArdle | ab00ef8 | 2020-12-30 05:40:55 | [diff] [blame] | 241 | parser.add_argument('--build', |
| 242 | dest='build', |
| 243 | action='store_true', |
| 244 | help='Build before isolating.') |
| 245 | parser.add_argument('--no-build', |
| 246 | dest='build', |
| 247 | action='store_false', |
| 248 | help='Do not build, just isolate (default).') |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 249 | parser.add_argument('--isolate-map-file', '-i', |
| 250 | help='path to isolate map file if not using default') |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 251 | parser.add_argument('--copies', '-n', type=int, default=1, |
| 252 | help='Number of copies to spawn.') |
Jeffrey Cohen | f128b51c | 2020-04-24 18:23:07 | [diff] [blame] | 253 | parser.add_argument( |
| 254 | '--device-os', help='Run tests on the given version of Android.') |
kylechar | 97370f30 | 2023-02-01 21:32:09 | [diff] [blame] | 255 | parser.add_argument('--device-type', |
| 256 | help='device_type specifier for Swarming' |
| 257 | ' from https://chromium-swarm.appspot.com/botlist .') |
| 258 | parser.add_argument('--gpu', |
| 259 | help='gpu specifier for Swarming' |
| 260 | ' from https://chromium-swarm.appspot.com/botlist .') |
Ben Pastene | 6ca322c | 2020-06-12 01:34:26 | [diff] [blame] | 261 | parser.add_argument('--pool', |
| 262 | default='chromium.tests', |
| 263 | help='Use the given swarming pool.') |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 264 | parser.add_argument('--results', '-r', default='results', |
| 265 | help='Directory in which to store results.') |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 266 | parser.add_argument( |
| 267 | '--gtest_filter', |
| 268 | help='Deprecated. Pass as test runner arg instead, like \'-- ' |
| 269 | '--gtest_filter="*#testFoo"\'') |
Wei-Yin Chen (陳威尹) | 3f33a02 | 2020-06-10 01:17:32 | [diff] [blame] | 270 | parser.add_argument( |
Cammie Smith Barnes | 773a7564 | 2020-09-08 20:17:44 | [diff] [blame] | 271 | '--gtest_repeat', |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 272 | help='Deprecated. Pass as test runner arg instead, like \'-- ' |
| 273 | '--gtest_repeat=99\'') |
ckitagawa | 3251d62 | 2021-03-09 15:10:30 | [diff] [blame] | 274 | parser.add_argument( |
| 275 | '--test-launcher-shard-index', |
| 276 | help='Shard index to run. Use with --test-launcher-total-shards.') |
| 277 | parser.add_argument('--test-launcher-total-shards', |
| 278 | help='Number of shards to split the test into. Use with' |
| 279 | ' --test-launcher-shard-index.') |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 280 | parser.add_argument('--no-test-flags', action='store_true', |
| 281 | help='Do not add --test-launcher-summary-output and ' |
| 282 | '--system-log-file flags to the comment.') |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 283 | parser.add_argument('out_dir', type=str, help='Build directory.') |
| 284 | parser.add_argument('target_name', type=str, help='Name of target to run.') |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 285 | parser.add_argument( |
| 286 | '--service-account', |
Haiyang Pan | a05cb2e | 2024-04-17 20:27:26 | [diff] [blame] | 287 | help='Optional service account that the swarming task will be run using. ' |
| 288 | 'Default value will be set based on the "--swarming-instance".') |
| 289 | # ios only args |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 290 | parser.add_argument('--ios-xcode-build-version', |
| 291 | help='The version of xcode that will be used for all ' |
| 292 | 'xcodebuild CLI commands') |
| 293 | parser.add_argument('--ios-sim-version', |
| 294 | help='iOS simulator version, ex. 17.2') |
| 295 | parser.add_argument('--ios-sim-platform', |
| 296 | help='iOS simulator platform, ex. iPhone 14') |
| 297 | parser.add_argument('--ios-device', |
| 298 | help='iOS physical device type, ex. iPhone12,1') |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 299 | parser.add_argument( |
| 300 | 'runner_args', |
| 301 | nargs='*', |
| 302 | type=str, |
| 303 | help='Arguments to pass to the test runner, e.g. gtest_filter and ' |
| 304 | 'gtest_repeat.') |
Ben Pastene | 11d8b766 | 2025-02-27 20:00:49 | [diff] [blame] | 305 | parser.add_argument('--force', |
| 306 | action='store_true', |
| 307 | help='Bypasses deprecation notice.') |
Scott Graham | 682f1b4 | 2017-10-18 23:35:13 | [diff] [blame] | 308 | |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 309 | args = parser.parse_intermixed_args() |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 310 | |
Ben Pastene | 11d8b766 | 2025-02-27 20:00:49 | [diff] [blame] | 311 | # TODO(crbug.com/386167803): Remove this script after this deprecation notice |
| 312 | # has been live for a few months. |
| 313 | if not args.force: |
| 314 | print( |
| 315 | 'This script is deprecated in favor of the UTR. For more info, see ' |
| 316 | 'https://chromium.googlesource.com/chromium/src/+/main/tools/utr/README.md. ' |
| 317 | 'To skip this warning, re-run this script with "--force". Note that ' |
| 318 | 'this script will be deleted sometime in 2025.', |
| 319 | file=sys.stderr) |
| 320 | return 1 |
| 321 | |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 322 | with open(os.path.join(args.out_dir, 'args.gn')) as f: |
| 323 | gn_args = gn_helpers.FromGNArgs(f.read()) |
| 324 | |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 325 | if args.target_os == 'detect': |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 326 | if 'target_os' in gn_args: |
| 327 | args.target_os = gn_args['target_os'].strip('"') |
| 328 | else: |
Takuto Ikuta | ed87b35 | 2022-02-04 11:52:56 | [diff] [blame] | 329 | args.target_os = { |
| 330 | 'darwin': 'mac', |
| 331 | 'linux': 'linux', |
| 332 | 'win32': 'win' |
| 333 | }[sys.platform] |
Nico Weber | b161b563 | 2018-02-27 14:31:44 | [diff] [blame] | 334 | |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 335 | if args.swarming_os is None: |
| 336 | args.swarming_os = { |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 337 | 'mac': 'Mac', |
| 338 | 'ios': 'Mac', |
| 339 | 'win': 'Windows', |
| 340 | 'linux': 'Linux', |
| 341 | 'android': 'Android', |
| 342 | 'fuchsia': 'Linux' |
Elly Fong-Jones | 23e2b71 | 2019-09-06 18:14:58 | [diff] [blame] | 343 | }[args.target_os] |
| 344 | |
Nico Weber | 9a7c247 | 2020-02-06 15:27:33 | [diff] [blame] | 345 | if args.target_os == 'win' and args.target_name.endswith('.exe'): |
| 346 | # The machinery expects not to have a '.exe' suffix. |
| 347 | args.target_name = os.path.splitext(args.target_name)[0] |
| 348 | |
Wez | 1fcb2d12 | 2018-01-18 02:34:30 | [diff] [blame] | 349 | # Determine the CPU architecture of the test binary, if not specified. |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 350 | if args.arch == 'detect': |
Victor Hugo Vianna Silva | b1a40ce | 2023-07-25 02:05:19 | [diff] [blame] | 351 | if args.target_os == 'ios': |
| 352 | print('iOS must specify --arch. Probably arm64 or x86-64.') |
| 353 | return 1 |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 354 | if args.target_os not in ('android', 'mac', 'win'): |
| 355 | executable_info = subprocess.check_output( |
Takuto Ikuta | ed87b35 | 2022-02-04 11:52:56 | [diff] [blame] | 356 | ['file', os.path.join(args.out_dir, args.target_name)], text=True) |
Ben Pastene | fbc2cf3 | 2021-09-29 01:29:48 | [diff] [blame] | 357 | if 'ARM aarch64' in executable_info: |
| 358 | args.arch = 'arm64', |
| 359 | else: |
| 360 | args.arch = 'x86-64' |
| 361 | elif args.target_os == 'android': |
| 362 | args.arch = gn_args.get('target_cpu', 'detect') |
Wez | 1fcb2d12 | 2018-01-18 02:34:30 | [diff] [blame] | 363 | |
Bruce Dawson | 66f8265c | 2023-02-21 19:16:05 | [diff] [blame] | 364 | mb_cmd = [sys.executable, 'tools/mb/mb.py', 'isolate'] |
Nico Weber | 9a7c247 | 2020-02-06 15:27:33 | [diff] [blame] | 365 | if not args.build: |
| 366 | mb_cmd.append('--no-build') |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 367 | if args.isolate_map_file: |
| 368 | mb_cmd += ['--isolate-map-file', args.isolate_map_file] |
Nico Weber | 9a7c247 | 2020-02-06 15:27:33 | [diff] [blame] | 369 | mb_cmd += ['//' + args.out_dir, args.target_name] |
Henrique Nakashima | 513e177 | 2021-11-10 21:23:13 | [diff] [blame] | 370 | subprocess.check_call(mb_cmd, shell=os.name == 'nt') |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 371 | |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 372 | print('If you get authentication errors, follow:') |
| 373 | print( |
Takuto Ikuta | 11aac05 | 2021-06-08 20:47:04 | [diff] [blame] | 374 | ' https://chromium.googlesource.com/chromium/src/+/HEAD/docs/workflow/debugging-with-swarming.md#authenticating' |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 375 | ) |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 376 | |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 377 | print('Uploading to isolate server, this can take a while...') |
Junji Watanabe | 927cbe8f | 2021-01-12 21:04:26 | [diff] [blame] | 378 | isolate = os.path.join(args.out_dir, args.target_name + '.isolate') |
Junji Watanabe | e3279315 | 2021-01-15 00:13:56 | [diff] [blame] | 379 | archive_json = os.path.join(args.out_dir, args.target_name + '.archive.json') |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 380 | subprocess.check_output([ |
Will Yeager | a399b98 | 2024-03-21 19:30:58 | [diff] [blame] | 381 | 'tools/luci-go/isolate', 'archive', '-cas-instance', |
| 382 | args.swarming_instance, '-isolate', isolate, '-dump-json', archive_json |
Takuto Ikuta | 85e93c1 | 2020-02-05 22:27:24 | [diff] [blame] | 383 | ]) |
Junji Watanabe | e3279315 | 2021-01-15 00:13:56 | [diff] [blame] | 384 | with open(archive_json) as f: |
Junji Watanabe | 927cbe8f | 2021-01-12 21:04:26 | [diff] [blame] | 385 | cas_digest = json.load(f).get(args.target_name) |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 386 | |
Bruce Dawson | 66f8265c | 2023-02-21 19:16:05 | [diff] [blame] | 387 | mb_cmd = [ |
| 388 | sys.executable, 'tools/mb/mb.py', 'get-swarming-command', '--as-list' |
| 389 | ] |
Dirk Pranke | a7e791a | 2020-10-26 22:18:52 | [diff] [blame] | 390 | if not args.build: |
| 391 | mb_cmd.append('--no-build') |
| 392 | if args.isolate_map_file: |
| 393 | mb_cmd += ['--isolate-map-file', args.isolate_map_file] |
| 394 | mb_cmd += ['//' + args.out_dir, args.target_name] |
Henrique Nakashima | 513e177 | 2021-11-10 21:23:13 | [diff] [blame] | 395 | mb_output = subprocess.check_output(mb_cmd, shell=os.name == 'nt') |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 396 | swarming_cmd = json.loads(mb_output) |
Dirk Pranke | a7e791a | 2020-10-26 22:18:52 | [diff] [blame] | 397 | |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 398 | if os.path.isdir(args.results): |
| 399 | shutil.rmtree(args.results) |
| 400 | os.makedirs(args.results) |
| 401 | |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 402 | try: |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 403 | print('Triggering %d tasks...' % args.copies) |
Andrew Grieve | 5d0a0f8 | 2020-03-20 17:26:59 | [diff] [blame] | 404 | # Use dummy since threadpools give better exception messages |
| 405 | # than process pools do, and threads work fine for what we're doing. |
| 406 | pool = multiprocessing.dummy.Pool() |
Henrique Nakashima | 14cfed59 | 2021-11-10 19:35:07 | [diff] [blame] | 407 | spawn_args = [(i, args, cas_digest, swarming_cmd) |
| 408 | for i in range(args.copies)] |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 409 | spawn_results = pool.imap_unordered(_Spawn, spawn_args) |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 410 | |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 411 | exit_codes = [] |
| 412 | collect_results = pool.imap_unordered(_Collect, spawn_results) |
| 413 | for result in collect_results: |
| 414 | exit_codes.append(result) |
| 415 | successes = sum(1 for x in exit_codes if x == 0) |
| 416 | errors = sum(1 for x in exit_codes if x == INTERNAL_ERROR_EXIT_CODE) |
| 417 | failures = len(exit_codes) - successes - errors |
| 418 | clear_to_eol = '\033[K' |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 419 | print( |
| 420 | '\r[%d/%d] collected: ' |
| 421 | '%d successes, %d failures, %d bot errors...%s' % |
| 422 | (len(exit_codes), args.copies, successes, failures, errors, |
| 423 | clear_to_eol), |
| 424 | end=' ') |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 425 | sys.stdout.flush() |
| 426 | |
Raul Tambre | 66e754d | 2019-09-25 12:03:44 | [diff] [blame] | 427 | print() |
| 428 | print('Results logs collected into', os.path.abspath(args.results) + '.') |
Scott Graham | a3f9577 | 2017-10-10 19:37:39 | [diff] [blame] | 429 | finally: |
| 430 | pool.close() |
| 431 | pool.join() |
Scott Graham | 5865515 | 2017-09-22 22:41:01 | [diff] [blame] | 432 | return 0 |
| 433 | |
| 434 | |
| 435 | if __name__ == '__main__': |
| 436 | sys.exit(main()) |