1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env vpython3 2*6777b538SAndroid Build Coastguard Worker# 3*6777b538SAndroid Build Coastguard Worker# Copyright 2013 The Chromium Authors 4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker"""Runs all types of tests from one unified interface.""" 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Workerfrom __future__ import absolute_import 10*6777b538SAndroid Build Coastguard Workerimport argparse 11*6777b538SAndroid Build Coastguard Workerimport collections 12*6777b538SAndroid Build Coastguard Workerimport contextlib 13*6777b538SAndroid Build Coastguard Workerimport io 14*6777b538SAndroid Build Coastguard Workerimport itertools 15*6777b538SAndroid Build Coastguard Workerimport logging 16*6777b538SAndroid Build Coastguard Workerimport os 17*6777b538SAndroid Build Coastguard Workerimport re 18*6777b538SAndroid Build Coastguard Workerimport shlex 19*6777b538SAndroid Build Coastguard Workerimport shutil 20*6777b538SAndroid Build Coastguard Workerimport signal 21*6777b538SAndroid Build Coastguard Workerimport sys 22*6777b538SAndroid Build Coastguard Workerimport tempfile 23*6777b538SAndroid Build Coastguard Workerimport threading 24*6777b538SAndroid Build Coastguard Workerimport traceback 25*6777b538SAndroid Build Coastguard Workerimport unittest 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker# Import _strptime before threaded code. datetime.datetime.strptime is 28*6777b538SAndroid Build Coastguard Worker# threadsafe except for the initial import of the _strptime module. 29*6777b538SAndroid Build Coastguard Worker# See http://crbug.com/724524 and https://bugs.python.org/issue7980. 30*6777b538SAndroid Build Coastguard Workerimport _strptime # pylint: disable=unused-import 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker# pylint: disable=ungrouped-imports 33*6777b538SAndroid Build Coastguard Workerfrom pylib.constants import host_paths 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Workerif host_paths.DEVIL_PATH not in sys.path: 36*6777b538SAndroid Build Coastguard Worker sys.path.append(host_paths.DEVIL_PATH) 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Workerfrom devil import base_error 39*6777b538SAndroid Build Coastguard Workerfrom devil.utils import reraiser_thread 40*6777b538SAndroid Build Coastguard Workerfrom devil.utils import run_tests_helper 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Workerfrom pylib import constants 43*6777b538SAndroid Build Coastguard Workerfrom pylib.base import base_test_result 44*6777b538SAndroid Build Coastguard Workerfrom pylib.base import environment_factory 45*6777b538SAndroid Build Coastguard Workerfrom pylib.base import output_manager 46*6777b538SAndroid Build Coastguard Workerfrom pylib.base import output_manager_factory 47*6777b538SAndroid Build Coastguard Workerfrom pylib.base import test_instance_factory 48*6777b538SAndroid Build Coastguard Workerfrom pylib.base import test_run_factory 49*6777b538SAndroid Build Coastguard Workerfrom pylib.results import json_results 50*6777b538SAndroid Build Coastguard Workerfrom pylib.results import report_results 51*6777b538SAndroid Build Coastguard Workerfrom pylib.results.presentation import test_results_presentation 52*6777b538SAndroid Build Coastguard Workerfrom pylib.utils import local_utils 53*6777b538SAndroid Build Coastguard Workerfrom pylib.utils import logdog_helper 54*6777b538SAndroid Build Coastguard Workerfrom pylib.utils import logging_utils 55*6777b538SAndroid Build Coastguard Workerfrom pylib.utils import test_filter 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Workerfrom py_utils import contextlib_ext 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Workerfrom lib.results import result_sink # pylint: disable=import-error 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker_DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join( 62*6777b538SAndroid Build Coastguard Worker host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json')) 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker_RERUN_FAILED_TESTS_FILE = 'rerun_failed_tests.filter' 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Workerdef _RealPath(arg): 68*6777b538SAndroid Build Coastguard Worker if arg.startswith('//'): 69*6777b538SAndroid Build Coastguard Worker arg = os.path.abspath(os.path.join(host_paths.DIR_SOURCE_ROOT, 70*6777b538SAndroid Build Coastguard Worker arg[2:].replace('/', os.sep))) 71*6777b538SAndroid Build Coastguard Worker return os.path.realpath(arg) 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Workerdef AddTestLauncherOptions(parser): 75*6777b538SAndroid Build Coastguard Worker """Adds arguments mirroring //base/test/launcher. 76*6777b538SAndroid Build Coastguard Worker 77*6777b538SAndroid Build Coastguard Worker Args: 78*6777b538SAndroid Build Coastguard Worker parser: The parser to which arguments should be added. 79*6777b538SAndroid Build Coastguard Worker Returns: 80*6777b538SAndroid Build Coastguard Worker The given parser. 81*6777b538SAndroid Build Coastguard Worker """ 82*6777b538SAndroid Build Coastguard Worker parser.add_argument( 83*6777b538SAndroid Build Coastguard Worker '--test-launcher-retry-limit', 84*6777b538SAndroid Build Coastguard Worker '--test_launcher_retry_limit', 85*6777b538SAndroid Build Coastguard Worker '--num_retries', '--num-retries', 86*6777b538SAndroid Build Coastguard Worker '--isolated-script-test-launcher-retry-limit', 87*6777b538SAndroid Build Coastguard Worker dest='num_retries', type=int, default=2, 88*6777b538SAndroid Build Coastguard Worker help='Number of retries for a test before ' 89*6777b538SAndroid Build Coastguard Worker 'giving up (default: %(default)s).') 90*6777b538SAndroid Build Coastguard Worker parser.add_argument( 91*6777b538SAndroid Build Coastguard Worker '--test-launcher-summary-output', 92*6777b538SAndroid Build Coastguard Worker '--json-results-file', 93*6777b538SAndroid Build Coastguard Worker dest='json_results_file', type=os.path.realpath, 94*6777b538SAndroid Build Coastguard Worker help='If set, will dump results in JSON form to the specified file. ' 95*6777b538SAndroid Build Coastguard Worker 'Note that this will also trigger saving per-test logcats to ' 96*6777b538SAndroid Build Coastguard Worker 'logdog.') 97*6777b538SAndroid Build Coastguard Worker parser.add_argument( 98*6777b538SAndroid Build Coastguard Worker '--test-launcher-shard-index', 99*6777b538SAndroid Build Coastguard Worker type=int, default=os.environ.get('GTEST_SHARD_INDEX', 0), 100*6777b538SAndroid Build Coastguard Worker help='Index of the external shard to run.') 101*6777b538SAndroid Build Coastguard Worker parser.add_argument( 102*6777b538SAndroid Build Coastguard Worker '--test-launcher-total-shards', 103*6777b538SAndroid Build Coastguard Worker type=int, default=os.environ.get('GTEST_TOTAL_SHARDS', 1), 104*6777b538SAndroid Build Coastguard Worker help='Total number of external shards.') 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker test_filter.AddFilterOptions(parser) 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker return parser 109*6777b538SAndroid Build Coastguard Worker 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Workerdef AddCommandLineOptions(parser): 112*6777b538SAndroid Build Coastguard Worker """Adds arguments to support passing command-line flags to the device.""" 113*6777b538SAndroid Build Coastguard Worker parser.add_argument( 114*6777b538SAndroid Build Coastguard Worker '--device-flags-file', 115*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 116*6777b538SAndroid Build Coastguard Worker help='The relative filepath to a file containing ' 117*6777b538SAndroid Build Coastguard Worker 'command-line flags to set on the device') 118*6777b538SAndroid Build Coastguard Worker parser.add_argument( 119*6777b538SAndroid Build Coastguard Worker '--use-apk-under-test-flags-file', 120*6777b538SAndroid Build Coastguard Worker action='store_true', 121*6777b538SAndroid Build Coastguard Worker help='Wether to use the flags file for the apk under test. If set, ' 122*6777b538SAndroid Build Coastguard Worker "the filename will be looked up in the APK's PackageInfo.") 123*6777b538SAndroid Build Coastguard Worker parser.add_argument('--variations-test-seed-path', 124*6777b538SAndroid Build Coastguard Worker type=os.path.relpath, 125*6777b538SAndroid Build Coastguard Worker default=None, 126*6777b538SAndroid Build Coastguard Worker help='Path to variations seed file.') 127*6777b538SAndroid Build Coastguard Worker parser.add_argument('--webview-variations-test-seed-path', 128*6777b538SAndroid Build Coastguard Worker type=os.path.relpath, 129*6777b538SAndroid Build Coastguard Worker default=None, 130*6777b538SAndroid Build Coastguard Worker help='Path to variations seed file for WebView.') 131*6777b538SAndroid Build Coastguard Worker 132*6777b538SAndroid Build Coastguard Worker parser.set_defaults(allow_unknown=True) 133*6777b538SAndroid Build Coastguard Worker parser.set_defaults(command_line_flags=None) 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Workerdef AddTracingOptions(parser): 137*6777b538SAndroid Build Coastguard Worker # TODO(shenghuazhang): Move this into AddCommonOptions once it's supported 138*6777b538SAndroid Build Coastguard Worker # for all test types. 139*6777b538SAndroid Build Coastguard Worker parser.add_argument( 140*6777b538SAndroid Build Coastguard Worker '--trace-output', 141*6777b538SAndroid Build Coastguard Worker metavar='FILENAME', type=os.path.realpath, 142*6777b538SAndroid Build Coastguard Worker help='Path to save test_runner trace json output to.') 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker parser.add_argument( 145*6777b538SAndroid Build Coastguard Worker '--trace-all', 146*6777b538SAndroid Build Coastguard Worker action='store_true', 147*6777b538SAndroid Build Coastguard Worker help='Whether to trace all function calls.') 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker 150*6777b538SAndroid Build Coastguard Workerdef AddCommonOptions(parser): 151*6777b538SAndroid Build Coastguard Worker """Adds all common options to |parser|.""" 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker default_build_type = os.environ.get('BUILDTYPE', 'Debug') 154*6777b538SAndroid Build Coastguard Worker 155*6777b538SAndroid Build Coastguard Worker debug_or_release_group = parser.add_mutually_exclusive_group() 156*6777b538SAndroid Build Coastguard Worker debug_or_release_group.add_argument( 157*6777b538SAndroid Build Coastguard Worker '--debug', 158*6777b538SAndroid Build Coastguard Worker action='store_const', const='Debug', dest='build_type', 159*6777b538SAndroid Build Coastguard Worker default=default_build_type, 160*6777b538SAndroid Build Coastguard Worker help='If set, run test suites under out/Debug. ' 161*6777b538SAndroid Build Coastguard Worker 'Default is env var BUILDTYPE or Debug.') 162*6777b538SAndroid Build Coastguard Worker debug_or_release_group.add_argument( 163*6777b538SAndroid Build Coastguard Worker '--release', 164*6777b538SAndroid Build Coastguard Worker action='store_const', const='Release', dest='build_type', 165*6777b538SAndroid Build Coastguard Worker help='If set, run test suites under out/Release. ' 166*6777b538SAndroid Build Coastguard Worker 'Default is env var BUILDTYPE or Debug.') 167*6777b538SAndroid Build Coastguard Worker 168*6777b538SAndroid Build Coastguard Worker parser.add_argument( 169*6777b538SAndroid Build Coastguard Worker '--break-on-failure', '--break_on_failure', 170*6777b538SAndroid Build Coastguard Worker dest='break_on_failure', action='store_true', 171*6777b538SAndroid Build Coastguard Worker help='Whether to break on failure.') 172*6777b538SAndroid Build Coastguard Worker 173*6777b538SAndroid Build Coastguard Worker # TODO(jbudorick): Remove this once everything has switched to platform 174*6777b538SAndroid Build Coastguard Worker # mode. 175*6777b538SAndroid Build Coastguard Worker parser.add_argument( 176*6777b538SAndroid Build Coastguard Worker '--enable-platform-mode', 177*6777b538SAndroid Build Coastguard Worker action='store_true', 178*6777b538SAndroid Build Coastguard Worker help='Run the test scripts in platform mode, which ' 179*6777b538SAndroid Build Coastguard Worker 'conceptually separates the test runner from the ' 180*6777b538SAndroid Build Coastguard Worker '"device" (local or remote, real or emulated) on ' 181*6777b538SAndroid Build Coastguard Worker 'which the tests are running. [experimental]') 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker parser.add_argument( 184*6777b538SAndroid Build Coastguard Worker '-e', '--environment', 185*6777b538SAndroid Build Coastguard Worker default='local', choices=constants.VALID_ENVIRONMENTS, 186*6777b538SAndroid Build Coastguard Worker help='Test environment to run in (default: %(default)s).') 187*6777b538SAndroid Build Coastguard Worker 188*6777b538SAndroid Build Coastguard Worker parser.add_argument( 189*6777b538SAndroid Build Coastguard Worker '--local-output', 190*6777b538SAndroid Build Coastguard Worker action='store_true', 191*6777b538SAndroid Build Coastguard Worker help='Whether to archive test output locally and generate ' 192*6777b538SAndroid Build Coastguard Worker 'a local results detail page.') 193*6777b538SAndroid Build Coastguard Worker 194*6777b538SAndroid Build Coastguard Worker parser.add_argument('--list-tests', 195*6777b538SAndroid Build Coastguard Worker action='store_true', 196*6777b538SAndroid Build Coastguard Worker help='List available tests and exit.') 197*6777b538SAndroid Build Coastguard Worker 198*6777b538SAndroid Build Coastguard Worker parser.add_argument('--wrapper-script-args', 199*6777b538SAndroid Build Coastguard Worker help='A string of args that were passed to the wrapper ' 200*6777b538SAndroid Build Coastguard Worker 'script. This should probably not be edited by a ' 201*6777b538SAndroid Build Coastguard Worker 'user as it is passed by the wrapper itself.') 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Worker class FastLocalDevAction(argparse.Action): 204*6777b538SAndroid Build Coastguard Worker def __call__(self, parser, namespace, values, option_string=None): 205*6777b538SAndroid Build Coastguard Worker namespace.enable_concurrent_adb = True 206*6777b538SAndroid Build Coastguard Worker namespace.enable_device_cache = True 207*6777b538SAndroid Build Coastguard Worker namespace.extract_test_list_from_filter = True 208*6777b538SAndroid Build Coastguard Worker namespace.local_output = True 209*6777b538SAndroid Build Coastguard Worker namespace.num_retries = 0 210*6777b538SAndroid Build Coastguard Worker namespace.skip_clear_data = True 211*6777b538SAndroid Build Coastguard Worker namespace.use_persistent_shell = True 212*6777b538SAndroid Build Coastguard Worker 213*6777b538SAndroid Build Coastguard Worker parser.add_argument( 214*6777b538SAndroid Build Coastguard Worker '--fast-local-dev', 215*6777b538SAndroid Build Coastguard Worker type=bool, 216*6777b538SAndroid Build Coastguard Worker nargs=0, 217*6777b538SAndroid Build Coastguard Worker action=FastLocalDevAction, 218*6777b538SAndroid Build Coastguard Worker help='Alias for: --num-retries=0 --enable-device-cache ' 219*6777b538SAndroid Build Coastguard Worker '--enable-concurrent-adb --skip-clear-data ' 220*6777b538SAndroid Build Coastguard Worker '--extract-test-list-from-filter --use-persistent-shell --local-output') 221*6777b538SAndroid Build Coastguard Worker 222*6777b538SAndroid Build Coastguard Worker # TODO(jbudorick): Remove this once downstream bots have switched to 223*6777b538SAndroid Build Coastguard Worker # api.test_results. 224*6777b538SAndroid Build Coastguard Worker parser.add_argument( 225*6777b538SAndroid Build Coastguard Worker '--flakiness-dashboard-server', 226*6777b538SAndroid Build Coastguard Worker dest='flakiness_dashboard_server', 227*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 228*6777b538SAndroid Build Coastguard Worker parser.add_argument( 229*6777b538SAndroid Build Coastguard Worker '--gs-results-bucket', 230*6777b538SAndroid Build Coastguard Worker help='Google Storage bucket to upload results to.') 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker parser.add_argument( 233*6777b538SAndroid Build Coastguard Worker '--output-directory', 234*6777b538SAndroid Build Coastguard Worker dest='output_directory', type=os.path.realpath, 235*6777b538SAndroid Build Coastguard Worker help='Path to the directory in which build files are' 236*6777b538SAndroid Build Coastguard Worker ' located (must include build type). This will take' 237*6777b538SAndroid Build Coastguard Worker ' precedence over --debug and --release') 238*6777b538SAndroid Build Coastguard Worker parser.add_argument( 239*6777b538SAndroid Build Coastguard Worker '-v', '--verbose', 240*6777b538SAndroid Build Coastguard Worker dest='verbose_count', default=0, action='count', 241*6777b538SAndroid Build Coastguard Worker help='Verbose level (multiple times for more)') 242*6777b538SAndroid Build Coastguard Worker 243*6777b538SAndroid Build Coastguard Worker parser.add_argument( 244*6777b538SAndroid Build Coastguard Worker '--repeat', '--gtest_repeat', '--gtest-repeat', 245*6777b538SAndroid Build Coastguard Worker '--isolated-script-test-repeat', 246*6777b538SAndroid Build Coastguard Worker dest='repeat', type=int, default=0, 247*6777b538SAndroid Build Coastguard Worker help='Number of times to repeat the specified set of tests.') 248*6777b538SAndroid Build Coastguard Worker 249*6777b538SAndroid Build Coastguard Worker # Not useful for junit tests. 250*6777b538SAndroid Build Coastguard Worker parser.add_argument( 251*6777b538SAndroid Build Coastguard Worker '--use-persistent-shell', 252*6777b538SAndroid Build Coastguard Worker action='store_true', 253*6777b538SAndroid Build Coastguard Worker help='Uses a persistent shell connection for the adb connection.') 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker parser.add_argument('--disable-test-server', 256*6777b538SAndroid Build Coastguard Worker action='store_true', 257*6777b538SAndroid Build Coastguard Worker help='Disables SpawnedTestServer which doesn' 258*6777b538SAndroid Build Coastguard Worker 't work with remote adb. ' 259*6777b538SAndroid Build Coastguard Worker 'WARNING: Will break tests which require the server.') 260*6777b538SAndroid Build Coastguard Worker 261*6777b538SAndroid Build Coastguard Worker # This is currently only implemented for gtests and instrumentation tests. 262*6777b538SAndroid Build Coastguard Worker parser.add_argument( 263*6777b538SAndroid Build Coastguard Worker '--gtest_also_run_disabled_tests', '--gtest-also-run-disabled-tests', 264*6777b538SAndroid Build Coastguard Worker '--isolated-script-test-also-run-disabled-tests', 265*6777b538SAndroid Build Coastguard Worker dest='run_disabled', action='store_true', 266*6777b538SAndroid Build Coastguard Worker help='Also run disabled tests if applicable.') 267*6777b538SAndroid Build Coastguard Worker 268*6777b538SAndroid Build Coastguard Worker # These are currently only implemented for gtests. 269*6777b538SAndroid Build Coastguard Worker parser.add_argument('--isolated-script-test-output', 270*6777b538SAndroid Build Coastguard Worker help='If present, store test results on this path.') 271*6777b538SAndroid Build Coastguard Worker parser.add_argument('--isolated-script-test-perf-output', 272*6777b538SAndroid Build Coastguard Worker help='If present, store chartjson results on this path.') 273*6777b538SAndroid Build Coastguard Worker 274*6777b538SAndroid Build Coastguard Worker AddTestLauncherOptions(parser) 275*6777b538SAndroid Build Coastguard Worker 276*6777b538SAndroid Build Coastguard Worker 277*6777b538SAndroid Build Coastguard Workerdef ProcessCommonOptions(args): 278*6777b538SAndroid Build Coastguard Worker """Processes and handles all common options.""" 279*6777b538SAndroid Build Coastguard Worker run_tests_helper.SetLogLevel(args.verbose_count, add_handler=False) 280*6777b538SAndroid Build Coastguard Worker if args.verbose_count > 0: 281*6777b538SAndroid Build Coastguard Worker handler = logging_utils.ColorStreamHandler() 282*6777b538SAndroid Build Coastguard Worker else: 283*6777b538SAndroid Build Coastguard Worker handler = logging.StreamHandler(sys.stdout) 284*6777b538SAndroid Build Coastguard Worker handler.setFormatter(run_tests_helper.CustomFormatter()) 285*6777b538SAndroid Build Coastguard Worker logging.getLogger().addHandler(handler) 286*6777b538SAndroid Build Coastguard Worker 287*6777b538SAndroid Build Coastguard Worker constants.SetBuildType(args.build_type) 288*6777b538SAndroid Build Coastguard Worker if args.output_directory: 289*6777b538SAndroid Build Coastguard Worker constants.SetOutputDirectory(args.output_directory) 290*6777b538SAndroid Build Coastguard Worker 291*6777b538SAndroid Build Coastguard Worker 292*6777b538SAndroid Build Coastguard Workerdef AddDeviceOptions(parser): 293*6777b538SAndroid Build Coastguard Worker """Adds device options to |parser|.""" 294*6777b538SAndroid Build Coastguard Worker 295*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('device arguments') 296*6777b538SAndroid Build Coastguard Worker 297*6777b538SAndroid Build Coastguard Worker parser.add_argument( 298*6777b538SAndroid Build Coastguard Worker '--adb-path', 299*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 300*6777b538SAndroid Build Coastguard Worker help='Specify the absolute path of the adb binary that ' 301*6777b538SAndroid Build Coastguard Worker 'should be used.') 302*6777b538SAndroid Build Coastguard Worker parser.add_argument( 303*6777b538SAndroid Build Coastguard Worker '--use-local-devil-tools', 304*6777b538SAndroid Build Coastguard Worker action='store_true', 305*6777b538SAndroid Build Coastguard Worker help='Use locally built versions of tools used by devil_chromium.') 306*6777b538SAndroid Build Coastguard Worker parser.add_argument('--denylist-file', 307*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 308*6777b538SAndroid Build Coastguard Worker help='Device denylist file.') 309*6777b538SAndroid Build Coastguard Worker parser.add_argument( 310*6777b538SAndroid Build Coastguard Worker '-d', '--device', nargs='+', 311*6777b538SAndroid Build Coastguard Worker dest='test_devices', 312*6777b538SAndroid Build Coastguard Worker help='Target device(s) for the test suite to run on.') 313*6777b538SAndroid Build Coastguard Worker parser.add_argument( 314*6777b538SAndroid Build Coastguard Worker '--enable-concurrent-adb', 315*6777b538SAndroid Build Coastguard Worker action='store_true', 316*6777b538SAndroid Build Coastguard Worker help='Run multiple adb commands at the same time, even ' 317*6777b538SAndroid Build Coastguard Worker 'for the same device.') 318*6777b538SAndroid Build Coastguard Worker parser.add_argument( 319*6777b538SAndroid Build Coastguard Worker '--enable-device-cache', 320*6777b538SAndroid Build Coastguard Worker action='store_true', 321*6777b538SAndroid Build Coastguard Worker help='Cache device state to disk between runs') 322*6777b538SAndroid Build Coastguard Worker parser.add_argument( 323*6777b538SAndroid Build Coastguard Worker '--skip-clear-data', 324*6777b538SAndroid Build Coastguard Worker action='store_true', 325*6777b538SAndroid Build Coastguard Worker help='Do not wipe app data between tests. Use this to ' 326*6777b538SAndroid Build Coastguard Worker 'speed up local development and never on bots ' 327*6777b538SAndroid Build Coastguard Worker '(increases flakiness)') 328*6777b538SAndroid Build Coastguard Worker parser.add_argument( 329*6777b538SAndroid Build Coastguard Worker '--recover-devices', 330*6777b538SAndroid Build Coastguard Worker action='store_true', 331*6777b538SAndroid Build Coastguard Worker help='Attempt to recover devices prior to the final retry. Warning: ' 332*6777b538SAndroid Build Coastguard Worker 'this will cause all devices to reboot.') 333*6777b538SAndroid Build Coastguard Worker parser.add_argument( 334*6777b538SAndroid Build Coastguard Worker '--tool', 335*6777b538SAndroid Build Coastguard Worker dest='tool', 336*6777b538SAndroid Build Coastguard Worker help='Run the test under a tool ' 337*6777b538SAndroid Build Coastguard Worker '(use --tool help to list them)') 338*6777b538SAndroid Build Coastguard Worker 339*6777b538SAndroid Build Coastguard Worker parser.add_argument( 340*6777b538SAndroid Build Coastguard Worker '--upload-logcats-file', 341*6777b538SAndroid Build Coastguard Worker action='store_true', 342*6777b538SAndroid Build Coastguard Worker dest='upload_logcats_file', 343*6777b538SAndroid Build Coastguard Worker help='Whether to upload logcat file to logdog.') 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker logcat_output_group = parser.add_mutually_exclusive_group() 346*6777b538SAndroid Build Coastguard Worker logcat_output_group.add_argument( 347*6777b538SAndroid Build Coastguard Worker '--logcat-output-dir', type=os.path.realpath, 348*6777b538SAndroid Build Coastguard Worker help='If set, will dump logcats recorded during test run to directory. ' 349*6777b538SAndroid Build Coastguard Worker 'File names will be the device ids with timestamps.') 350*6777b538SAndroid Build Coastguard Worker logcat_output_group.add_argument( 351*6777b538SAndroid Build Coastguard Worker '--logcat-output-file', type=os.path.realpath, 352*6777b538SAndroid Build Coastguard Worker help='If set, will merge logcats recorded during test run and dump them ' 353*6777b538SAndroid Build Coastguard Worker 'to the specified file.') 354*6777b538SAndroid Build Coastguard Worker 355*6777b538SAndroid Build Coastguard Worker parser.add_argument( 356*6777b538SAndroid Build Coastguard Worker '--force-main-user', 357*6777b538SAndroid Build Coastguard Worker action='store_true', 358*6777b538SAndroid Build Coastguard Worker help='Force the applicable adb commands to run with "--user" param set ' 359*6777b538SAndroid Build Coastguard Worker 'to the id of the main user on device. Only use when the main user is a ' 360*6777b538SAndroid Build Coastguard Worker 'secondary user, e.g. Android Automotive OS.') 361*6777b538SAndroid Build Coastguard Worker 362*6777b538SAndroid Build Coastguard Worker 363*6777b538SAndroid Build Coastguard Workerdef AddEmulatorOptions(parser): 364*6777b538SAndroid Build Coastguard Worker """Adds emulator-specific options to |parser|.""" 365*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('emulator arguments') 366*6777b538SAndroid Build Coastguard Worker 367*6777b538SAndroid Build Coastguard Worker parser.add_argument( 368*6777b538SAndroid Build Coastguard Worker '--avd-config', 369*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 370*6777b538SAndroid Build Coastguard Worker help='Path to the avd config textpb. ' 371*6777b538SAndroid Build Coastguard Worker '(See //tools/android/avd/proto/ for message definition' 372*6777b538SAndroid Build Coastguard Worker ' and existing textpb files.)') 373*6777b538SAndroid Build Coastguard Worker parser.add_argument( 374*6777b538SAndroid Build Coastguard Worker '--emulator-count', 375*6777b538SAndroid Build Coastguard Worker type=int, 376*6777b538SAndroid Build Coastguard Worker default=1, 377*6777b538SAndroid Build Coastguard Worker help='Number of emulators to use.') 378*6777b538SAndroid Build Coastguard Worker parser.add_argument( 379*6777b538SAndroid Build Coastguard Worker '--emulator-window', 380*6777b538SAndroid Build Coastguard Worker action='store_true', 381*6777b538SAndroid Build Coastguard Worker default=False, 382*6777b538SAndroid Build Coastguard Worker help='Enable graphical window display on the emulator.') 383*6777b538SAndroid Build Coastguard Worker parser.add_argument( 384*6777b538SAndroid Build Coastguard Worker '--emulator-debug-tags', 385*6777b538SAndroid Build Coastguard Worker help='Comma-separated list of debug tags. This can be used to enable or ' 386*6777b538SAndroid Build Coastguard Worker 'disable debug messages from specific parts of the emulator, e.g. ' 387*6777b538SAndroid Build Coastguard Worker 'init,snapshot. See "emulator -help-debug-tags" ' 388*6777b538SAndroid Build Coastguard Worker 'for a full list of tags.') 389*6777b538SAndroid Build Coastguard Worker parser.add_argument( 390*6777b538SAndroid Build Coastguard Worker '--emulator-enable-network', 391*6777b538SAndroid Build Coastguard Worker action='store_true', 392*6777b538SAndroid Build Coastguard Worker help='Enable the network (WiFi and mobile data) on the emulator.') 393*6777b538SAndroid Build Coastguard Worker 394*6777b538SAndroid Build Coastguard Worker 395*6777b538SAndroid Build Coastguard Workerdef AddGTestOptions(parser): 396*6777b538SAndroid Build Coastguard Worker """Adds gtest options to |parser|.""" 397*6777b538SAndroid Build Coastguard Worker 398*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('gtest arguments') 399*6777b538SAndroid Build Coastguard Worker 400*6777b538SAndroid Build Coastguard Worker parser.add_argument( 401*6777b538SAndroid Build Coastguard Worker '--additional-apk', 402*6777b538SAndroid Build Coastguard Worker action='append', dest='additional_apks', default=[], 403*6777b538SAndroid Build Coastguard Worker type=_RealPath, 404*6777b538SAndroid Build Coastguard Worker help='Additional apk that must be installed on ' 405*6777b538SAndroid Build Coastguard Worker 'the device when the tests are run.') 406*6777b538SAndroid Build Coastguard Worker parser.add_argument( 407*6777b538SAndroid Build Coastguard Worker '--app-data-file', 408*6777b538SAndroid Build Coastguard Worker action='append', dest='app_data_files', 409*6777b538SAndroid Build Coastguard Worker help='A file path relative to the app data directory ' 410*6777b538SAndroid Build Coastguard Worker 'that should be saved to the host.') 411*6777b538SAndroid Build Coastguard Worker parser.add_argument( 412*6777b538SAndroid Build Coastguard Worker '--app-data-file-dir', 413*6777b538SAndroid Build Coastguard Worker help='Host directory to which app data files will be' 414*6777b538SAndroid Build Coastguard Worker ' saved. Used with --app-data-file.') 415*6777b538SAndroid Build Coastguard Worker parser.add_argument( 416*6777b538SAndroid Build Coastguard Worker '--enable-xml-result-parsing', 417*6777b538SAndroid Build Coastguard Worker action='store_true', help=argparse.SUPPRESS) 418*6777b538SAndroid Build Coastguard Worker parser.add_argument( 419*6777b538SAndroid Build Coastguard Worker '--executable-dist-dir', 420*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 421*6777b538SAndroid Build Coastguard Worker help="Path to executable's dist directory for native" 422*6777b538SAndroid Build Coastguard Worker " (non-apk) tests.") 423*6777b538SAndroid Build Coastguard Worker parser.add_argument( 424*6777b538SAndroid Build Coastguard Worker '--extract-test-list-from-filter', 425*6777b538SAndroid Build Coastguard Worker action='store_true', 426*6777b538SAndroid Build Coastguard Worker help='When a test filter is specified, and the list of ' 427*6777b538SAndroid Build Coastguard Worker 'tests can be determined from it, skip querying the ' 428*6777b538SAndroid Build Coastguard Worker 'device for the list of all tests. Speeds up local ' 429*6777b538SAndroid Build Coastguard Worker 'development, but is not safe to use on bots (' 430*6777b538SAndroid Build Coastguard Worker 'http://crbug.com/549214') 431*6777b538SAndroid Build Coastguard Worker parser.add_argument( 432*6777b538SAndroid Build Coastguard Worker '--gs-test-artifacts-bucket', 433*6777b538SAndroid Build Coastguard Worker help=('If present, test artifacts will be uploaded to this Google ' 434*6777b538SAndroid Build Coastguard Worker 'Storage bucket.')) 435*6777b538SAndroid Build Coastguard Worker parser.add_argument( 436*6777b538SAndroid Build Coastguard Worker '--render-test-output-dir', 437*6777b538SAndroid Build Coastguard Worker help='If present, store rendering artifacts in this path.') 438*6777b538SAndroid Build Coastguard Worker parser.add_argument( 439*6777b538SAndroid Build Coastguard Worker '--runtime-deps-path', 440*6777b538SAndroid Build Coastguard Worker dest='runtime_deps_path', type=os.path.realpath, 441*6777b538SAndroid Build Coastguard Worker help='Runtime data dependency file from GN.') 442*6777b538SAndroid Build Coastguard Worker parser.add_argument( 443*6777b538SAndroid Build Coastguard Worker '-t', '--shard-timeout', 444*6777b538SAndroid Build Coastguard Worker dest='shard_timeout', type=int, default=120, 445*6777b538SAndroid Build Coastguard Worker help='Timeout to wait for each test (default: %(default)s).') 446*6777b538SAndroid Build Coastguard Worker parser.add_argument( 447*6777b538SAndroid Build Coastguard Worker '--store-tombstones', 448*6777b538SAndroid Build Coastguard Worker dest='store_tombstones', action='store_true', 449*6777b538SAndroid Build Coastguard Worker help='Add tombstones in results if crash.') 450*6777b538SAndroid Build Coastguard Worker parser.add_argument( 451*6777b538SAndroid Build Coastguard Worker '-s', '--suite', 452*6777b538SAndroid Build Coastguard Worker dest='suite_name', nargs='+', metavar='SUITE_NAME', required=True, 453*6777b538SAndroid Build Coastguard Worker help='Executable name of the test suite to run.') 454*6777b538SAndroid Build Coastguard Worker parser.add_argument( 455*6777b538SAndroid Build Coastguard Worker '--test-apk-incremental-install-json', 456*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 457*6777b538SAndroid Build Coastguard Worker help='Path to install json for the test apk.') 458*6777b538SAndroid Build Coastguard Worker parser.add_argument('--test-launcher-batch-limit', 459*6777b538SAndroid Build Coastguard Worker dest='test_launcher_batch_limit', 460*6777b538SAndroid Build Coastguard Worker type=int, 461*6777b538SAndroid Build Coastguard Worker help='The max number of tests to run in a shard. ' 462*6777b538SAndroid Build Coastguard Worker 'Ignores non-positive ints and those greater than ' 463*6777b538SAndroid Build Coastguard Worker 'MAX_SHARDS') 464*6777b538SAndroid Build Coastguard Worker parser.add_argument( 465*6777b538SAndroid Build Coastguard Worker '-w', '--wait-for-java-debugger', action='store_true', 466*6777b538SAndroid Build Coastguard Worker help='Wait for java debugger to attach before running any application ' 467*6777b538SAndroid Build Coastguard Worker 'code. Also disables test timeouts and sets retries=0.') 468*6777b538SAndroid Build Coastguard Worker parser.add_argument( 469*6777b538SAndroid Build Coastguard Worker '--coverage-dir', 470*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 471*6777b538SAndroid Build Coastguard Worker help='Directory in which to place all generated coverage files.') 472*6777b538SAndroid Build Coastguard Worker parser.add_argument( 473*6777b538SAndroid Build Coastguard Worker '--use-existing-test-data', 474*6777b538SAndroid Build Coastguard Worker action='store_true', 475*6777b538SAndroid Build Coastguard Worker help='Do not push new files to the device, instead using existing APK ' 476*6777b538SAndroid Build Coastguard Worker 'and test data. Only use when running the same test for multiple ' 477*6777b538SAndroid Build Coastguard Worker 'iterations.') 478*6777b538SAndroid Build Coastguard Worker # This is currently only implemented for gtests tests. 479*6777b538SAndroid Build Coastguard Worker parser.add_argument('--gtest_also_run_pre_tests', 480*6777b538SAndroid Build Coastguard Worker '--gtest-also-run-pre-tests', 481*6777b538SAndroid Build Coastguard Worker dest='run_pre_tests', 482*6777b538SAndroid Build Coastguard Worker action='store_true', 483*6777b538SAndroid Build Coastguard Worker help='Also run PRE_ tests if applicable.') 484*6777b538SAndroid Build Coastguard Worker 485*6777b538SAndroid Build Coastguard Worker 486*6777b538SAndroid Build Coastguard Workerdef AddInstrumentationTestOptions(parser): 487*6777b538SAndroid Build Coastguard Worker """Adds Instrumentation test options to |parser|.""" 488*6777b538SAndroid Build Coastguard Worker 489*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('instrumentation arguments') 490*6777b538SAndroid Build Coastguard Worker 491*6777b538SAndroid Build Coastguard Worker parser.add_argument('--additional-apex', 492*6777b538SAndroid Build Coastguard Worker action='append', 493*6777b538SAndroid Build Coastguard Worker dest='additional_apexs', 494*6777b538SAndroid Build Coastguard Worker default=[], 495*6777b538SAndroid Build Coastguard Worker type=_RealPath, 496*6777b538SAndroid Build Coastguard Worker help='Additional apex that must be installed on ' 497*6777b538SAndroid Build Coastguard Worker 'the device when the tests are run') 498*6777b538SAndroid Build Coastguard Worker parser.add_argument( 499*6777b538SAndroid Build Coastguard Worker '--additional-apk', 500*6777b538SAndroid Build Coastguard Worker action='append', dest='additional_apks', default=[], 501*6777b538SAndroid Build Coastguard Worker type=_RealPath, 502*6777b538SAndroid Build Coastguard Worker help='Additional apk that must be installed on ' 503*6777b538SAndroid Build Coastguard Worker 'the device when the tests are run') 504*6777b538SAndroid Build Coastguard Worker parser.add_argument('--forced-queryable-additional-apk', 505*6777b538SAndroid Build Coastguard Worker action='append', 506*6777b538SAndroid Build Coastguard Worker dest='forced_queryable_additional_apks', 507*6777b538SAndroid Build Coastguard Worker default=[], 508*6777b538SAndroid Build Coastguard Worker type=_RealPath, 509*6777b538SAndroid Build Coastguard Worker help='Configures an additional-apk to be forced ' 510*6777b538SAndroid Build Coastguard Worker 'to be queryable by other APKs.') 511*6777b538SAndroid Build Coastguard Worker parser.add_argument('--instant-additional-apk', 512*6777b538SAndroid Build Coastguard Worker action='append', 513*6777b538SAndroid Build Coastguard Worker dest='instant_additional_apks', 514*6777b538SAndroid Build Coastguard Worker default=[], 515*6777b538SAndroid Build Coastguard Worker type=_RealPath, 516*6777b538SAndroid Build Coastguard Worker help='Configures an additional-apk to be an instant APK') 517*6777b538SAndroid Build Coastguard Worker parser.add_argument( 518*6777b538SAndroid Build Coastguard Worker '-A', '--annotation', 519*6777b538SAndroid Build Coastguard Worker dest='annotation_str', 520*6777b538SAndroid Build Coastguard Worker help='Comma-separated list of annotations. Run only tests with any of ' 521*6777b538SAndroid Build Coastguard Worker 'the given annotations. An annotation can be either a key or a ' 522*6777b538SAndroid Build Coastguard Worker 'key-values pair. A test that has no annotation is considered ' 523*6777b538SAndroid Build Coastguard Worker '"SmallTest".') 524*6777b538SAndroid Build Coastguard Worker # TODO(jbudorick): Remove support for name-style APK specification once 525*6777b538SAndroid Build Coastguard Worker # bots are no longer doing it. 526*6777b538SAndroid Build Coastguard Worker parser.add_argument( 527*6777b538SAndroid Build Coastguard Worker '--apk-under-test', 528*6777b538SAndroid Build Coastguard Worker help='Path or name of the apk under test.') 529*6777b538SAndroid Build Coastguard Worker parser.add_argument( 530*6777b538SAndroid Build Coastguard Worker '--store-data-dependencies-in-temp', 531*6777b538SAndroid Build Coastguard Worker action='store_true', 532*6777b538SAndroid Build Coastguard Worker help='Store data dependencies in /data/local/tmp/chromium_tests_root') 533*6777b538SAndroid Build Coastguard Worker parser.add_argument( 534*6777b538SAndroid Build Coastguard Worker '--module', 535*6777b538SAndroid Build Coastguard Worker action='append', 536*6777b538SAndroid Build Coastguard Worker dest='modules', 537*6777b538SAndroid Build Coastguard Worker help='Specify Android App Bundle modules to install in addition to the ' 538*6777b538SAndroid Build Coastguard Worker 'base module.') 539*6777b538SAndroid Build Coastguard Worker parser.add_argument( 540*6777b538SAndroid Build Coastguard Worker '--fake-module', 541*6777b538SAndroid Build Coastguard Worker action='append', 542*6777b538SAndroid Build Coastguard Worker dest='fake_modules', 543*6777b538SAndroid Build Coastguard Worker help='Specify Android App Bundle modules to fake install in addition to ' 544*6777b538SAndroid Build Coastguard Worker 'the real modules.') 545*6777b538SAndroid Build Coastguard Worker parser.add_argument( 546*6777b538SAndroid Build Coastguard Worker '--additional-locale', 547*6777b538SAndroid Build Coastguard Worker action='append', 548*6777b538SAndroid Build Coastguard Worker dest='additional_locales', 549*6777b538SAndroid Build Coastguard Worker help='Specify locales in addition to the device locale to install splits ' 550*6777b538SAndroid Build Coastguard Worker 'for when --apk-under-test is an Android App Bundle.') 551*6777b538SAndroid Build Coastguard Worker parser.add_argument( 552*6777b538SAndroid Build Coastguard Worker '--coverage-dir', 553*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 554*6777b538SAndroid Build Coastguard Worker help='Directory in which to place all generated ' 555*6777b538SAndroid Build Coastguard Worker 'Jacoco coverage files.') 556*6777b538SAndroid Build Coastguard Worker parser.add_argument( 557*6777b538SAndroid Build Coastguard Worker '--disable-dalvik-asserts', 558*6777b538SAndroid Build Coastguard Worker dest='set_asserts', action='store_false', default=True, 559*6777b538SAndroid Build Coastguard Worker help='Removes the dalvik.vm.enableassertions property') 560*6777b538SAndroid Build Coastguard Worker parser.add_argument( 561*6777b538SAndroid Build Coastguard Worker '--proguard-mapping-path', 562*6777b538SAndroid Build Coastguard Worker help='.mapping file to use to Deobfuscate java stack traces in test ' 563*6777b538SAndroid Build Coastguard Worker 'output and logcat.') 564*6777b538SAndroid Build Coastguard Worker parser.add_argument( 565*6777b538SAndroid Build Coastguard Worker '-E', '--exclude-annotation', 566*6777b538SAndroid Build Coastguard Worker dest='exclude_annotation_str', 567*6777b538SAndroid Build Coastguard Worker help='Comma-separated list of annotations. Exclude tests with these ' 568*6777b538SAndroid Build Coastguard Worker 'annotations.') 569*6777b538SAndroid Build Coastguard Worker parser.add_argument( 570*6777b538SAndroid Build Coastguard Worker '--enable-breakpad-dump', 571*6777b538SAndroid Build Coastguard Worker action='store_true', 572*6777b538SAndroid Build Coastguard Worker help='Stores any breakpad dumps till the end of the test.') 573*6777b538SAndroid Build Coastguard Worker parser.add_argument( 574*6777b538SAndroid Build Coastguard Worker '--replace-system-package', 575*6777b538SAndroid Build Coastguard Worker type=_RealPath, 576*6777b538SAndroid Build Coastguard Worker default=None, 577*6777b538SAndroid Build Coastguard Worker help='Use this apk to temporarily replace a system package with the same ' 578*6777b538SAndroid Build Coastguard Worker 'package name.') 579*6777b538SAndroid Build Coastguard Worker parser.add_argument( 580*6777b538SAndroid Build Coastguard Worker '--remove-system-package', 581*6777b538SAndroid Build Coastguard Worker default=[], 582*6777b538SAndroid Build Coastguard Worker action='append', 583*6777b538SAndroid Build Coastguard Worker dest='system_packages_to_remove', 584*6777b538SAndroid Build Coastguard Worker help='Specifies a system package to remove before testing if it exists ' 585*6777b538SAndroid Build Coastguard Worker 'on the system. WARNING: THIS WILL PERMANENTLY REMOVE THE SYSTEM APP. ' 586*6777b538SAndroid Build Coastguard Worker 'Unlike --replace-system-package, the app will not be restored after ' 587*6777b538SAndroid Build Coastguard Worker 'tests are finished.') 588*6777b538SAndroid Build Coastguard Worker parser.add_argument( 589*6777b538SAndroid Build Coastguard Worker '--use-voice-interaction-service', 590*6777b538SAndroid Build Coastguard Worker help='This can be used to update the voice interaction service to be a ' 591*6777b538SAndroid Build Coastguard Worker 'custom one. This is useful for mocking assistants. eg: ' 592*6777b538SAndroid Build Coastguard Worker 'android.assist.service/.MainInteractionService') 593*6777b538SAndroid Build Coastguard Worker parser.add_argument( 594*6777b538SAndroid Build Coastguard Worker '--use-webview-provider', 595*6777b538SAndroid Build Coastguard Worker type=_RealPath, default=None, 596*6777b538SAndroid Build Coastguard Worker help='Use this apk as the webview provider during test. ' 597*6777b538SAndroid Build Coastguard Worker 'The original provider will be restored if possible, ' 598*6777b538SAndroid Build Coastguard Worker "on Nougat the provider can't be determined and so " 599*6777b538SAndroid Build Coastguard Worker 'the system will choose the default provider.') 600*6777b538SAndroid Build Coastguard Worker parser.add_argument( 601*6777b538SAndroid Build Coastguard Worker '--webview-command-line-arg', 602*6777b538SAndroid Build Coastguard Worker default=[], 603*6777b538SAndroid Build Coastguard Worker action='append', 604*6777b538SAndroid Build Coastguard Worker help="Specifies command line arguments to add to WebView's flag file") 605*6777b538SAndroid Build Coastguard Worker parser.add_argument( 606*6777b538SAndroid Build Coastguard Worker '--run-setup-command', 607*6777b538SAndroid Build Coastguard Worker default=[], 608*6777b538SAndroid Build Coastguard Worker action='append', 609*6777b538SAndroid Build Coastguard Worker dest='run_setup_commands', 610*6777b538SAndroid Build Coastguard Worker help='This can be used to run a custom shell command on the device as a ' 611*6777b538SAndroid Build Coastguard Worker 'setup step') 612*6777b538SAndroid Build Coastguard Worker parser.add_argument( 613*6777b538SAndroid Build Coastguard Worker '--run-teardown-command', 614*6777b538SAndroid Build Coastguard Worker default=[], 615*6777b538SAndroid Build Coastguard Worker action='append', 616*6777b538SAndroid Build Coastguard Worker dest='run_teardown_commands', 617*6777b538SAndroid Build Coastguard Worker help='This can be used to run a custom shell command on the device as a ' 618*6777b538SAndroid Build Coastguard Worker 'teardown step') 619*6777b538SAndroid Build Coastguard Worker parser.add_argument( 620*6777b538SAndroid Build Coastguard Worker '--runtime-deps-path', 621*6777b538SAndroid Build Coastguard Worker dest='runtime_deps_path', type=os.path.realpath, 622*6777b538SAndroid Build Coastguard Worker help='Runtime data dependency file from GN.') 623*6777b538SAndroid Build Coastguard Worker parser.add_argument( 624*6777b538SAndroid Build Coastguard Worker '--screenshot-directory', 625*6777b538SAndroid Build Coastguard Worker dest='screenshot_dir', type=os.path.realpath, 626*6777b538SAndroid Build Coastguard Worker help='Capture screenshots of test failures') 627*6777b538SAndroid Build Coastguard Worker parser.add_argument( 628*6777b538SAndroid Build Coastguard Worker '--store-tombstones', 629*6777b538SAndroid Build Coastguard Worker action='store_true', dest='store_tombstones', 630*6777b538SAndroid Build Coastguard Worker help='Add tombstones in results if crash.') 631*6777b538SAndroid Build Coastguard Worker parser.add_argument( 632*6777b538SAndroid Build Coastguard Worker '--strict-mode', 633*6777b538SAndroid Build Coastguard Worker dest='strict_mode', default='testing', 634*6777b538SAndroid Build Coastguard Worker help='StrictMode command-line flag set on the device, ' 635*6777b538SAndroid Build Coastguard Worker 'death/testing to kill the process, off to stop ' 636*6777b538SAndroid Build Coastguard Worker 'checking, flash to flash only. (default: %(default)s)') 637*6777b538SAndroid Build Coastguard Worker parser.add_argument( 638*6777b538SAndroid Build Coastguard Worker '--test-apk', 639*6777b538SAndroid Build Coastguard Worker required=True, 640*6777b538SAndroid Build Coastguard Worker help='Path or name of the apk containing the tests.') 641*6777b538SAndroid Build Coastguard Worker parser.add_argument( 642*6777b538SAndroid Build Coastguard Worker '--test-apk-as-instant', 643*6777b538SAndroid Build Coastguard Worker action='store_true', 644*6777b538SAndroid Build Coastguard Worker help='Install the test apk as an instant app. ' 645*6777b538SAndroid Build Coastguard Worker 'Instant apps run in a more restrictive execution environment.') 646*6777b538SAndroid Build Coastguard Worker parser.add_argument( 647*6777b538SAndroid Build Coastguard Worker '--test-launcher-batch-limit', 648*6777b538SAndroid Build Coastguard Worker dest='test_launcher_batch_limit', 649*6777b538SAndroid Build Coastguard Worker type=int, 650*6777b538SAndroid Build Coastguard Worker help=('Not actually used for instrumentation tests, but can be used as ' 651*6777b538SAndroid Build Coastguard Worker 'a proxy for determining if the current run is a retry without ' 652*6777b538SAndroid Build Coastguard Worker 'patch.')) 653*6777b538SAndroid Build Coastguard Worker parser.add_argument( 654*6777b538SAndroid Build Coastguard Worker '--timeout-scale', 655*6777b538SAndroid Build Coastguard Worker type=float, 656*6777b538SAndroid Build Coastguard Worker help='Factor by which timeouts should be scaled.') 657*6777b538SAndroid Build Coastguard Worker parser.add_argument( 658*6777b538SAndroid Build Coastguard Worker '--is-unit-test', 659*6777b538SAndroid Build Coastguard Worker action='store_true', 660*6777b538SAndroid Build Coastguard Worker help=('Specify the test suite as composed of unit tests, blocking ' 661*6777b538SAndroid Build Coastguard Worker 'certain operations.')) 662*6777b538SAndroid Build Coastguard Worker parser.add_argument( 663*6777b538SAndroid Build Coastguard Worker '-w', '--wait-for-java-debugger', action='store_true', 664*6777b538SAndroid Build Coastguard Worker help='Wait for java debugger to attach before running any application ' 665*6777b538SAndroid Build Coastguard Worker 'code. Also disables test timeouts and sets retries=0.') 666*6777b538SAndroid Build Coastguard Worker 667*6777b538SAndroid Build Coastguard Worker # WPR record mode. 668*6777b538SAndroid Build Coastguard Worker parser.add_argument('--wpr-enable-record', 669*6777b538SAndroid Build Coastguard Worker action='store_true', 670*6777b538SAndroid Build Coastguard Worker default=False, 671*6777b538SAndroid Build Coastguard Worker help='If true, WPR server runs in record mode.' 672*6777b538SAndroid Build Coastguard Worker 'otherwise, runs in replay mode.') 673*6777b538SAndroid Build Coastguard Worker 674*6777b538SAndroid Build Coastguard Worker parser.add_argument( 675*6777b538SAndroid Build Coastguard Worker '--approve-app-links', 676*6777b538SAndroid Build Coastguard Worker help='Force enables Digital Asset Link verification for the provided ' 677*6777b538SAndroid Build Coastguard Worker 'package and domain, example usage: --approve-app-links ' 678*6777b538SAndroid Build Coastguard Worker 'com.android.package:www.example.com') 679*6777b538SAndroid Build Coastguard Worker 680*6777b538SAndroid Build Coastguard Worker # These arguments are suppressed from the help text because they should 681*6777b538SAndroid Build Coastguard Worker # only ever be specified by an intermediate script. 682*6777b538SAndroid Build Coastguard Worker parser.add_argument( 683*6777b538SAndroid Build Coastguard Worker '--apk-under-test-incremental-install-json', 684*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 685*6777b538SAndroid Build Coastguard Worker parser.add_argument( 686*6777b538SAndroid Build Coastguard Worker '--test-apk-incremental-install-json', 687*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 688*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 689*6777b538SAndroid Build Coastguard Worker 690*6777b538SAndroid Build Coastguard Worker 691*6777b538SAndroid Build Coastguard Workerdef AddSkiaGoldTestOptions(parser): 692*6777b538SAndroid Build Coastguard Worker """Adds Skia Gold test options to |parser|.""" 693*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group("Skia Gold arguments") 694*6777b538SAndroid Build Coastguard Worker parser.add_argument( 695*6777b538SAndroid Build Coastguard Worker '--code-review-system', 696*6777b538SAndroid Build Coastguard Worker help='A non-default code review system to pass to pass to Gold, if ' 697*6777b538SAndroid Build Coastguard Worker 'applicable') 698*6777b538SAndroid Build Coastguard Worker parser.add_argument( 699*6777b538SAndroid Build Coastguard Worker '--continuous-integration-system', 700*6777b538SAndroid Build Coastguard Worker help='A non-default continuous integration system to pass to Gold, if ' 701*6777b538SAndroid Build Coastguard Worker 'applicable') 702*6777b538SAndroid Build Coastguard Worker parser.add_argument( 703*6777b538SAndroid Build Coastguard Worker '--git-revision', help='The git commit currently being tested.') 704*6777b538SAndroid Build Coastguard Worker parser.add_argument( 705*6777b538SAndroid Build Coastguard Worker '--gerrit-issue', 706*6777b538SAndroid Build Coastguard Worker help='The Gerrit issue this test is being run on, if applicable.') 707*6777b538SAndroid Build Coastguard Worker parser.add_argument( 708*6777b538SAndroid Build Coastguard Worker '--gerrit-patchset', 709*6777b538SAndroid Build Coastguard Worker help='The Gerrit patchset this test is being run on, if applicable.') 710*6777b538SAndroid Build Coastguard Worker parser.add_argument( 711*6777b538SAndroid Build Coastguard Worker '--buildbucket-id', 712*6777b538SAndroid Build Coastguard Worker help='The Buildbucket build ID that this test was triggered from, if ' 713*6777b538SAndroid Build Coastguard Worker 'applicable.') 714*6777b538SAndroid Build Coastguard Worker local_group = parser.add_mutually_exclusive_group() 715*6777b538SAndroid Build Coastguard Worker local_group.add_argument( 716*6777b538SAndroid Build Coastguard Worker '--local-pixel-tests', 717*6777b538SAndroid Build Coastguard Worker action='store_true', 718*6777b538SAndroid Build Coastguard Worker default=None, 719*6777b538SAndroid Build Coastguard Worker help='Specifies to run the Skia Gold pixel tests in local mode. When run ' 720*6777b538SAndroid Build Coastguard Worker 'in local mode, uploading to Gold is disabled and traditional ' 721*6777b538SAndroid Build Coastguard Worker 'generated/golden/diff images are output instead of triage links. ' 722*6777b538SAndroid Build Coastguard Worker 'Running in local mode also implies --no-luci-auth. If both this ' 723*6777b538SAndroid Build Coastguard Worker 'and --no-local-pixel-tests are left unset, the test harness will ' 724*6777b538SAndroid Build Coastguard Worker 'attempt to detect whether it is running on a workstation or not ' 725*6777b538SAndroid Build Coastguard Worker 'and set the options accordingly.') 726*6777b538SAndroid Build Coastguard Worker local_group.add_argument( 727*6777b538SAndroid Build Coastguard Worker '--no-local-pixel-tests', 728*6777b538SAndroid Build Coastguard Worker action='store_false', 729*6777b538SAndroid Build Coastguard Worker dest='local_pixel_tests', 730*6777b538SAndroid Build Coastguard Worker help='Specifies to run the Skia Gold pixel tests in non-local (bot) ' 731*6777b538SAndroid Build Coastguard Worker 'mode. When run in this mode, data is actually uploaded to Gold and ' 732*6777b538SAndroid Build Coastguard Worker 'triage links are generated. If both this and --local-pixel-tests ' 733*6777b538SAndroid Build Coastguard Worker 'are left unset, the test harness will attempt to detect whether ' 734*6777b538SAndroid Build Coastguard Worker 'it is running on a workstation or not and set the options ' 735*6777b538SAndroid Build Coastguard Worker 'accordingly.') 736*6777b538SAndroid Build Coastguard Worker parser.add_argument( 737*6777b538SAndroid Build Coastguard Worker '--no-luci-auth', 738*6777b538SAndroid Build Coastguard Worker action='store_true', 739*6777b538SAndroid Build Coastguard Worker default=False, 740*6777b538SAndroid Build Coastguard Worker help="Don't use the serve account provided by LUCI for authentication " 741*6777b538SAndroid Build Coastguard Worker 'with Skia Gold, instead relying on gsutil to be pre-authenticated. ' 742*6777b538SAndroid Build Coastguard Worker 'Meant for testing locally instead of on the bots.') 743*6777b538SAndroid Build Coastguard Worker parser.add_argument( 744*6777b538SAndroid Build Coastguard Worker '--bypass-skia-gold-functionality', 745*6777b538SAndroid Build Coastguard Worker action='store_true', 746*6777b538SAndroid Build Coastguard Worker default=False, 747*6777b538SAndroid Build Coastguard Worker help='Bypass all interaction with Skia Gold, effectively disabling the ' 748*6777b538SAndroid Build Coastguard Worker 'image comparison portion of any tests that use Gold. Only meant to be ' 749*6777b538SAndroid Build Coastguard Worker 'used in case a Gold outage occurs and cannot be fixed quickly.') 750*6777b538SAndroid Build Coastguard Worker 751*6777b538SAndroid Build Coastguard Worker 752*6777b538SAndroid Build Coastguard Workerdef AddHostsideTestOptions(parser): 753*6777b538SAndroid Build Coastguard Worker """Adds hostside test options to |parser|.""" 754*6777b538SAndroid Build Coastguard Worker 755*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('hostside arguments') 756*6777b538SAndroid Build Coastguard Worker 757*6777b538SAndroid Build Coastguard Worker parser.add_argument( 758*6777b538SAndroid Build Coastguard Worker '-s', '--test-suite', required=True, 759*6777b538SAndroid Build Coastguard Worker help='Hostside test suite to run.') 760*6777b538SAndroid Build Coastguard Worker parser.add_argument( 761*6777b538SAndroid Build Coastguard Worker '--test-apk-as-instant', 762*6777b538SAndroid Build Coastguard Worker action='store_true', 763*6777b538SAndroid Build Coastguard Worker help='Install the test apk as an instant app. ' 764*6777b538SAndroid Build Coastguard Worker 'Instant apps run in a more restrictive execution environment.') 765*6777b538SAndroid Build Coastguard Worker parser.add_argument( 766*6777b538SAndroid Build Coastguard Worker '--additional-apk', 767*6777b538SAndroid Build Coastguard Worker action='append', 768*6777b538SAndroid Build Coastguard Worker dest='additional_apks', 769*6777b538SAndroid Build Coastguard Worker default=[], 770*6777b538SAndroid Build Coastguard Worker type=_RealPath, 771*6777b538SAndroid Build Coastguard Worker help='Additional apk that must be installed on ' 772*6777b538SAndroid Build Coastguard Worker 'the device when the tests are run') 773*6777b538SAndroid Build Coastguard Worker parser.add_argument( 774*6777b538SAndroid Build Coastguard Worker '--use-webview-provider', 775*6777b538SAndroid Build Coastguard Worker type=_RealPath, default=None, 776*6777b538SAndroid Build Coastguard Worker help='Use this apk as the webview provider during test. ' 777*6777b538SAndroid Build Coastguard Worker 'The original provider will be restored if possible, ' 778*6777b538SAndroid Build Coastguard Worker "on Nougat the provider can't be determined and so " 779*6777b538SAndroid Build Coastguard Worker 'the system will choose the default provider.') 780*6777b538SAndroid Build Coastguard Worker parser.add_argument( 781*6777b538SAndroid Build Coastguard Worker '--tradefed-executable', 782*6777b538SAndroid Build Coastguard Worker type=_RealPath, default=None, 783*6777b538SAndroid Build Coastguard Worker help='Location of the cts-tradefed script') 784*6777b538SAndroid Build Coastguard Worker parser.add_argument( 785*6777b538SAndroid Build Coastguard Worker '--tradefed-aapt-path', 786*6777b538SAndroid Build Coastguard Worker type=_RealPath, default=None, 787*6777b538SAndroid Build Coastguard Worker help='Location of the directory containing aapt binary') 788*6777b538SAndroid Build Coastguard Worker parser.add_argument( 789*6777b538SAndroid Build Coastguard Worker '--tradefed-adb-path', 790*6777b538SAndroid Build Coastguard Worker type=_RealPath, default=None, 791*6777b538SAndroid Build Coastguard Worker help='Location of the directory containing adb binary') 792*6777b538SAndroid Build Coastguard Worker # The below arguments are not used, but allow us to pass the same arguments 793*6777b538SAndroid Build Coastguard Worker # from run_cts.py regardless of type of run (instrumentation/hostside) 794*6777b538SAndroid Build Coastguard Worker parser.add_argument( 795*6777b538SAndroid Build Coastguard Worker '--apk-under-test', 796*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 797*6777b538SAndroid Build Coastguard Worker parser.add_argument( 798*6777b538SAndroid Build Coastguard Worker '--use-apk-under-test-flags-file', 799*6777b538SAndroid Build Coastguard Worker action='store_true', 800*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 801*6777b538SAndroid Build Coastguard Worker parser.add_argument( 802*6777b538SAndroid Build Coastguard Worker '-E', '--exclude-annotation', 803*6777b538SAndroid Build Coastguard Worker dest='exclude_annotation_str', 804*6777b538SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 805*6777b538SAndroid Build Coastguard Worker 806*6777b538SAndroid Build Coastguard Worker 807*6777b538SAndroid Build Coastguard Workerdef AddJUnitTestOptions(parser): 808*6777b538SAndroid Build Coastguard Worker """Adds junit test options to |parser|.""" 809*6777b538SAndroid Build Coastguard Worker 810*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('junit arguments') 811*6777b538SAndroid Build Coastguard Worker 812*6777b538SAndroid Build Coastguard Worker parser.add_argument( 813*6777b538SAndroid Build Coastguard Worker '--coverage-on-the-fly', 814*6777b538SAndroid Build Coastguard Worker action='store_true', 815*6777b538SAndroid Build Coastguard Worker help='Generate coverage data by Jacoco on-the-fly instrumentation.') 816*6777b538SAndroid Build Coastguard Worker parser.add_argument( 817*6777b538SAndroid Build Coastguard Worker '--coverage-dir', type=os.path.realpath, 818*6777b538SAndroid Build Coastguard Worker help='Directory to store coverage info.') 819*6777b538SAndroid Build Coastguard Worker parser.add_argument( 820*6777b538SAndroid Build Coastguard Worker '--package-filter', 821*6777b538SAndroid Build Coastguard Worker help='Filters tests by package.') 822*6777b538SAndroid Build Coastguard Worker parser.add_argument( 823*6777b538SAndroid Build Coastguard Worker '--runner-filter', 824*6777b538SAndroid Build Coastguard Worker help='Filters tests by runner class. Must be fully qualified.') 825*6777b538SAndroid Build Coastguard Worker parser.add_argument('--json-config', 826*6777b538SAndroid Build Coastguard Worker help='Runs only tests listed in this config.') 827*6777b538SAndroid Build Coastguard Worker parser.add_argument( 828*6777b538SAndroid Build Coastguard Worker '--shards', 829*6777b538SAndroid Build Coastguard Worker type=int, 830*6777b538SAndroid Build Coastguard Worker help='Number of shards to run junit tests in parallel on. Only 1 shard ' 831*6777b538SAndroid Build Coastguard Worker 'is supported when test-filter is specified. Values less than 1 will ' 832*6777b538SAndroid Build Coastguard Worker 'use auto select.') 833*6777b538SAndroid Build Coastguard Worker parser.add_argument('--shard-filter', 834*6777b538SAndroid Build Coastguard Worker help='Comma separated list of shard indices to run.') 835*6777b538SAndroid Build Coastguard Worker parser.add_argument( 836*6777b538SAndroid Build Coastguard Worker '-s', '--test-suite', required=True, 837*6777b538SAndroid Build Coastguard Worker help='JUnit test suite to run.') 838*6777b538SAndroid Build Coastguard Worker debug_group = parser.add_mutually_exclusive_group() 839*6777b538SAndroid Build Coastguard Worker debug_group.add_argument( 840*6777b538SAndroid Build Coastguard Worker '-w', '--wait-for-java-debugger', action='store_const', const='8701', 841*6777b538SAndroid Build Coastguard Worker dest='debug_socket', help='Alias for --debug-socket=8701') 842*6777b538SAndroid Build Coastguard Worker debug_group.add_argument( 843*6777b538SAndroid Build Coastguard Worker '--debug-socket', 844*6777b538SAndroid Build Coastguard Worker help='Wait for java debugger to attach at specified socket address ' 845*6777b538SAndroid Build Coastguard Worker 'before running any application code. Also disables test timeouts ' 846*6777b538SAndroid Build Coastguard Worker 'and sets retries=0.') 847*6777b538SAndroid Build Coastguard Worker 848*6777b538SAndroid Build Coastguard Worker # These arguments are for Android Robolectric tests. 849*6777b538SAndroid Build Coastguard Worker parser.add_argument( 850*6777b538SAndroid Build Coastguard Worker '--robolectric-runtime-deps-dir', 851*6777b538SAndroid Build Coastguard Worker help='Path to runtime deps for Robolectric.') 852*6777b538SAndroid Build Coastguard Worker parser.add_argument('--native-libs-dir', 853*6777b538SAndroid Build Coastguard Worker help='Path to search for native libraries.') 854*6777b538SAndroid Build Coastguard Worker parser.add_argument( 855*6777b538SAndroid Build Coastguard Worker '--resource-apk', 856*6777b538SAndroid Build Coastguard Worker required=True, 857*6777b538SAndroid Build Coastguard Worker help='Path to .ap_ containing binary resources for Robolectric.') 858*6777b538SAndroid Build Coastguard Worker 859*6777b538SAndroid Build Coastguard Worker 860*6777b538SAndroid Build Coastguard Workerdef AddLinkerTestOptions(parser): 861*6777b538SAndroid Build Coastguard Worker 862*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('linker arguments') 863*6777b538SAndroid Build Coastguard Worker 864*6777b538SAndroid Build Coastguard Worker parser.add_argument( 865*6777b538SAndroid Build Coastguard Worker '--test-apk', 866*6777b538SAndroid Build Coastguard Worker type=os.path.realpath, 867*6777b538SAndroid Build Coastguard Worker help='Path to the linker test APK.') 868*6777b538SAndroid Build Coastguard Worker 869*6777b538SAndroid Build Coastguard Worker 870*6777b538SAndroid Build Coastguard Workerdef AddMonkeyTestOptions(parser): 871*6777b538SAndroid Build Coastguard Worker """Adds monkey test options to |parser|.""" 872*6777b538SAndroid Build Coastguard Worker 873*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('monkey arguments') 874*6777b538SAndroid Build Coastguard Worker 875*6777b538SAndroid Build Coastguard Worker parser.add_argument('--browser', 876*6777b538SAndroid Build Coastguard Worker required=True, 877*6777b538SAndroid Build Coastguard Worker choices=list(constants.PACKAGE_INFO.keys()), 878*6777b538SAndroid Build Coastguard Worker metavar='BROWSER', 879*6777b538SAndroid Build Coastguard Worker help='Browser under test.') 880*6777b538SAndroid Build Coastguard Worker parser.add_argument( 881*6777b538SAndroid Build Coastguard Worker '--category', 882*6777b538SAndroid Build Coastguard Worker nargs='*', dest='categories', default=[], 883*6777b538SAndroid Build Coastguard Worker help='A list of allowed categories. Monkey will only visit activities ' 884*6777b538SAndroid Build Coastguard Worker 'that are listed with one of the specified categories.') 885*6777b538SAndroid Build Coastguard Worker parser.add_argument( 886*6777b538SAndroid Build Coastguard Worker '--event-count', 887*6777b538SAndroid Build Coastguard Worker default=10000, type=int, 888*6777b538SAndroid Build Coastguard Worker help='Number of events to generate (default: %(default)s).') 889*6777b538SAndroid Build Coastguard Worker parser.add_argument( 890*6777b538SAndroid Build Coastguard Worker '--seed', 891*6777b538SAndroid Build Coastguard Worker type=int, 892*6777b538SAndroid Build Coastguard Worker help='Seed value for pseudo-random generator. Same seed value generates ' 893*6777b538SAndroid Build Coastguard Worker 'the same sequence of events. Seed is randomized by default.') 894*6777b538SAndroid Build Coastguard Worker parser.add_argument( 895*6777b538SAndroid Build Coastguard Worker '--throttle', 896*6777b538SAndroid Build Coastguard Worker default=100, type=int, 897*6777b538SAndroid Build Coastguard Worker help='Delay between events (ms) (default: %(default)s). ') 898*6777b538SAndroid Build Coastguard Worker 899*6777b538SAndroid Build Coastguard Worker 900*6777b538SAndroid Build Coastguard Workerdef AddPythonTestOptions(parser): 901*6777b538SAndroid Build Coastguard Worker 902*6777b538SAndroid Build Coastguard Worker parser = parser.add_argument_group('python arguments') 903*6777b538SAndroid Build Coastguard Worker 904*6777b538SAndroid Build Coastguard Worker parser.add_argument('-s', 905*6777b538SAndroid Build Coastguard Worker '--suite', 906*6777b538SAndroid Build Coastguard Worker dest='suite_name', 907*6777b538SAndroid Build Coastguard Worker metavar='SUITE_NAME', 908*6777b538SAndroid Build Coastguard Worker choices=list(constants.PYTHON_UNIT_TEST_SUITES.keys()), 909*6777b538SAndroid Build Coastguard Worker help='Name of the test suite to run.') 910*6777b538SAndroid Build Coastguard Worker 911*6777b538SAndroid Build Coastguard Worker 912*6777b538SAndroid Build Coastguard Workerdef _CreateClassToFileNameDict(test_apk): 913*6777b538SAndroid Build Coastguard Worker """Creates a dict mapping classes to file names from size-info apk.""" 914*6777b538SAndroid Build Coastguard Worker constants.CheckOutputDirectory() 915*6777b538SAndroid Build Coastguard Worker test_apk_size_info = os.path.join(constants.GetOutDirectory(), 'size-info', 916*6777b538SAndroid Build Coastguard Worker os.path.basename(test_apk) + '.jar.info') 917*6777b538SAndroid Build Coastguard Worker 918*6777b538SAndroid Build Coastguard Worker class_to_file_dict = {} 919*6777b538SAndroid Build Coastguard Worker # Some tests such as webview_cts_tests use a separately downloaded apk to run 920*6777b538SAndroid Build Coastguard Worker # tests. This means the apk may not have been built by the system and hence 921*6777b538SAndroid Build Coastguard Worker # no size info file exists. 922*6777b538SAndroid Build Coastguard Worker if not os.path.exists(test_apk_size_info): 923*6777b538SAndroid Build Coastguard Worker logging.debug('Apk size file not found. %s', test_apk_size_info) 924*6777b538SAndroid Build Coastguard Worker return class_to_file_dict 925*6777b538SAndroid Build Coastguard Worker 926*6777b538SAndroid Build Coastguard Worker with open(test_apk_size_info, 'r') as f: 927*6777b538SAndroid Build Coastguard Worker for line in f: 928*6777b538SAndroid Build Coastguard Worker file_class, file_name = line.rstrip().split(',', 1) 929*6777b538SAndroid Build Coastguard Worker # Only want files that are not prebuilt. 930*6777b538SAndroid Build Coastguard Worker if file_name.startswith('../../'): 931*6777b538SAndroid Build Coastguard Worker class_to_file_dict[file_class] = str( 932*6777b538SAndroid Build Coastguard Worker file_name.replace('../../', '//', 1)) 933*6777b538SAndroid Build Coastguard Worker 934*6777b538SAndroid Build Coastguard Worker return class_to_file_dict 935*6777b538SAndroid Build Coastguard Worker 936*6777b538SAndroid Build Coastguard Worker 937*6777b538SAndroid Build Coastguard Workerdef _RunPythonTests(args): 938*6777b538SAndroid Build Coastguard Worker """Subcommand of RunTestsCommand which runs python unit tests.""" 939*6777b538SAndroid Build Coastguard Worker suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name] 940*6777b538SAndroid Build Coastguard Worker suite_path = suite_vars['path'] 941*6777b538SAndroid Build Coastguard Worker suite_test_modules = suite_vars['test_modules'] 942*6777b538SAndroid Build Coastguard Worker 943*6777b538SAndroid Build Coastguard Worker sys.path = [suite_path] + sys.path 944*6777b538SAndroid Build Coastguard Worker try: 945*6777b538SAndroid Build Coastguard Worker suite = unittest.TestSuite() 946*6777b538SAndroid Build Coastguard Worker suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m) 947*6777b538SAndroid Build Coastguard Worker for m in suite_test_modules) 948*6777b538SAndroid Build Coastguard Worker runner = unittest.TextTestRunner(verbosity=1+args.verbose_count) 949*6777b538SAndroid Build Coastguard Worker return 0 if runner.run(suite).wasSuccessful() else 1 950*6777b538SAndroid Build Coastguard Worker finally: 951*6777b538SAndroid Build Coastguard Worker sys.path = sys.path[1:] 952*6777b538SAndroid Build Coastguard Worker 953*6777b538SAndroid Build Coastguard Worker 954*6777b538SAndroid Build Coastguard Worker_DEFAULT_PLATFORM_MODE_TESTS = [ 955*6777b538SAndroid Build Coastguard Worker 'gtest', 'hostside', 'instrumentation', 'junit', 'linker', 'monkey' 956*6777b538SAndroid Build Coastguard Worker] 957*6777b538SAndroid Build Coastguard Worker 958*6777b538SAndroid Build Coastguard Worker 959*6777b538SAndroid Build Coastguard Workerdef RunTestsCommand(args, result_sink_client=None): 960*6777b538SAndroid Build Coastguard Worker """Checks test type and dispatches to the appropriate function. 961*6777b538SAndroid Build Coastguard Worker 962*6777b538SAndroid Build Coastguard Worker Args: 963*6777b538SAndroid Build Coastguard Worker args: argparse.Namespace object. 964*6777b538SAndroid Build Coastguard Worker result_sink_client: A ResultSinkClient object. 965*6777b538SAndroid Build Coastguard Worker 966*6777b538SAndroid Build Coastguard Worker Returns: 967*6777b538SAndroid Build Coastguard Worker Integer indicated exit code. 968*6777b538SAndroid Build Coastguard Worker 969*6777b538SAndroid Build Coastguard Worker Raises: 970*6777b538SAndroid Build Coastguard Worker Exception: Unknown command name passed in, or an exception from an 971*6777b538SAndroid Build Coastguard Worker individual test runner. 972*6777b538SAndroid Build Coastguard Worker """ 973*6777b538SAndroid Build Coastguard Worker command = args.command 974*6777b538SAndroid Build Coastguard Worker 975*6777b538SAndroid Build Coastguard Worker ProcessCommonOptions(args) 976*6777b538SAndroid Build Coastguard Worker logging.info('command: %s', ' '.join(sys.argv)) 977*6777b538SAndroid Build Coastguard Worker if args.enable_platform_mode or command in _DEFAULT_PLATFORM_MODE_TESTS: 978*6777b538SAndroid Build Coastguard Worker return RunTestsInPlatformMode(args, result_sink_client) 979*6777b538SAndroid Build Coastguard Worker 980*6777b538SAndroid Build Coastguard Worker if command == 'python': 981*6777b538SAndroid Build Coastguard Worker return _RunPythonTests(args) 982*6777b538SAndroid Build Coastguard Worker raise Exception('Unknown test type.') 983*6777b538SAndroid Build Coastguard Worker 984*6777b538SAndroid Build Coastguard Worker 985*6777b538SAndroid Build Coastguard Workerdef _SinkTestResult(test_result, test_file_name, result_sink_client): 986*6777b538SAndroid Build Coastguard Worker """Upload test result to result_sink. 987*6777b538SAndroid Build Coastguard Worker 988*6777b538SAndroid Build Coastguard Worker Args: 989*6777b538SAndroid Build Coastguard Worker test_result: A BaseTestResult object 990*6777b538SAndroid Build Coastguard Worker test_file_name: A string representing the file location of the test 991*6777b538SAndroid Build Coastguard Worker result_sink_client: A ResultSinkClient object 992*6777b538SAndroid Build Coastguard Worker 993*6777b538SAndroid Build Coastguard Worker Returns: 994*6777b538SAndroid Build Coastguard Worker N/A 995*6777b538SAndroid Build Coastguard Worker """ 996*6777b538SAndroid Build Coastguard Worker # Some tests put in non utf-8 char as part of the test 997*6777b538SAndroid Build Coastguard Worker # which breaks uploads, so need to decode and re-encode. 998*6777b538SAndroid Build Coastguard Worker log_decoded = test_result.GetLog() 999*6777b538SAndroid Build Coastguard Worker if isinstance(log_decoded, bytes): 1000*6777b538SAndroid Build Coastguard Worker log_decoded = log_decoded.decode('utf-8', 'replace') 1001*6777b538SAndroid Build Coastguard Worker html_artifact = '' 1002*6777b538SAndroid Build Coastguard Worker https_artifacts = [] 1003*6777b538SAndroid Build Coastguard Worker for link_name, link_url in sorted(test_result.GetLinks().items()): 1004*6777b538SAndroid Build Coastguard Worker if link_url.startswith('https:'): 1005*6777b538SAndroid Build Coastguard Worker https_artifacts.append('<li><a target="_blank" href=%s>%s</a></li>' % 1006*6777b538SAndroid Build Coastguard Worker (link_url, link_name)) 1007*6777b538SAndroid Build Coastguard Worker else: 1008*6777b538SAndroid Build Coastguard Worker logging.info('Skipping non-https link %r (%s) for test %s.', link_name, 1009*6777b538SAndroid Build Coastguard Worker link_url, test_result.GetName()) 1010*6777b538SAndroid Build Coastguard Worker if https_artifacts: 1011*6777b538SAndroid Build Coastguard Worker html_artifact += '<ul>%s</ul>' % '\n'.join(https_artifacts) 1012*6777b538SAndroid Build Coastguard Worker result_sink_client.Post(test_result.GetNameForResultSink(), 1013*6777b538SAndroid Build Coastguard Worker test_result.GetType(), 1014*6777b538SAndroid Build Coastguard Worker test_result.GetDuration(), 1015*6777b538SAndroid Build Coastguard Worker log_decoded, 1016*6777b538SAndroid Build Coastguard Worker test_file_name, 1017*6777b538SAndroid Build Coastguard Worker variant=test_result.GetVariantForResultSink(), 1018*6777b538SAndroid Build Coastguard Worker failure_reason=test_result.GetFailureReason(), 1019*6777b538SAndroid Build Coastguard Worker html_artifact=html_artifact) 1020*6777b538SAndroid Build Coastguard Worker 1021*6777b538SAndroid Build Coastguard Worker 1022*6777b538SAndroid Build Coastguard Worker_SUPPORTED_IN_PLATFORM_MODE = [ 1023*6777b538SAndroid Build Coastguard Worker # TODO(jbudorick): Add support for more test types. 1024*6777b538SAndroid Build Coastguard Worker 'gtest', 1025*6777b538SAndroid Build Coastguard Worker 'hostside', 1026*6777b538SAndroid Build Coastguard Worker 'instrumentation', 1027*6777b538SAndroid Build Coastguard Worker 'junit', 1028*6777b538SAndroid Build Coastguard Worker 'linker', 1029*6777b538SAndroid Build Coastguard Worker 'monkey', 1030*6777b538SAndroid Build Coastguard Worker] 1031*6777b538SAndroid Build Coastguard Worker 1032*6777b538SAndroid Build Coastguard Worker 1033*6777b538SAndroid Build Coastguard Workerdef RunTestsInPlatformMode(args, result_sink_client=None): 1034*6777b538SAndroid Build Coastguard Worker 1035*6777b538SAndroid Build Coastguard Worker def infra_error(message): 1036*6777b538SAndroid Build Coastguard Worker logging.fatal(message) 1037*6777b538SAndroid Build Coastguard Worker sys.exit(constants.INFRA_EXIT_CODE) 1038*6777b538SAndroid Build Coastguard Worker 1039*6777b538SAndroid Build Coastguard Worker if args.command not in _SUPPORTED_IN_PLATFORM_MODE: 1040*6777b538SAndroid Build Coastguard Worker infra_error('%s is not yet supported in platform mode' % args.command) 1041*6777b538SAndroid Build Coastguard Worker 1042*6777b538SAndroid Build Coastguard Worker ### Set up sigterm handler. 1043*6777b538SAndroid Build Coastguard Worker 1044*6777b538SAndroid Build Coastguard Worker contexts_to_notify_on_sigterm = [] 1045*6777b538SAndroid Build Coastguard Worker def unexpected_sigterm(_signum, _frame): 1046*6777b538SAndroid Build Coastguard Worker msg = [ 1047*6777b538SAndroid Build Coastguard Worker 'Received SIGTERM. Shutting down.', 1048*6777b538SAndroid Build Coastguard Worker ] 1049*6777b538SAndroid Build Coastguard Worker for live_thread in threading.enumerate(): 1050*6777b538SAndroid Build Coastguard Worker # pylint: disable=protected-access 1051*6777b538SAndroid Build Coastguard Worker thread_stack = ''.join(traceback.format_stack( 1052*6777b538SAndroid Build Coastguard Worker sys._current_frames()[live_thread.ident])) 1053*6777b538SAndroid Build Coastguard Worker msg.extend([ 1054*6777b538SAndroid Build Coastguard Worker 'Thread "%s" (ident: %s) is currently running:' % ( 1055*6777b538SAndroid Build Coastguard Worker live_thread.name, live_thread.ident), 1056*6777b538SAndroid Build Coastguard Worker thread_stack]) 1057*6777b538SAndroid Build Coastguard Worker 1058*6777b538SAndroid Build Coastguard Worker for context in contexts_to_notify_on_sigterm: 1059*6777b538SAndroid Build Coastguard Worker context.ReceivedSigterm() 1060*6777b538SAndroid Build Coastguard Worker 1061*6777b538SAndroid Build Coastguard Worker infra_error('\n'.join(msg)) 1062*6777b538SAndroid Build Coastguard Worker 1063*6777b538SAndroid Build Coastguard Worker signal.signal(signal.SIGTERM, unexpected_sigterm) 1064*6777b538SAndroid Build Coastguard Worker 1065*6777b538SAndroid Build Coastguard Worker ### Set up results handling. 1066*6777b538SAndroid Build Coastguard Worker # TODO(jbudorick): Rewrite results handling. 1067*6777b538SAndroid Build Coastguard Worker 1068*6777b538SAndroid Build Coastguard Worker # all_raw_results is a list of lists of 1069*6777b538SAndroid Build Coastguard Worker # base_test_result.TestRunResults objects. Each instance of 1070*6777b538SAndroid Build Coastguard Worker # TestRunResults contains all test results produced by a single try, 1071*6777b538SAndroid Build Coastguard Worker # while each list of TestRunResults contains all tries in a single 1072*6777b538SAndroid Build Coastguard Worker # iteration. 1073*6777b538SAndroid Build Coastguard Worker all_raw_results = [] 1074*6777b538SAndroid Build Coastguard Worker 1075*6777b538SAndroid Build Coastguard Worker # all_iteration_results is a list of base_test_result.TestRunResults 1076*6777b538SAndroid Build Coastguard Worker # objects. Each instance of TestRunResults contains the last test 1077*6777b538SAndroid Build Coastguard Worker # result for each test run in that iteration. 1078*6777b538SAndroid Build Coastguard Worker all_iteration_results = [] 1079*6777b538SAndroid Build Coastguard Worker 1080*6777b538SAndroid Build Coastguard Worker global_results_tags = set() 1081*6777b538SAndroid Build Coastguard Worker 1082*6777b538SAndroid Build Coastguard Worker json_file = tempfile.NamedTemporaryFile(delete=False) 1083*6777b538SAndroid Build Coastguard Worker json_file.close() 1084*6777b538SAndroid Build Coastguard Worker 1085*6777b538SAndroid Build Coastguard Worker @contextlib.contextmanager 1086*6777b538SAndroid Build Coastguard Worker def json_finalizer(): 1087*6777b538SAndroid Build Coastguard Worker try: 1088*6777b538SAndroid Build Coastguard Worker yield 1089*6777b538SAndroid Build Coastguard Worker finally: 1090*6777b538SAndroid Build Coastguard Worker if args.json_results_file and os.path.exists(json_file.name): 1091*6777b538SAndroid Build Coastguard Worker shutil.move(json_file.name, args.json_results_file) 1092*6777b538SAndroid Build Coastguard Worker elif args.isolated_script_test_output and os.path.exists(json_file.name): 1093*6777b538SAndroid Build Coastguard Worker shutil.move(json_file.name, args.isolated_script_test_output) 1094*6777b538SAndroid Build Coastguard Worker else: 1095*6777b538SAndroid Build Coastguard Worker os.remove(json_file.name) 1096*6777b538SAndroid Build Coastguard Worker 1097*6777b538SAndroid Build Coastguard Worker @contextlib.contextmanager 1098*6777b538SAndroid Build Coastguard Worker def json_writer(): 1099*6777b538SAndroid Build Coastguard Worker try: 1100*6777b538SAndroid Build Coastguard Worker yield 1101*6777b538SAndroid Build Coastguard Worker except Exception: 1102*6777b538SAndroid Build Coastguard Worker global_results_tags.add('UNRELIABLE_RESULTS') 1103*6777b538SAndroid Build Coastguard Worker raise 1104*6777b538SAndroid Build Coastguard Worker finally: 1105*6777b538SAndroid Build Coastguard Worker if args.isolated_script_test_output: 1106*6777b538SAndroid Build Coastguard Worker interrupted = 'UNRELIABLE_RESULTS' in global_results_tags 1107*6777b538SAndroid Build Coastguard Worker json_results.GenerateJsonTestResultFormatFile(all_raw_results, 1108*6777b538SAndroid Build Coastguard Worker interrupted, 1109*6777b538SAndroid Build Coastguard Worker json_file.name, 1110*6777b538SAndroid Build Coastguard Worker indent=2) 1111*6777b538SAndroid Build Coastguard Worker else: 1112*6777b538SAndroid Build Coastguard Worker json_results.GenerateJsonResultsFile( 1113*6777b538SAndroid Build Coastguard Worker all_raw_results, 1114*6777b538SAndroid Build Coastguard Worker json_file.name, 1115*6777b538SAndroid Build Coastguard Worker global_tags=list(global_results_tags), 1116*6777b538SAndroid Build Coastguard Worker indent=2) 1117*6777b538SAndroid Build Coastguard Worker 1118*6777b538SAndroid Build Coastguard Worker test_class_to_file_name_dict = {} 1119*6777b538SAndroid Build Coastguard Worker # Test Location is only supported for instrumentation tests as it 1120*6777b538SAndroid Build Coastguard Worker # requires the size-info file. 1121*6777b538SAndroid Build Coastguard Worker if test_instance.TestType() == 'instrumentation': 1122*6777b538SAndroid Build Coastguard Worker test_class_to_file_name_dict = _CreateClassToFileNameDict(args.test_apk) 1123*6777b538SAndroid Build Coastguard Worker 1124*6777b538SAndroid Build Coastguard Worker if result_sink_client: 1125*6777b538SAndroid Build Coastguard Worker for run in all_raw_results: 1126*6777b538SAndroid Build Coastguard Worker for results in run: 1127*6777b538SAndroid Build Coastguard Worker for r in results.GetAll(): 1128*6777b538SAndroid Build Coastguard Worker # Matches chrome.page_info.PageInfoViewTest#testChromePage 1129*6777b538SAndroid Build Coastguard Worker match = re.search(r'^(.+\..+)#', r.GetName()) 1130*6777b538SAndroid Build Coastguard Worker test_file_name = test_class_to_file_name_dict.get( 1131*6777b538SAndroid Build Coastguard Worker match.group(1)) if match else None 1132*6777b538SAndroid Build Coastguard Worker _SinkTestResult(r, test_file_name, result_sink_client) 1133*6777b538SAndroid Build Coastguard Worker 1134*6777b538SAndroid Build Coastguard Worker @contextlib.contextmanager 1135*6777b538SAndroid Build Coastguard Worker def upload_logcats_file(): 1136*6777b538SAndroid Build Coastguard Worker try: 1137*6777b538SAndroid Build Coastguard Worker yield 1138*6777b538SAndroid Build Coastguard Worker finally: 1139*6777b538SAndroid Build Coastguard Worker if not args.logcat_output_file: 1140*6777b538SAndroid Build Coastguard Worker logging.critical('Cannot upload logcat file: no file specified.') 1141*6777b538SAndroid Build Coastguard Worker elif not os.path.exists(args.logcat_output_file): 1142*6777b538SAndroid Build Coastguard Worker logging.critical("Cannot upload logcat file: file doesn't exist.") 1143*6777b538SAndroid Build Coastguard Worker else: 1144*6777b538SAndroid Build Coastguard Worker with open(args.logcat_output_file) as src: 1145*6777b538SAndroid Build Coastguard Worker dst = logdog_helper.open_text('unified_logcats') 1146*6777b538SAndroid Build Coastguard Worker if dst: 1147*6777b538SAndroid Build Coastguard Worker shutil.copyfileobj(src, dst) 1148*6777b538SAndroid Build Coastguard Worker dst.close() 1149*6777b538SAndroid Build Coastguard Worker logging.critical( 1150*6777b538SAndroid Build Coastguard Worker 'Logcat: %s', logdog_helper.get_viewer_url('unified_logcats')) 1151*6777b538SAndroid Build Coastguard Worker 1152*6777b538SAndroid Build Coastguard Worker 1153*6777b538SAndroid Build Coastguard Worker logcats_uploader = contextlib_ext.Optional( 1154*6777b538SAndroid Build Coastguard Worker upload_logcats_file(), 1155*6777b538SAndroid Build Coastguard Worker 'upload_logcats_file' in args and args.upload_logcats_file) 1156*6777b538SAndroid Build Coastguard Worker 1157*6777b538SAndroid Build Coastguard Worker save_detailed_results = (args.local_output or not local_utils.IsOnSwarming() 1158*6777b538SAndroid Build Coastguard Worker ) and not args.isolated_script_test_output 1159*6777b538SAndroid Build Coastguard Worker 1160*6777b538SAndroid Build Coastguard Worker ### Set up test objects. 1161*6777b538SAndroid Build Coastguard Worker 1162*6777b538SAndroid Build Coastguard Worker out_manager = output_manager_factory.CreateOutputManager(args) 1163*6777b538SAndroid Build Coastguard Worker env = environment_factory.CreateEnvironment( 1164*6777b538SAndroid Build Coastguard Worker args, out_manager, infra_error) 1165*6777b538SAndroid Build Coastguard Worker test_instance = test_instance_factory.CreateTestInstance(args, infra_error) 1166*6777b538SAndroid Build Coastguard Worker test_run = test_run_factory.CreateTestRun(env, test_instance, infra_error) 1167*6777b538SAndroid Build Coastguard Worker 1168*6777b538SAndroid Build Coastguard Worker contexts_to_notify_on_sigterm.append(env) 1169*6777b538SAndroid Build Coastguard Worker contexts_to_notify_on_sigterm.append(test_run) 1170*6777b538SAndroid Build Coastguard Worker 1171*6777b538SAndroid Build Coastguard Worker if args.list_tests: 1172*6777b538SAndroid Build Coastguard Worker try: 1173*6777b538SAndroid Build Coastguard Worker with out_manager, env, test_instance, test_run: 1174*6777b538SAndroid Build Coastguard Worker test_names = test_run.GetTestsForListing() 1175*6777b538SAndroid Build Coastguard Worker print('There are {} tests:'.format(len(test_names))) 1176*6777b538SAndroid Build Coastguard Worker for n in test_names: 1177*6777b538SAndroid Build Coastguard Worker print(n) 1178*6777b538SAndroid Build Coastguard Worker return 0 1179*6777b538SAndroid Build Coastguard Worker except NotImplementedError: 1180*6777b538SAndroid Build Coastguard Worker sys.stderr.write('Test does not support --list-tests (type={}).\n'.format( 1181*6777b538SAndroid Build Coastguard Worker args.command)) 1182*6777b538SAndroid Build Coastguard Worker return 1 1183*6777b538SAndroid Build Coastguard Worker 1184*6777b538SAndroid Build Coastguard Worker ### Run. 1185*6777b538SAndroid Build Coastguard Worker with out_manager, json_finalizer(): 1186*6777b538SAndroid Build Coastguard Worker # |raw_logs_fh| is only used by Robolectric tests. 1187*6777b538SAndroid Build Coastguard Worker raw_logs_fh = io.StringIO() if save_detailed_results else None 1188*6777b538SAndroid Build Coastguard Worker 1189*6777b538SAndroid Build Coastguard Worker with json_writer(), logcats_uploader, env, test_instance, test_run: 1190*6777b538SAndroid Build Coastguard Worker 1191*6777b538SAndroid Build Coastguard Worker repetitions = (range(args.repeat + 1192*6777b538SAndroid Build Coastguard Worker 1) if args.repeat >= 0 else itertools.count()) 1193*6777b538SAndroid Build Coastguard Worker result_counts = collections.defaultdict( 1194*6777b538SAndroid Build Coastguard Worker lambda: collections.defaultdict(int)) 1195*6777b538SAndroid Build Coastguard Worker iteration_count = 0 1196*6777b538SAndroid Build Coastguard Worker for _ in repetitions: 1197*6777b538SAndroid Build Coastguard Worker # raw_results will be populated with base_test_result.TestRunResults by 1198*6777b538SAndroid Build Coastguard Worker # test_run.RunTests(). It is immediately added to all_raw_results so 1199*6777b538SAndroid Build Coastguard Worker # that in the event of an exception, all_raw_results will already have 1200*6777b538SAndroid Build Coastguard Worker # the up-to-date results and those can be written to disk. 1201*6777b538SAndroid Build Coastguard Worker raw_results = [] 1202*6777b538SAndroid Build Coastguard Worker all_raw_results.append(raw_results) 1203*6777b538SAndroid Build Coastguard Worker 1204*6777b538SAndroid Build Coastguard Worker test_run.RunTests(raw_results, raw_logs_fh=raw_logs_fh) 1205*6777b538SAndroid Build Coastguard Worker if not raw_results: 1206*6777b538SAndroid Build Coastguard Worker all_raw_results.pop() 1207*6777b538SAndroid Build Coastguard Worker continue 1208*6777b538SAndroid Build Coastguard Worker 1209*6777b538SAndroid Build Coastguard Worker iteration_results = base_test_result.TestRunResults() 1210*6777b538SAndroid Build Coastguard Worker for r in reversed(raw_results): 1211*6777b538SAndroid Build Coastguard Worker iteration_results.AddTestRunResults(r) 1212*6777b538SAndroid Build Coastguard Worker all_iteration_results.append(iteration_results) 1213*6777b538SAndroid Build Coastguard Worker iteration_count += 1 1214*6777b538SAndroid Build Coastguard Worker 1215*6777b538SAndroid Build Coastguard Worker for r in iteration_results.GetAll(): 1216*6777b538SAndroid Build Coastguard Worker result_counts[r.GetName()][r.GetType()] += 1 1217*6777b538SAndroid Build Coastguard Worker 1218*6777b538SAndroid Build Coastguard Worker report_results.LogFull( 1219*6777b538SAndroid Build Coastguard Worker results=iteration_results, 1220*6777b538SAndroid Build Coastguard Worker test_type=test_instance.TestType(), 1221*6777b538SAndroid Build Coastguard Worker test_package=test_run.TestPackage(), 1222*6777b538SAndroid Build Coastguard Worker annotation=getattr(args, 'annotations', None), 1223*6777b538SAndroid Build Coastguard Worker flakiness_server=getattr(args, 'flakiness_dashboard_server', 1224*6777b538SAndroid Build Coastguard Worker None)) 1225*6777b538SAndroid Build Coastguard Worker 1226*6777b538SAndroid Build Coastguard Worker failed_tests = (iteration_results.GetNotPass() - 1227*6777b538SAndroid Build Coastguard Worker iteration_results.GetSkip()) 1228*6777b538SAndroid Build Coastguard Worker if failed_tests: 1229*6777b538SAndroid Build Coastguard Worker _LogRerunStatement(failed_tests, args.wrapper_script_args) 1230*6777b538SAndroid Build Coastguard Worker 1231*6777b538SAndroid Build Coastguard Worker if args.break_on_failure and not iteration_results.DidRunPass(): 1232*6777b538SAndroid Build Coastguard Worker break 1233*6777b538SAndroid Build Coastguard Worker 1234*6777b538SAndroid Build Coastguard Worker if iteration_count > 1: 1235*6777b538SAndroid Build Coastguard Worker # display summary results 1236*6777b538SAndroid Build Coastguard Worker # only display results for a test if at least one test did not pass 1237*6777b538SAndroid Build Coastguard Worker all_pass = 0 1238*6777b538SAndroid Build Coastguard Worker tot_tests = 0 1239*6777b538SAndroid Build Coastguard Worker for test_name in result_counts: 1240*6777b538SAndroid Build Coastguard Worker tot_tests += 1 1241*6777b538SAndroid Build Coastguard Worker if any(result_counts[test_name][x] for x in ( 1242*6777b538SAndroid Build Coastguard Worker base_test_result.ResultType.FAIL, 1243*6777b538SAndroid Build Coastguard Worker base_test_result.ResultType.CRASH, 1244*6777b538SAndroid Build Coastguard Worker base_test_result.ResultType.TIMEOUT, 1245*6777b538SAndroid Build Coastguard Worker base_test_result.ResultType.UNKNOWN)): 1246*6777b538SAndroid Build Coastguard Worker logging.critical( 1247*6777b538SAndroid Build Coastguard Worker '%s: %s', 1248*6777b538SAndroid Build Coastguard Worker test_name, 1249*6777b538SAndroid Build Coastguard Worker ', '.join('%s %s' % (str(result_counts[test_name][i]), i) 1250*6777b538SAndroid Build Coastguard Worker for i in base_test_result.ResultType.GetTypes())) 1251*6777b538SAndroid Build Coastguard Worker else: 1252*6777b538SAndroid Build Coastguard Worker all_pass += 1 1253*6777b538SAndroid Build Coastguard Worker 1254*6777b538SAndroid Build Coastguard Worker logging.critical('%s of %s tests passed in all %s runs', 1255*6777b538SAndroid Build Coastguard Worker str(all_pass), 1256*6777b538SAndroid Build Coastguard Worker str(tot_tests), 1257*6777b538SAndroid Build Coastguard Worker str(iteration_count)) 1258*6777b538SAndroid Build Coastguard Worker 1259*6777b538SAndroid Build Coastguard Worker if save_detailed_results: 1260*6777b538SAndroid Build Coastguard Worker assert raw_logs_fh 1261*6777b538SAndroid Build Coastguard Worker raw_logs_fh.seek(0) 1262*6777b538SAndroid Build Coastguard Worker raw_logs = raw_logs_fh.read() 1263*6777b538SAndroid Build Coastguard Worker if raw_logs: 1264*6777b538SAndroid Build Coastguard Worker with out_manager.ArchivedTempfile( 1265*6777b538SAndroid Build Coastguard Worker 'raw_logs.txt', 'raw_logs', 1266*6777b538SAndroid Build Coastguard Worker output_manager.Datatype.TEXT) as raw_logs_file: 1267*6777b538SAndroid Build Coastguard Worker raw_logs_file.write(raw_logs) 1268*6777b538SAndroid Build Coastguard Worker logging.critical('RAW LOGS: %s', raw_logs_file.Link()) 1269*6777b538SAndroid Build Coastguard Worker 1270*6777b538SAndroid Build Coastguard Worker with out_manager.ArchivedTempfile( 1271*6777b538SAndroid Build Coastguard Worker 'test_results_presentation.html', 1272*6777b538SAndroid Build Coastguard Worker 'test_results_presentation', 1273*6777b538SAndroid Build Coastguard Worker output_manager.Datatype.HTML) as results_detail_file: 1274*6777b538SAndroid Build Coastguard Worker result_html_string, _, _ = test_results_presentation.result_details( 1275*6777b538SAndroid Build Coastguard Worker json_path=json_file.name, 1276*6777b538SAndroid Build Coastguard Worker test_name=args.command, 1277*6777b538SAndroid Build Coastguard Worker cs_base_url='http://cs.chromium.org', 1278*6777b538SAndroid Build Coastguard Worker local_output=True) 1279*6777b538SAndroid Build Coastguard Worker results_detail_file.write(result_html_string) 1280*6777b538SAndroid Build Coastguard Worker results_detail_file.flush() 1281*6777b538SAndroid Build Coastguard Worker logging.critical('TEST RESULTS: %s', results_detail_file.Link()) 1282*6777b538SAndroid Build Coastguard Worker 1283*6777b538SAndroid Build Coastguard Worker ui_screenshots = test_results_presentation.ui_screenshot_set( 1284*6777b538SAndroid Build Coastguard Worker json_file.name) 1285*6777b538SAndroid Build Coastguard Worker if ui_screenshots: 1286*6777b538SAndroid Build Coastguard Worker with out_manager.ArchivedTempfile( 1287*6777b538SAndroid Build Coastguard Worker 'ui_screenshots.json', 1288*6777b538SAndroid Build Coastguard Worker 'ui_capture', 1289*6777b538SAndroid Build Coastguard Worker output_manager.Datatype.JSON) as ui_screenshot_file: 1290*6777b538SAndroid Build Coastguard Worker ui_screenshot_file.write(ui_screenshots) 1291*6777b538SAndroid Build Coastguard Worker logging.critical('UI Screenshots: %s', ui_screenshot_file.Link()) 1292*6777b538SAndroid Build Coastguard Worker 1293*6777b538SAndroid Build Coastguard Worker return (0 if all(r.DidRunPass() for r in all_iteration_results) 1294*6777b538SAndroid Build Coastguard Worker else constants.ERROR_EXIT_CODE) 1295*6777b538SAndroid Build Coastguard Worker 1296*6777b538SAndroid Build Coastguard Worker 1297*6777b538SAndroid Build Coastguard Workerdef _LogRerunStatement(failed_tests, wrapper_arg_str): 1298*6777b538SAndroid Build Coastguard Worker """Logs a message that can rerun the failed tests. 1299*6777b538SAndroid Build Coastguard Worker 1300*6777b538SAndroid Build Coastguard Worker Logs a copy/pasteable message that filters tests so just the failing tests 1301*6777b538SAndroid Build Coastguard Worker are run. 1302*6777b538SAndroid Build Coastguard Worker 1303*6777b538SAndroid Build Coastguard Worker Args: 1304*6777b538SAndroid Build Coastguard Worker failed_tests: A set of test results that did not pass. 1305*6777b538SAndroid Build Coastguard Worker wrapper_arg_str: A string of args that were passed to the called wrapper 1306*6777b538SAndroid Build Coastguard Worker script. 1307*6777b538SAndroid Build Coastguard Worker """ 1308*6777b538SAndroid Build Coastguard Worker rerun_arg_list = [] 1309*6777b538SAndroid Build Coastguard Worker try: 1310*6777b538SAndroid Build Coastguard Worker constants.CheckOutputDirectory() 1311*6777b538SAndroid Build Coastguard Worker # constants.CheckOutputDirectory throws bare exceptions. 1312*6777b538SAndroid Build Coastguard Worker except: # pylint: disable=bare-except 1313*6777b538SAndroid Build Coastguard Worker logging.exception('Output directory not found. Unable to generate failing ' 1314*6777b538SAndroid Build Coastguard Worker 'test filter file.') 1315*6777b538SAndroid Build Coastguard Worker return 1316*6777b538SAndroid Build Coastguard Worker 1317*6777b538SAndroid Build Coastguard Worker output_directory = constants.GetOutDirectory() 1318*6777b538SAndroid Build Coastguard Worker if not os.path.exists(output_directory): 1319*6777b538SAndroid Build Coastguard Worker logging.error('Output directory not found. Unable to generate failing ' 1320*6777b538SAndroid Build Coastguard Worker 'test filter file.') 1321*6777b538SAndroid Build Coastguard Worker return 1322*6777b538SAndroid Build Coastguard Worker 1323*6777b538SAndroid Build Coastguard Worker test_filter_file = os.path.join(os.path.relpath(output_directory), 1324*6777b538SAndroid Build Coastguard Worker _RERUN_FAILED_TESTS_FILE) 1325*6777b538SAndroid Build Coastguard Worker arg_list = shlex.split(wrapper_arg_str) if wrapper_arg_str else sys.argv 1326*6777b538SAndroid Build Coastguard Worker index = 0 1327*6777b538SAndroid Build Coastguard Worker while index < len(arg_list): 1328*6777b538SAndroid Build Coastguard Worker arg = arg_list[index] 1329*6777b538SAndroid Build Coastguard Worker # Skip adding the filter=<file> and/or the filter arg as we're replacing 1330*6777b538SAndroid Build Coastguard Worker # it with the new filter arg. 1331*6777b538SAndroid Build Coastguard Worker # This covers --test-filter=, --test-launcher-filter-file=, --gtest-filter=, 1332*6777b538SAndroid Build Coastguard Worker # --test-filter *Foobar.baz, -f *foobar, --package-filter <package>, 1333*6777b538SAndroid Build Coastguard Worker # --runner-filter <runner>. 1334*6777b538SAndroid Build Coastguard Worker if 'filter' in arg or arg == '-f': 1335*6777b538SAndroid Build Coastguard Worker index += 1 if '=' in arg else 2 1336*6777b538SAndroid Build Coastguard Worker continue 1337*6777b538SAndroid Build Coastguard Worker 1338*6777b538SAndroid Build Coastguard Worker rerun_arg_list.append(arg) 1339*6777b538SAndroid Build Coastguard Worker index += 1 1340*6777b538SAndroid Build Coastguard Worker 1341*6777b538SAndroid Build Coastguard Worker failed_test_list = [str(t) for t in failed_tests] 1342*6777b538SAndroid Build Coastguard Worker with open(test_filter_file, 'w') as fp: 1343*6777b538SAndroid Build Coastguard Worker for t in failed_test_list: 1344*6777b538SAndroid Build Coastguard Worker # Test result names can have # in them that don't match when applied as 1345*6777b538SAndroid Build Coastguard Worker # a test name filter. 1346*6777b538SAndroid Build Coastguard Worker fp.write('%s\n' % t.replace('#', '.')) 1347*6777b538SAndroid Build Coastguard Worker 1348*6777b538SAndroid Build Coastguard Worker rerun_arg_list.append('--test-launcher-filter-file=%s' % test_filter_file) 1349*6777b538SAndroid Build Coastguard Worker msg = """ 1350*6777b538SAndroid Build Coastguard Worker %d Test(s) failed. 1351*6777b538SAndroid Build Coastguard Worker Rerun failed tests with copy and pastable command: 1352*6777b538SAndroid Build Coastguard Worker %s 1353*6777b538SAndroid Build Coastguard Worker """ 1354*6777b538SAndroid Build Coastguard Worker logging.critical(msg, len(failed_tests), shlex.join(rerun_arg_list)) 1355*6777b538SAndroid Build Coastguard Worker 1356*6777b538SAndroid Build Coastguard Worker 1357*6777b538SAndroid Build Coastguard Workerdef DumpThreadStacks(_signal, _frame): 1358*6777b538SAndroid Build Coastguard Worker for thread in threading.enumerate(): 1359*6777b538SAndroid Build Coastguard Worker reraiser_thread.LogThreadStack(thread) 1360*6777b538SAndroid Build Coastguard Worker 1361*6777b538SAndroid Build Coastguard Worker 1362*6777b538SAndroid Build Coastguard Workerdef main(): 1363*6777b538SAndroid Build Coastguard Worker signal.signal(signal.SIGUSR1, DumpThreadStacks) 1364*6777b538SAndroid Build Coastguard Worker 1365*6777b538SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 1366*6777b538SAndroid Build Coastguard Worker command_parsers = parser.add_subparsers( 1367*6777b538SAndroid Build Coastguard Worker title='test types', dest='command') 1368*6777b538SAndroid Build Coastguard Worker 1369*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1370*6777b538SAndroid Build Coastguard Worker 'gtest', 1371*6777b538SAndroid Build Coastguard Worker help='googletest-based C++ tests') 1372*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1373*6777b538SAndroid Build Coastguard Worker AddDeviceOptions(subp) 1374*6777b538SAndroid Build Coastguard Worker AddEmulatorOptions(subp) 1375*6777b538SAndroid Build Coastguard Worker AddGTestOptions(subp) 1376*6777b538SAndroid Build Coastguard Worker AddTracingOptions(subp) 1377*6777b538SAndroid Build Coastguard Worker AddCommandLineOptions(subp) 1378*6777b538SAndroid Build Coastguard Worker 1379*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1380*6777b538SAndroid Build Coastguard Worker 'hostside', 1381*6777b538SAndroid Build Coastguard Worker help='Webview CTS host-side tests') 1382*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1383*6777b538SAndroid Build Coastguard Worker AddDeviceOptions(subp) 1384*6777b538SAndroid Build Coastguard Worker AddEmulatorOptions(subp) 1385*6777b538SAndroid Build Coastguard Worker AddHostsideTestOptions(subp) 1386*6777b538SAndroid Build Coastguard Worker 1387*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1388*6777b538SAndroid Build Coastguard Worker 'instrumentation', 1389*6777b538SAndroid Build Coastguard Worker help='InstrumentationTestCase-based Java tests') 1390*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1391*6777b538SAndroid Build Coastguard Worker AddDeviceOptions(subp) 1392*6777b538SAndroid Build Coastguard Worker AddEmulatorOptions(subp) 1393*6777b538SAndroid Build Coastguard Worker AddInstrumentationTestOptions(subp) 1394*6777b538SAndroid Build Coastguard Worker AddSkiaGoldTestOptions(subp) 1395*6777b538SAndroid Build Coastguard Worker AddTracingOptions(subp) 1396*6777b538SAndroid Build Coastguard Worker AddCommandLineOptions(subp) 1397*6777b538SAndroid Build Coastguard Worker 1398*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1399*6777b538SAndroid Build Coastguard Worker 'junit', 1400*6777b538SAndroid Build Coastguard Worker help='JUnit4-based Java tests') 1401*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1402*6777b538SAndroid Build Coastguard Worker AddJUnitTestOptions(subp) 1403*6777b538SAndroid Build Coastguard Worker 1404*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1405*6777b538SAndroid Build Coastguard Worker 'linker', 1406*6777b538SAndroid Build Coastguard Worker help='linker tests') 1407*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1408*6777b538SAndroid Build Coastguard Worker AddDeviceOptions(subp) 1409*6777b538SAndroid Build Coastguard Worker AddEmulatorOptions(subp) 1410*6777b538SAndroid Build Coastguard Worker AddLinkerTestOptions(subp) 1411*6777b538SAndroid Build Coastguard Worker 1412*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1413*6777b538SAndroid Build Coastguard Worker 'monkey', 1414*6777b538SAndroid Build Coastguard Worker help="tests based on Android's monkey command") 1415*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1416*6777b538SAndroid Build Coastguard Worker AddDeviceOptions(subp) 1417*6777b538SAndroid Build Coastguard Worker AddEmulatorOptions(subp) 1418*6777b538SAndroid Build Coastguard Worker AddMonkeyTestOptions(subp) 1419*6777b538SAndroid Build Coastguard Worker 1420*6777b538SAndroid Build Coastguard Worker subp = command_parsers.add_parser( 1421*6777b538SAndroid Build Coastguard Worker 'python', 1422*6777b538SAndroid Build Coastguard Worker help='python tests based on unittest.TestCase') 1423*6777b538SAndroid Build Coastguard Worker AddCommonOptions(subp) 1424*6777b538SAndroid Build Coastguard Worker AddPythonTestOptions(subp) 1425*6777b538SAndroid Build Coastguard Worker 1426*6777b538SAndroid Build Coastguard Worker args, unknown_args = parser.parse_known_args() 1427*6777b538SAndroid Build Coastguard Worker if unknown_args: 1428*6777b538SAndroid Build Coastguard Worker if hasattr(args, 'allow_unknown') and args.allow_unknown: 1429*6777b538SAndroid Build Coastguard Worker args.command_line_flags = unknown_args 1430*6777b538SAndroid Build Coastguard Worker else: 1431*6777b538SAndroid Build Coastguard Worker parser.error('unrecognized arguments: %s' % ' '.join(unknown_args)) 1432*6777b538SAndroid Build Coastguard Worker 1433*6777b538SAndroid Build Coastguard Worker # --replace-system-package/--remove-system-package has the potential to cause 1434*6777b538SAndroid Build Coastguard Worker # issues if --enable-concurrent-adb is set, so disallow that combination. 1435*6777b538SAndroid Build Coastguard Worker concurrent_adb_enabled = (hasattr(args, 'enable_concurrent_adb') 1436*6777b538SAndroid Build Coastguard Worker and args.enable_concurrent_adb) 1437*6777b538SAndroid Build Coastguard Worker replacing_system_packages = (hasattr(args, 'replace_system_package') 1438*6777b538SAndroid Build Coastguard Worker and args.replace_system_package) 1439*6777b538SAndroid Build Coastguard Worker removing_system_packages = (hasattr(args, 'system_packages_to_remove') 1440*6777b538SAndroid Build Coastguard Worker and args.system_packages_to_remove) 1441*6777b538SAndroid Build Coastguard Worker if (concurrent_adb_enabled 1442*6777b538SAndroid Build Coastguard Worker and (replacing_system_packages or removing_system_packages)): 1443*6777b538SAndroid Build Coastguard Worker parser.error('--enable-concurrent-adb cannot be used with either ' 1444*6777b538SAndroid Build Coastguard Worker '--replace-system-package or --remove-system-package') 1445*6777b538SAndroid Build Coastguard Worker 1446*6777b538SAndroid Build Coastguard Worker # --use-webview-provider has the potential to cause issues if 1447*6777b538SAndroid Build Coastguard Worker # --enable-concurrent-adb is set, so disallow that combination 1448*6777b538SAndroid Build Coastguard Worker if (hasattr(args, 'use_webview_provider') and 1449*6777b538SAndroid Build Coastguard Worker hasattr(args, 'enable_concurrent_adb') and args.use_webview_provider and 1450*6777b538SAndroid Build Coastguard Worker args.enable_concurrent_adb): 1451*6777b538SAndroid Build Coastguard Worker parser.error('--use-webview-provider and --enable-concurrent-adb cannot ' 1452*6777b538SAndroid Build Coastguard Worker 'be used together') 1453*6777b538SAndroid Build Coastguard Worker 1454*6777b538SAndroid Build Coastguard Worker if (getattr(args, 'coverage_on_the_fly', False) 1455*6777b538SAndroid Build Coastguard Worker and not getattr(args, 'coverage_dir', '')): 1456*6777b538SAndroid Build Coastguard Worker parser.error('--coverage-on-the-fly requires --coverage-dir') 1457*6777b538SAndroid Build Coastguard Worker 1458*6777b538SAndroid Build Coastguard Worker if (hasattr(args, 'debug_socket') or 1459*6777b538SAndroid Build Coastguard Worker (hasattr(args, 'wait_for_java_debugger') and 1460*6777b538SAndroid Build Coastguard Worker args.wait_for_java_debugger)): 1461*6777b538SAndroid Build Coastguard Worker args.num_retries = 0 1462*6777b538SAndroid Build Coastguard Worker 1463*6777b538SAndroid Build Coastguard Worker # Result-sink may not exist in the environment if rdb stream is not enabled. 1464*6777b538SAndroid Build Coastguard Worker result_sink_client = result_sink.TryInitClient() 1465*6777b538SAndroid Build Coastguard Worker 1466*6777b538SAndroid Build Coastguard Worker try: 1467*6777b538SAndroid Build Coastguard Worker return RunTestsCommand(args, result_sink_client) 1468*6777b538SAndroid Build Coastguard Worker except base_error.BaseError as e: 1469*6777b538SAndroid Build Coastguard Worker logging.exception('Error occurred.') 1470*6777b538SAndroid Build Coastguard Worker if e.is_infra_error: 1471*6777b538SAndroid Build Coastguard Worker return constants.INFRA_EXIT_CODE 1472*6777b538SAndroid Build Coastguard Worker return constants.ERROR_EXIT_CODE 1473*6777b538SAndroid Build Coastguard Worker except Exception: # pylint: disable=W0703 1474*6777b538SAndroid Build Coastguard Worker logging.exception('Unrecognized error occurred.') 1475*6777b538SAndroid Build Coastguard Worker return constants.ERROR_EXIT_CODE 1476*6777b538SAndroid Build Coastguard Worker 1477*6777b538SAndroid Build Coastguard Worker 1478*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 1479*6777b538SAndroid Build Coastguard Worker exit_code = main() 1480*6777b538SAndroid Build Coastguard Worker if exit_code == constants.INFRA_EXIT_CODE: 1481*6777b538SAndroid Build Coastguard Worker # This exit code is returned in case of missing, unreachable, 1482*6777b538SAndroid Build Coastguard Worker # or otherwise not fit for purpose test devices. 1483*6777b538SAndroid Build Coastguard Worker # When this happens, the graceful cleanup triggered by sys.exit() 1484*6777b538SAndroid Build Coastguard Worker # hangs indefinitely (on swarming - until it hits 20min timeout). 1485*6777b538SAndroid Build Coastguard Worker # Skip cleanup (other than flushing output streams) and exit forcefully 1486*6777b538SAndroid Build Coastguard Worker # to avoid the hang. 1487*6777b538SAndroid Build Coastguard Worker sys.stdout.flush() 1488*6777b538SAndroid Build Coastguard Worker sys.stderr.flush() 1489*6777b538SAndroid Build Coastguard Worker os._exit(exit_code) # pylint: disable=protected-access 1490*6777b538SAndroid Build Coastguard Worker else: 1491*6777b538SAndroid Build Coastguard Worker sys.exit(exit_code) 1492