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