blob: 9f1b22e56dd19e66e84ad72b97b081383bff7490 [file] [log] [blame]
[email protected]fbe29322013-07-09 09:03:261#!/usr/bin/env python
2#
3# Copyright 2013 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
[email protected]181a5c92013-09-06 17:11:467"""Runs all types of tests from one unified interface."""
[email protected]fbe29322013-07-09 09:03:268
jama47ca85c2014-12-03 18:38:079import argparse
[email protected]fbe29322013-07-09 09:03:2610import collections
jbudorickeb7ea71c2015-09-28 16:40:2011import itertools
[email protected]f7148dd42013-08-20 14:24:5712import logging
[email protected]fbe29322013-07-09 09:03:2613import os
[email protected]83bb8152013-11-19 15:02:2114import signal
[email protected]fbe29322013-07-09 09:03:2615import sys
[email protected]83bb8152013-11-19 15:02:2116import threading
jbudorick256fd532014-10-24 01:50:1317import unittest
[email protected]fbe29322013-07-09 09:03:2618
jbudorick0c2a94a2015-12-04 14:27:4319import devil_chromium
20
jbudorick061629442015-09-03 18:00:5721from devil import base_error
22from devil.android import apk_helper
23from devil.android import device_blacklist
24from devil.android import device_errors
25from devil.android import device_utils
26from devil.android import ports
27from devil.utils import reraiser_thread
28from devil.utils import run_tests_helper
29
[email protected]fbe29322013-07-09 09:03:2630from pylib import constants
[email protected]c0662e092013-11-12 11:51:2531from pylib import forwarder
[email protected]fbe29322013-07-09 09:03:2632from pylib.base import base_test_result
jbudorick66dc3722014-11-06 21:33:5133from pylib.base import environment_factory
[email protected]6bc1bda22013-07-19 22:08:3734from pylib.base import test_dispatcher
jbudorick66dc3722014-11-06 21:33:5135from pylib.base import test_instance_factory
36from pylib.base import test_run_factory
[email protected]6b6abac6d2013-10-03 11:56:3837from pylib.linker import setup as linker_setup
[email protected]37ee0c792013-08-06 19:10:1338from pylib.host_driven import setup as host_driven_setup
[email protected]6bc1bda22013-07-19 22:08:3739from pylib.instrumentation import setup as instrumentation_setup
[email protected]2a684222013-08-01 16:59:2240from pylib.instrumentation import test_options as instrumentation_test_options
jbudorick9a6b7b332014-09-20 00:01:0741from pylib.junit import setup as junit_setup
42from pylib.junit import test_dispatcher as junit_dispatcher
[email protected]3dbdfa42013-08-08 01:08:1443from pylib.monkey import setup as monkey_setup
44from pylib.monkey import test_options as monkey_test_options
[email protected]ec3170b2013-08-14 14:39:4745from pylib.perf import setup as perf_setup
46from pylib.perf import test_options as perf_test_options
47from pylib.perf import test_runner as perf_test_runner
jbudorickb8c42072014-12-01 18:07:5448from pylib.results import json_results
49from pylib.results import report_results
[email protected]fbe29322013-07-09 09:03:2650
51
jbudorick0c2a94a2015-12-04 14:27:4352_DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join(
53 constants.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json'))
54
55
jama47ca85c2014-12-03 18:38:0756def AddCommonOptions(parser):
57 """Adds all common options to |parser|."""
[email protected]fbe29322013-07-09 09:03:2658
jama47ca85c2014-12-03 18:38:0759 group = parser.add_argument_group('Common Options')
60
[email protected]dfffbcbc2013-09-17 22:06:0161 default_build_type = os.environ.get('BUILDTYPE', 'Debug')
jama47ca85c2014-12-03 18:38:0762
63 debug_or_release_group = group.add_mutually_exclusive_group()
64 debug_or_release_group.add_argument(
65 '--debug', action='store_const', const='Debug', dest='build_type',
66 default=default_build_type,
67 help=('If set, run test suites under out/Debug. '
68 'Default is env var BUILDTYPE or Debug.'))
69 debug_or_release_group.add_argument(
70 '--release', action='store_const', const='Release', dest='build_type',
71 help=('If set, run test suites under out/Release. '
72 'Default is env var BUILDTYPE or Debug.'))
73
74 group.add_argument('--build-directory', dest='build_directory',
75 help=('Path to the directory in which build files are'
76 ' located (should not include build type)'))
77 group.add_argument('--output-directory', dest='output_directory',
78 help=('Path to the directory in which build files are'
79 ' located (must include build type). This will take'
80 ' precedence over --debug, --release and'
81 ' --build-directory'))
agrieveddb11f12015-10-23 17:03:4382 group.add_argument('--num_retries', '--num-retries', dest='num_retries',
83 type=int, default=2,
jama47ca85c2014-12-03 18:38:0784 help=('Number of retries for a test before '
85 'giving up (default: %(default)s).'))
86 group.add_argument('-v',
87 '--verbose',
88 dest='verbose_count',
89 default=0,
90 action='count',
91 help='Verbose level (multiple times for more)')
92 group.add_argument('--flakiness-dashboard-server',
93 dest='flakiness_dashboard_server',
94 help=('Address of the server that is hosting the '
95 'Chrome for Android flakiness dashboard.'))
96 group.add_argument('--enable-platform-mode', action='store_true',
97 help=('Run the test scripts in platform mode, which '
98 'conceptually separates the test runner from the '
99 '"device" (local or remote, real or emulated) on '
100 'which the tests are running. [experimental]'))
101 group.add_argument('-e', '--environment', default='local',
102 choices=constants.VALID_ENVIRONMENTS,
103 help='Test environment to run in (default: %(default)s).')
104 group.add_argument('--adb-path',
105 help=('Specify the absolute path of the adb binary that '
106 'should be used.'))
stipa5733b52015-12-02 08:17:19107 group.add_argument('--json-results-file', '--test-launcher-summary-output',
108 dest='json_results_file',
jama47ca85c2014-12-03 18:38:07109 help='If set, will dump results in JSON form '
110 'to specified file.')
[email protected]fbe29322013-07-09 09:03:26111
jama47ca85c2014-12-03 18:38:07112def ProcessCommonOptions(args):
[email protected]fbe29322013-07-09 09:03:26113 """Processes and handles all common options."""
jama47ca85c2014-12-03 18:38:07114 run_tests_helper.SetLogLevel(args.verbose_count)
115 constants.SetBuildType(args.build_type)
116 if args.build_directory:
117 constants.SetBuildDirectory(args.build_directory)
118 if args.output_directory:
mikecase0aea9c52015-04-30 00:12:33119 constants.SetOutputDirectory(args.output_directory)
jbudorick0c2a94a2015-12-04 14:27:43120
121 devil_custom_deps = None
jama47ca85c2014-12-03 18:38:07122 if args.adb_path:
jbudorick0c2a94a2015-12-04 14:27:43123 devil_custom_deps = {
124 'adb': {
125 'android_host': [args.adb_path]
126 }
127 }
128
129 devil_chromium.Initialize(
130 output_directory=constants.GetOutDirectory(),
131 custom_deps=devil_custom_deps)
132
mikecase48e16bf2014-11-19 22:46:45133 # Some things such as Forwarder require ADB to be in the environment path.
134 adb_dir = os.path.dirname(constants.GetAdbPath())
135 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep):
136 os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
[email protected]fbe29322013-07-09 09:03:26137
138
rnephew5c499782014-12-12 19:08:55139def AddRemoteDeviceOptions(parser):
140 group = parser.add_argument_group('Remote Device Options')
141
rnephewefe44b42015-02-04 04:45:15142 group.add_argument('--trigger',
jbudoricke6c560152015-01-13 23:49:28143 help=('Only triggers the test if set. Stores test_run_id '
144 'in given file path. '))
rnephewefe44b42015-02-04 04:45:15145 group.add_argument('--collect',
jbudoricke6c560152015-01-13 23:49:28146 help=('Only collects the test results if set. '
147 'Gets test_run_id from given file path.'))
rnephewefe44b42015-02-04 04:45:15148 group.add_argument('--remote-device', action='append',
jbudoricke6c560152015-01-13 23:49:28149 help='Device type to run test on.')
rnephewefe44b42015-02-04 04:45:15150 group.add_argument('--results-path',
jbudoricke6c560152015-01-13 23:49:28151 help='File path to download results to.')
rnephew7f1e2052014-12-12 23:00:11152 group.add_argument('--api-protocol',
jbudoricke6c560152015-01-13 23:49:28153 help='HTTP protocol to use. (http or https)')
rnephewefe44b42015-02-04 04:45:15154 group.add_argument('--api-address',
155 help='Address to send HTTP requests.')
156 group.add_argument('--api-port',
157 help='Port to send HTTP requests to.')
158 group.add_argument('--runner-type',
jbudoricke6c560152015-01-13 23:49:28159 help='Type of test to run as.')
rnephewefe44b42015-02-04 04:45:15160 group.add_argument('--runner-package',
161 help='Package name of test.')
162 group.add_argument('--device-type',
rnephewa46fc562015-01-23 16:00:14163 choices=constants.VALID_DEVICE_TYPES,
164 help=('Type of device to run on. iOS or android'))
rnephewefe44b42015-02-04 04:45:15165 group.add_argument('--device-oem', action='append',
166 help='Device OEM to run on.')
167 group.add_argument('--remote-device-file',
168 help=('File with JSON to select remote device. '
169 'Overrides all other flags.'))
rnephewc9ae8f52015-02-13 03:02:55170 group.add_argument('--remote-device-timeout', type=int,
171 help='Times to retry finding remote device')
mikecase520cbbb52015-04-21 18:51:18172 group.add_argument('--network-config', type=int,
173 help='Integer that specifies the network environment '
174 'that the tests will be run in.')
mikecaseddfa35d2015-10-28 01:14:27175 group.add_argument('--test-timeout', type=int,
176 help='Test run timeout in seconds.')
rnephewefe44b42015-02-04 04:45:15177
178 device_os_group = group.add_mutually_exclusive_group()
179 device_os_group.add_argument('--remote-device-minimum-os',
180 help='Minimum OS on device.')
181 device_os_group.add_argument('--remote-device-os', action='append',
182 help='OS to have on the device.')
rnephew5c499782014-12-12 19:08:55183
184 api_secret_group = group.add_mutually_exclusive_group()
185 api_secret_group.add_argument('--api-secret', default='',
jbudoricke6c560152015-01-13 23:49:28186 help='API secret for remote devices.')
rnephew5c499782014-12-12 19:08:55187 api_secret_group.add_argument('--api-secret-file', default='',
jbudoricke6c560152015-01-13 23:49:28188 help='Path to file that contains API secret.')
rnephew5c499782014-12-12 19:08:55189
190 api_key_group = group.add_mutually_exclusive_group()
191 api_key_group.add_argument('--api-key', default='',
jbudoricke6c560152015-01-13 23:49:28192 help='API key for remote devices.')
rnephew5c499782014-12-12 19:08:55193 api_key_group.add_argument('--api-key-file', default='',
jbudoricke6c560152015-01-13 23:49:28194 help='Path to file that contains API key.')
rnephew5c499782014-12-12 19:08:55195
196
jama47ca85c2014-12-03 18:38:07197def AddDeviceOptions(parser):
198 """Adds device options to |parser|."""
199 group = parser.add_argument_group(title='Device Options')
jama47ca85c2014-12-03 18:38:07200 group.add_argument('--tool',
201 dest='tool',
202 help=('Run the test under a tool '
203 '(use --tool help to list them)'))
204 group.add_argument('-d', '--device', dest='test_device',
205 help=('Target device for the test suite '
206 'to run on.'))
jbudorickdde688fb2015-08-27 03:00:17207 group.add_argument('--blacklist-file', help='Device blacklist file.')
agrievea538a142015-10-09 15:45:56208 group.add_argument('--enable-device-cache', action='store_true',
209 help='Cache device state to disk between runs')
agrieve1a02e582015-10-15 21:35:39210 group.add_argument('--incremental-install', action='store_true',
211 help='Use an _incremental apk.')
agrieve8bcb52e2015-10-20 19:38:33212 group.add_argument('--enable-concurrent-adb', action='store_true',
213 help='Run multiple adb commands at the same time, even '
214 'for the same device.')
jbudorick256fd532014-10-24 01:50:13215
216
jama47ca85c2014-12-03 18:38:07217def AddGTestOptions(parser):
218 """Adds gtest options to |parser|."""
[email protected]fbe29322013-07-09 09:03:26219
jama47ca85c2014-12-03 18:38:07220 group = parser.add_argument_group('GTest Options')
jbudorick15cdcd52014-12-03 19:58:49221 group.add_argument('-s', '--suite', dest='suite_name',
jama47ca85c2014-12-03 18:38:07222 nargs='+', metavar='SUITE_NAME', required=True,
jbudorick277f2312015-09-24 16:37:43223 help='Executable name of the test suite to run.')
jama47ca85c2014-12-03 18:38:07224 group.add_argument('--gtest_also_run_disabled_tests',
225 '--gtest-also-run-disabled-tests',
226 dest='run_disabled', action='store_true',
227 help='Also run disabled tests if applicable.')
228 group.add_argument('-a', '--test-arguments', dest='test_arguments',
229 default='',
230 help='Additional arguments to pass to the test.')
jbudorick24616eb2015-10-06 02:40:57231 group.add_argument('-t', '--shard-timeout',
232 dest='shard_timeout', type=int, default=60,
jama47ca85c2014-12-03 18:38:07233 help='Timeout to wait for each test '
234 '(default: %(default)s).')
235 group.add_argument('--isolate_file_path',
236 '--isolate-file-path',
237 dest='isolate_file_path',
238 help='.isolate file path to override the default '
239 'path')
jbudorick5ee45892015-06-10 18:46:22240 group.add_argument('--app-data-file', action='append', dest='app_data_files',
241 help='A file path relative to the app data directory '
242 'that should be saved to the host.')
243 group.add_argument('--app-data-file-dir',
244 help='Host directory to which app data files will be'
245 ' saved. Used with --app-data-file.')
mlliud7f9fe92015-06-15 19:36:56246 group.add_argument('--delete-stale-data', dest='delete_stale_data',
247 action='store_true',
248 help='Delete stale test data on the device.')
jbudorickeb7ea71c2015-09-28 16:40:20249 group.add_argument('--repeat', '--gtest_repeat', '--gtest-repeat',
250 dest='repeat', type=int, default=0,
251 help='Number of times to repeat the specified set of '
252 'tests.')
alexandermonta3f03bf2015-12-02 18:56:45253 group.add_argument('--break-on-failure', '--break_on_failure',
254 dest='break_on_failure', action='store_true',
255 help='Whether to break on failure.')
jbudorick442a6932015-02-03 03:01:15256
257 filter_group = group.add_mutually_exclusive_group()
258 filter_group.add_argument('-f', '--gtest_filter', '--gtest-filter',
259 dest='test_filter',
260 help='googletest-style filter string.')
261 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file',
262 help='Path to file that contains googletest-style '
263 'filter strings. (Lines will be joined with '
264 '":" to create a single filter string.)')
265
jama47ca85c2014-12-03 18:38:07266 AddDeviceOptions(parser)
267 AddCommonOptions(parser)
rnephew5c499782014-12-12 19:08:55268 AddRemoteDeviceOptions(parser)
[email protected]fbe29322013-07-09 09:03:26269
270
jama47ca85c2014-12-03 18:38:07271def AddLinkerTestOptions(parser):
272 group = parser.add_argument_group('Linker Test Options')
273 group.add_argument('-f', '--gtest-filter', dest='test_filter',
274 help='googletest-style filter string.')
275 AddCommonOptions(parser)
276 AddDeviceOptions(parser)
[email protected]6b6abac6d2013-10-03 11:56:38277
278
jama47ca85c2014-12-03 18:38:07279def AddJavaTestOptions(argument_group):
[email protected]fbe29322013-07-09 09:03:26280 """Adds the Java test options to |option_parser|."""
281
jama47ca85c2014-12-03 18:38:07282 argument_group.add_argument(
283 '-f', '--test-filter', dest='test_filter',
284 help=('Test filter (if not fully qualified, will run all matches).'))
285 argument_group.add_argument(
jbudorickeb7ea71c2015-09-28 16:40:20286 '--repeat', dest='repeat', type=int, default=0,
287 help='Number of times to repeat the specified set of tests.')
288 argument_group.add_argument(
alexandermonta3f03bf2015-12-02 18:56:45289 '--break-on-failure', '--break_on_failure',
290 dest='break_on_failure', action='store_true',
291 help='Whether to break on failure.')
292 argument_group.add_argument(
[email protected]fbe29322013-07-09 09:03:26293 '-A', '--annotation', dest='annotation_str',
294 help=('Comma-separated list of annotations. Run only tests with any of '
295 'the given annotations. An annotation can be either a key or a '
296 'key-values pair. A test that has no annotation is considered '
297 '"SmallTest".'))
jama47ca85c2014-12-03 18:38:07298 argument_group.add_argument(
[email protected]fbe29322013-07-09 09:03:26299 '-E', '--exclude-annotation', dest='exclude_annotation_str',
300 help=('Comma-separated list of annotations. Exclude tests with these '
301 'annotations.'))
jama47ca85c2014-12-03 18:38:07302 argument_group.add_argument(
jbudorickcbcc115d2014-09-18 17:50:59303 '--screenshot', dest='screenshot_failures', action='store_true',
304 help='Capture screenshots of test failures')
jama47ca85c2014-12-03 18:38:07305 argument_group.add_argument(
jbudorickcbcc115d2014-09-18 17:50:59306 '--save-perf-json', action='store_true',
307 help='Saves the JSON file for each UI Perf test.')
jama47ca85c2014-12-03 18:38:07308 argument_group.add_argument(
jbudorickcbcc115d2014-09-18 17:50:59309 '--official-build', action='store_true', help='Run official build tests.')
jama47ca85c2014-12-03 18:38:07310 argument_group.add_argument(
jbudorickcbcc115d2014-09-18 17:50:59311 '--test_data', '--test-data', action='append', default=[],
312 help=('Each instance defines a directory of test data that should be '
313 'copied to the target(s) before running the tests. The argument '
314 'should be of the form <target>:<source>, <target> is relative to '
315 'the device data directory, and <source> is relative to the '
316 'chromium build directory.'))
davileen98efad12015-01-05 19:48:21317 argument_group.add_argument(
318 '--disable-dalvik-asserts', dest='set_asserts', action='store_false',
319 default=True, help='Removes the dalvik.vm.enableassertions property')
320
[email protected]fbe29322013-07-09 09:03:26321
322
jama47ca85c2014-12-03 18:38:07323def ProcessJavaTestOptions(args):
[email protected]fbe29322013-07-09 09:03:26324 """Processes options/arguments and populates |options| with defaults."""
325
jama47ca85c2014-12-03 18:38:07326 # TODO(jbudorick): Handle most of this function in argparse.
327 if args.annotation_str:
328 args.annotations = args.annotation_str.split(',')
329 elif args.test_filter:
330 args.annotations = []
[email protected]fbe29322013-07-09 09:03:26331 else:
jama47ca85c2014-12-03 18:38:07332 args.annotations = ['Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
333 'EnormousTest', 'IntegrationTest']
[email protected]fbe29322013-07-09 09:03:26334
jama47ca85c2014-12-03 18:38:07335 if args.exclude_annotation_str:
336 args.exclude_annotations = args.exclude_annotation_str.split(',')
[email protected]fbe29322013-07-09 09:03:26337 else:
jama47ca85c2014-12-03 18:38:07338 args.exclude_annotations = []
[email protected]fbe29322013-07-09 09:03:26339
[email protected]fbe29322013-07-09 09:03:26340
jama47ca85c2014-12-03 18:38:07341def AddInstrumentationTestOptions(parser):
342 """Adds Instrumentation test options to |parser|."""
[email protected]fbe29322013-07-09 09:03:26343
jama47ca85c2014-12-03 18:38:07344 parser.usage = '%(prog)s [options]'
[email protected]fbe29322013-07-09 09:03:26345
jama47ca85c2014-12-03 18:38:07346 group = parser.add_argument_group('Instrumentation Test Options')
347 AddJavaTestOptions(group)
[email protected]fbe29322013-07-09 09:03:26348
jama47ca85c2014-12-03 18:38:07349 java_or_python_group = group.add_mutually_exclusive_group()
350 java_or_python_group.add_argument(
351 '-j', '--java-only', action='store_false',
352 dest='run_python_tests', default=True, help='Run only the Java tests.')
353 java_or_python_group.add_argument(
354 '-p', '--python-only', action='store_false',
355 dest='run_java_tests', default=True,
356 help='Run only the host-driven tests.')
357
358 group.add_argument('--host-driven-root',
359 help='Root of the host-driven tests.')
360 group.add_argument('-w', '--wait_debugger', dest='wait_for_debugger',
361 action='store_true',
362 help='Wait for debugger.')
jbudorick911be58d2015-01-13 02:51:06363 group.add_argument('--apk-under-test', dest='apk_under_test',
364 help=('the name of the apk under test.'))
jama47ca85c2014-12-03 18:38:07365 group.add_argument('--test-apk', dest='test_apk', required=True,
366 help=('The name of the apk containing the tests '
367 '(without the .apk extension; '
368 'e.g. "ContentShellTest").'))
mikecasee7258622015-09-29 13:47:35369 group.add_argument('--additional-apk', action='append',
mikecase8c4ab302015-09-29 17:03:29370 dest='additional_apks', default=[],
mikecasee7258622015-09-29 13:47:35371 help='Additional apk that must be installed on '
372 'the device when the tests are run')
jama47ca85c2014-12-03 18:38:07373 group.add_argument('--coverage-dir',
374 help=('Directory in which to place all generated '
375 'EMMA coverage files.'))
376 group.add_argument('--device-flags', dest='device_flags', default='',
377 help='The relative filepath to a file containing '
378 'command-line flags to set on the device')
jbudorick911be58d2015-01-13 02:51:06379 group.add_argument('--device-flags-file', default='',
380 help='The relative filepath to a file containing '
381 'command-line flags to set on the device')
jama47ca85c2014-12-03 18:38:07382 group.add_argument('--isolate_file_path',
383 '--isolate-file-path',
384 dest='isolate_file_path',
385 help='.isolate file path to override the default '
386 'path')
mlliud7f9fe92015-06-15 19:36:56387 group.add_argument('--delete-stale-data', dest='delete_stale_data',
388 action='store_true',
389 help='Delete stale test data on the device.')
jbudorickede49722015-11-25 05:16:34390 group.add_argument('--timeout-scale', type=float,
391 help='Factor by which timeouts should be scaled.')
jama47ca85c2014-12-03 18:38:07392
393 AddCommonOptions(parser)
394 AddDeviceOptions(parser)
rnephewe416dff2015-01-21 21:26:37395 AddRemoteDeviceOptions(parser)
[email protected]fbe29322013-07-09 09:03:26396
397
jama47ca85c2014-12-03 18:38:07398def ProcessInstrumentationOptions(args):
[email protected]2a684222013-08-01 16:59:22399 """Processes options/arguments and populate |options| with defaults.
400
401 Args:
jama47ca85c2014-12-03 18:38:07402 args: argparse.Namespace object.
[email protected]2a684222013-08-01 16:59:22403
404 Returns:
405 An InstrumentationOptions named tuple which contains all options relevant to
406 instrumentation tests.
407 """
[email protected]fbe29322013-07-09 09:03:26408
jama47ca85c2014-12-03 18:38:07409 ProcessJavaTestOptions(args)
[email protected]fbe29322013-07-09 09:03:26410
jama47ca85c2014-12-03 18:38:07411 if not args.host_driven_root:
412 args.run_python_tests = False
[email protected]37ee0c792013-08-06 19:10:13413
jbudorick9ef3f9552015-10-20 22:58:33414 if os.path.exists(args.test_apk):
415 args.test_apk_path = args.test_apk
416 args.test_apk, _ = os.path.splitext(os.path.basename(args.test_apk))
417 else:
418 args.test_apk_path = os.path.join(
419 constants.GetOutDirectory(),
420 constants.SDK_BUILD_APKS_DIR,
421 '%s.apk' % args.test_apk)
422
jama47ca85c2014-12-03 18:38:07423 args.test_apk_jar_path = os.path.join(
[email protected]ae68d4a2013-09-24 21:57:15424 constants.GetOutDirectory(),
425 constants.SDK_BUILD_TEST_JAVALIB_DIR,
jbudorick9ef3f9552015-10-20 22:58:33426 '%s.jar' % args.test_apk)
yusufo72c598c02015-07-16 23:40:20427 args.test_support_apk_path = '%sSupport%s' % (
428 os.path.splitext(args.test_apk_path))
[email protected]5e2f3f62014-06-23 12:31:46429
jama47ca85c2014-12-03 18:38:07430 args.test_runner = apk_helper.GetInstrumentationName(args.test_apk_path)
[email protected]5e2f3f62014-06-23 12:31:46431
jama47ca85c2014-12-03 18:38:07432 # TODO(jbudorick): Get rid of InstrumentationOptions.
[email protected]2a684222013-08-01 16:59:22433 return instrumentation_test_options.InstrumentationOptions(
jama47ca85c2014-12-03 18:38:07434 args.tool,
jama47ca85c2014-12-03 18:38:07435 args.annotations,
436 args.exclude_annotations,
437 args.test_filter,
438 args.test_data,
439 args.save_perf_json,
440 args.screenshot_failures,
441 args.wait_for_debugger,
442 args.coverage_dir,
443 args.test_apk,
444 args.test_apk_path,
445 args.test_apk_jar_path,
446 args.test_runner,
447 args.test_support_apk_path,
448 args.device_flags,
davileen98efad12015-01-05 19:48:21449 args.isolate_file_path,
mlliud7f9fe92015-06-15 19:36:56450 args.set_asserts,
jbudorickede49722015-11-25 05:16:34451 args.delete_stale_data,
452 args.timeout_scale)
[email protected]2a684222013-08-01 16:59:22453
[email protected]fbe29322013-07-09 09:03:26454
jama47ca85c2014-12-03 18:38:07455def AddUIAutomatorTestOptions(parser):
456 """Adds UI Automator test options to |parser|."""
[email protected]fbe29322013-07-09 09:03:26457
jama47ca85c2014-12-03 18:38:07458 group = parser.add_argument_group('UIAutomator Test Options')
459 AddJavaTestOptions(group)
460 group.add_argument(
461 '--package', required=True, choices=constants.PACKAGE_INFO.keys(),
462 metavar='PACKAGE', help='Package under test.')
463 group.add_argument(
464 '--test-jar', dest='test_jar', required=True,
[email protected]fbe29322013-07-09 09:03:26465 help=('The name of the dexed jar containing the tests (without the '
466 '.dex.jar extension). Alternatively, this can be a full path '
467 'to the jar.'))
468
jama47ca85c2014-12-03 18:38:07469 AddCommonOptions(parser)
470 AddDeviceOptions(parser)
[email protected]fbe29322013-07-09 09:03:26471
472
jama47ca85c2014-12-03 18:38:07473def AddJUnitTestOptions(parser):
474 """Adds junit test options to |parser|."""
jbudorick9a6b7b332014-09-20 00:01:07475
jama47ca85c2014-12-03 18:38:07476 group = parser.add_argument_group('JUnit Test Options')
477 group.add_argument(
478 '-s', '--test-suite', dest='test_suite', required=True,
jbudorick9a6b7b332014-09-20 00:01:07479 help=('JUnit test suite to run.'))
jama47ca85c2014-12-03 18:38:07480 group.add_argument(
jbudorick9a6b7b332014-09-20 00:01:07481 '-f', '--test-filter', dest='test_filter',
482 help='Filters tests googletest-style.')
jama47ca85c2014-12-03 18:38:07483 group.add_argument(
jbudorick9a6b7b332014-09-20 00:01:07484 '--package-filter', dest='package_filter',
485 help='Filters tests by package.')
jama47ca85c2014-12-03 18:38:07486 group.add_argument(
jbudorick9a6b7b332014-09-20 00:01:07487 '--runner-filter', dest='runner_filter',
488 help='Filters tests by runner class. Must be fully qualified.')
jama47ca85c2014-12-03 18:38:07489 group.add_argument(
490 '--sdk-version', dest='sdk_version', type=int,
jbudorick9a6b7b332014-09-20 00:01:07491 help='The Android SDK version.')
jama47ca85c2014-12-03 18:38:07492 AddCommonOptions(parser)
jbudorick9a6b7b332014-09-20 00:01:07493
494
jama47ca85c2014-12-03 18:38:07495def AddMonkeyTestOptions(parser):
496 """Adds monkey test options to |parser|."""
jbudorick9a6b7b332014-09-20 00:01:07497
jama47ca85c2014-12-03 18:38:07498 group = parser.add_argument_group('Monkey Test Options')
499 group.add_argument(
500 '--package', required=True, choices=constants.PACKAGE_INFO.keys(),
501 metavar='PACKAGE', help='Package under test.')
502 group.add_argument(
503 '--event-count', default=10000, type=int,
504 help='Number of events to generate (default: %(default)s).')
505 group.add_argument(
[email protected]3dbdfa42013-08-08 01:08:14506 '--category', default='',
[email protected]fb81b982013-08-09 00:07:12507 help='A list of allowed categories.')
jama47ca85c2014-12-03 18:38:07508 group.add_argument(
509 '--throttle', default=100, type=int,
510 help='Delay between events (ms) (default: %(default)s). ')
511 group.add_argument(
512 '--seed', type=int,
[email protected]3dbdfa42013-08-08 01:08:14513 help=('Seed value for pseudo-random generator. Same seed value generates '
514 'the same sequence of events. Seed is randomized by default.'))
jama47ca85c2014-12-03 18:38:07515 group.add_argument(
[email protected]3dbdfa42013-08-08 01:08:14516 '--extra-args', default='',
jama47ca85c2014-12-03 18:38:07517 help=('String of other args to pass to the command verbatim.'))
[email protected]3dbdfa42013-08-08 01:08:14518
jama47ca85c2014-12-03 18:38:07519 AddCommonOptions(parser)
520 AddDeviceOptions(parser)
[email protected]3dbdfa42013-08-08 01:08:14521
jama47ca85c2014-12-03 18:38:07522def ProcessMonkeyTestOptions(args):
[email protected]3dbdfa42013-08-08 01:08:14523 """Processes all monkey test options.
524
525 Args:
jama47ca85c2014-12-03 18:38:07526 args: argparse.Namespace object.
[email protected]3dbdfa42013-08-08 01:08:14527
528 Returns:
529 A MonkeyOptions named tuple which contains all options relevant to
530 monkey tests.
531 """
jama47ca85c2014-12-03 18:38:07532 # TODO(jbudorick): Handle this directly in argparse with nargs='+'
533 category = args.category
[email protected]3dbdfa42013-08-08 01:08:14534 if category:
jama47ca85c2014-12-03 18:38:07535 category = args.category.split(',')
[email protected]3dbdfa42013-08-08 01:08:14536
jama47ca85c2014-12-03 18:38:07537 # TODO(jbudorick): Get rid of MonkeyOptions.
[email protected]3dbdfa42013-08-08 01:08:14538 return monkey_test_options.MonkeyOptions(
jama47ca85c2014-12-03 18:38:07539 args.verbose_count,
540 args.package,
541 args.event_count,
[email protected]3dbdfa42013-08-08 01:08:14542 category,
jama47ca85c2014-12-03 18:38:07543 args.throttle,
544 args.seed,
545 args.extra_args)
[email protected]3dbdfa42013-08-08 01:08:14546
rnephew5c499782014-12-12 19:08:55547def AddUirobotTestOptions(parser):
548 """Adds uirobot test options to |option_parser|."""
549 group = parser.add_argument_group('Uirobot Test Options')
550
rnephewefe44b42015-02-04 04:45:15551 group.add_argument('--app-under-test', required=True,
552 help='APK to run tests on.')
rnephew5c499782014-12-12 19:08:55553 group.add_argument(
mikecaseafa43842015-10-19 23:04:12554 '--repeat', dest='repeat', type=int, default=0,
555 help='Number of times to repeat the uirobot test.')
556 group.add_argument(
rnephew5c499782014-12-12 19:08:55557 '--minutes', default=5, type=int,
jbudorick676b1202015-02-06 22:02:27558 help='Number of minutes to run uirobot test [default: %(default)s].')
rnephew5c499782014-12-12 19:08:55559
560 AddCommonOptions(parser)
561 AddDeviceOptions(parser)
562 AddRemoteDeviceOptions(parser)
[email protected]3dbdfa42013-08-08 01:08:14563
jama47ca85c2014-12-03 18:38:07564def AddPerfTestOptions(parser):
565 """Adds perf test options to |parser|."""
[email protected]ec3170b2013-08-14 14:39:47566
jama47ca85c2014-12-03 18:38:07567 group = parser.add_argument_group('Perf Test Options')
[email protected]ec3170b2013-08-14 14:39:47568
jama47ca85c2014-12-03 18:38:07569 class SingleStepAction(argparse.Action):
570 def __call__(self, parser, namespace, values, option_string=None):
571 if values and not namespace.single_step:
572 parser.error('single step command provided, '
573 'but --single-step not specified.')
574 elif namespace.single_step and not values:
575 parser.error('--single-step specified, '
576 'but no single step command provided.')
577 setattr(namespace, self.dest, values)
578
579 step_group = group.add_mutually_exclusive_group(required=True)
580 # TODO(jbudorick): Revise --single-step to use argparse.REMAINDER.
581 # This requires removing "--" from client calls.
582 step_group.add_argument(
583 '--single-step', action='store_true',
[email protected]def4bce2013-11-12 12:59:52584 help='Execute the given command with retries, but only print the result '
585 'for the "most successful" round.')
jama47ca85c2014-12-03 18:38:07586 step_group.add_argument(
[email protected]181a5c92013-09-06 17:11:46587 '--steps',
[email protected]def4bce2013-11-12 12:59:52588 help='JSON file containing the list of commands to run.')
jama47ca85c2014-12-03 18:38:07589 step_group.add_argument(
590 '--print-step',
591 help='The name of a previously executed perf step to print.')
592
593 group.add_argument(
peterbd4e73d2014-12-03 15:47:36594 '--output-json-list',
595 help='Write a simple list of names from --steps into the given file.')
jama47ca85c2014-12-03 18:38:07596 group.add_argument(
peterbd4e73d2014-12-03 15:47:36597 '--collect-chartjson-data',
598 action='store_true',
599 help='Cache the chartjson output from each step for later use.')
jama47ca85c2014-12-03 18:38:07600 group.add_argument(
peterbd4e73d2014-12-03 15:47:36601 '--output-chartjson-data',
602 default='',
603 help='Write out chartjson into the given file.')
jama47ca85c2014-12-03 18:38:07604 group.add_argument(
perezju67cf7f12015-09-29 11:39:05605 '--get-output-dir-archive', metavar='FILENAME',
606 help='Write the chached output directory archived by a step into the'
607 ' given ZIP file.')
608 group.add_argument(
jama47ca85c2014-12-03 18:38:07609 '--flaky-steps',
610 help=('A JSON file containing steps that are flaky '
611 'and will have its exit code ignored.'))
612 group.add_argument(
[email protected]181a5c92013-09-06 17:11:46613 '--no-timeout', action='store_true',
614 help=('Do not impose a timeout. Each perf step is responsible for '
615 'implementing the timeout logic.'))
jama47ca85c2014-12-03 18:38:07616 group.add_argument(
[email protected]650487c2013-09-30 11:40:49617 '-f', '--test-filter',
618 help=('Test filter (will match against the names listed in --steps).'))
jama47ca85c2014-12-03 18:38:07619 group.add_argument(
620 '--dry-run', action='store_true',
[email protected]650487c2013-09-30 11:40:49621 help='Just print the steps without executing.')
jbudorick5cfff872015-07-01 18:46:13622 # Uses 0.1 degrees C because that's what Android does.
623 group.add_argument(
624 '--max-battery-temp', type=int,
625 help='Only start tests when the battery is at or below the given '
626 'temperature (0.1 C)')
jama47ca85c2014-12-03 18:38:07627 group.add_argument('single_step_command', nargs='*', action=SingleStepAction,
628 help='If --single-step is specified, the command to run.')
rnephewdde05da82015-07-09 20:31:01629 group.add_argument('--min-battery-level', type=int,
630 help='Only starts tests when the battery is charged above '
631 'given level.')
jama47ca85c2014-12-03 18:38:07632 AddCommonOptions(parser)
633 AddDeviceOptions(parser)
[email protected]ec3170b2013-08-14 14:39:47634
635
jama47ca85c2014-12-03 18:38:07636def ProcessPerfTestOptions(args):
[email protected]ec3170b2013-08-14 14:39:47637 """Processes all perf test options.
638
639 Args:
jama47ca85c2014-12-03 18:38:07640 args: argparse.Namespace object.
[email protected]ec3170b2013-08-14 14:39:47641
642 Returns:
643 A PerfOptions named tuple which contains all options relevant to
644 perf tests.
645 """
jama47ca85c2014-12-03 18:38:07646 # TODO(jbudorick): Move single_step handling down into the perf tests.
647 if args.single_step:
648 args.single_step = ' '.join(args.single_step_command)
649 # TODO(jbudorick): Get rid of PerfOptions.
[email protected]ec3170b2013-08-14 14:39:47650 return perf_test_options.PerfOptions(
jama47ca85c2014-12-03 18:38:07651 args.steps, args.flaky_steps, args.output_json_list,
652 args.print_step, args.no_timeout, args.test_filter,
653 args.dry_run, args.single_step, args.collect_chartjson_data,
perezju67cf7f12015-09-29 11:39:05654 args.output_chartjson_data, args.get_output_dir_archive,
655 args.max_battery_temp, args.min_battery_level)
[email protected]ec3170b2013-08-14 14:39:47656
657
jama47ca85c2014-12-03 18:38:07658def AddPythonTestOptions(parser):
659 group = parser.add_argument_group('Python Test Options')
660 group.add_argument(
661 '-s', '--suite', dest='suite_name', metavar='SUITE_NAME',
662 choices=constants.PYTHON_UNIT_TEST_SUITES.keys(),
663 help='Name of the test suite to run.')
664 AddCommonOptions(parser)
jbudorick256fd532014-10-24 01:50:13665
666
jama47ca85c2014-12-03 18:38:07667def _RunLinkerTests(args, devices):
[email protected]6b6abac6d2013-10-03 11:56:38668 """Subcommand of RunTestsCommands which runs linker tests."""
jama47ca85c2014-12-03 18:38:07669 runner_factory, tests = linker_setup.Setup(args, devices)
[email protected]6b6abac6d2013-10-03 11:56:38670
671 results, exit_code = test_dispatcher.RunTests(
672 tests, runner_factory, devices, shard=True, test_timeout=60,
jama47ca85c2014-12-03 18:38:07673 num_retries=args.num_retries)
[email protected]6b6abac6d2013-10-03 11:56:38674
675 report_results.LogFull(
676 results=results,
677 test_type='Linker test',
[email protected]93c9f9b2014-02-10 16:19:22678 test_package='ChromiumLinkerTest')
[email protected]6b6abac6d2013-10-03 11:56:38679
jama47ca85c2014-12-03 18:38:07680 if args.json_results_file:
jbudorickeb7ea71c2015-09-28 16:40:20681 json_results.GenerateJsonResultsFile([results], args.json_results_file)
jbudorickb8c42072014-12-01 18:07:54682
[email protected]6b6abac6d2013-10-03 11:56:38683 return exit_code
684
685
jama47ca85c2014-12-03 18:38:07686def _RunInstrumentationTests(args, devices):
[email protected]6bc1bda22013-07-19 22:08:37687 """Subcommand of RunTestsCommands which runs instrumentation tests."""
jbudorick58b4d362015-09-08 16:44:59688 logging.info('_RunInstrumentationTests(%s, %s)', str(args), str(devices))
[email protected]6bc1bda22013-07-19 22:08:37689
jama47ca85c2014-12-03 18:38:07690 instrumentation_options = ProcessInstrumentationOptions(args)
691
692 if len(devices) > 1 and args.wait_for_debugger:
[email protected]f7148dd42013-08-20 14:24:57693 logging.warning('Debugger can not be sharded, using first available device')
694 devices = devices[:1]
695
[email protected]6bc1bda22013-07-19 22:08:37696 results = base_test_result.TestRunResults()
697 exit_code = 0
698
jama47ca85c2014-12-03 18:38:07699 if args.run_java_tests:
jbudorickeb7ea71c2015-09-28 16:40:20700 java_runner_factory, java_tests = instrumentation_setup.Setup(
mikecase526d68e2014-11-19 20:02:05701 instrumentation_options, devices)
jbudorickeb7ea71c2015-09-28 16:40:20702 else:
703 java_runner_factory = None
704 java_tests = None
[email protected]6bc1bda22013-07-19 22:08:37705
jama47ca85c2014-12-03 18:38:07706 if args.run_python_tests:
jbudorickeb7ea71c2015-09-28 16:40:20707 py_runner_factory, py_tests = host_driven_setup.InstrumentationSetup(
jama47ca85c2014-12-03 18:38:07708 args.host_driven_root, args.official_build,
[email protected]37ee0c792013-08-06 19:10:13709 instrumentation_options)
jbudorickeb7ea71c2015-09-28 16:40:20710 else:
711 py_runner_factory = None
712 py_tests = None
[email protected]37ee0c792013-08-06 19:10:13713
jbudorickeb7ea71c2015-09-28 16:40:20714 results = []
715 repetitions = (xrange(args.repeat + 1) if args.repeat >= 0
716 else itertools.count())
alexandermonta3f03bf2015-12-02 18:56:45717
718 def _escalate_code(old, new):
719 for x in (constants.INFRA_EXIT_CODE,
720 constants.ERROR_EXIT_CODE,
721 constants.WARNING_EXIT_CODE):
722 if x in (old, new):
723 return x
724 return 0
725
jbudorickeb7ea71c2015-09-28 16:40:20726 for _ in repetitions:
727 iteration_results = base_test_result.TestRunResults()
728 if java_tests:
[email protected]34020022013-08-06 23:35:34729 test_results, test_exit_code = test_dispatcher.RunTests(
jbudorickeb7ea71c2015-09-28 16:40:20730 java_tests, java_runner_factory, devices, shard=True,
731 test_timeout=None, num_retries=args.num_retries)
732 iteration_results.AddTestRunResults(test_results)
[email protected]6bc1bda22013-07-19 22:08:37733
alexandermonta3f03bf2015-12-02 18:56:45734 exit_code = _escalate_code(exit_code, test_exit_code)
[email protected]6bc1bda22013-07-19 22:08:37735
jbudorickeb7ea71c2015-09-28 16:40:20736 if py_tests:
737 test_results, test_exit_code = test_dispatcher.RunTests(
738 py_tests, py_runner_factory, devices, shard=True, test_timeout=None,
739 num_retries=args.num_retries)
740 iteration_results.AddTestRunResults(test_results)
[email protected]4f777ca2014-08-08 01:45:59741
alexandermonta3f03bf2015-12-02 18:56:45742 exit_code = _escalate_code(exit_code, test_exit_code)
jbudorickeb7ea71c2015-09-28 16:40:20743
744 results.append(iteration_results)
745 report_results.LogFull(
746 results=iteration_results,
747 test_type='Instrumentation',
748 test_package=os.path.basename(args.test_apk),
749 annotation=args.annotations,
750 flakiness_server=args.flakiness_dashboard_server)
[email protected]6bc1bda22013-07-19 22:08:37751
alexandermonta3f03bf2015-12-02 18:56:45752 if args.break_on_failure and exit_code in (constants.ERROR_EXIT_CODE,
753 constants.INFRA_EXIT_CODE):
754 break
755
jama47ca85c2014-12-03 18:38:07756 if args.json_results_file:
757 json_results.GenerateJsonResultsFile(results, args.json_results_file)
jbudorickb8c42072014-12-01 18:07:54758
[email protected]6bc1bda22013-07-19 22:08:37759 return exit_code
760
761
jama47ca85c2014-12-03 18:38:07762def _RunJUnitTests(args):
jbudorick9a6b7b332014-09-20 00:01:07763 """Subcommand of RunTestsCommand which runs junit tests."""
jama47ca85c2014-12-03 18:38:07764 runner_factory, tests = junit_setup.Setup(args)
mikecasec638a072015-04-01 16:35:35765 results, exit_code = junit_dispatcher.RunTests(tests, runner_factory)
766
767 report_results.LogFull(
768 results=results,
769 test_type='JUnit',
770 test_package=args.test_suite)
771
mikecase572401b2015-04-09 02:28:57772 if args.json_results_file:
jbudorickeb7ea71c2015-09-28 16:40:20773 json_results.GenerateJsonResultsFile([results], args.json_results_file)
mikecase572401b2015-04-09 02:28:57774
jbudorick9a6b7b332014-09-20 00:01:07775 return exit_code
776
777
jama47ca85c2014-12-03 18:38:07778def _RunMonkeyTests(args, devices):
[email protected]3dbdfa42013-08-08 01:08:14779 """Subcommand of RunTestsCommands which runs monkey tests."""
jama47ca85c2014-12-03 18:38:07780 monkey_options = ProcessMonkeyTestOptions(args)
[email protected]3dbdfa42013-08-08 01:08:14781
782 runner_factory, tests = monkey_setup.Setup(monkey_options)
783
784 results, exit_code = test_dispatcher.RunTests(
[email protected]181a5c92013-09-06 17:11:46785 tests, runner_factory, devices, shard=False, test_timeout=None,
jama47ca85c2014-12-03 18:38:07786 num_retries=args.num_retries)
[email protected]3dbdfa42013-08-08 01:08:14787
788 report_results.LogFull(
789 results=results,
790 test_type='Monkey',
[email protected]14b3b1202013-08-15 22:25:28791 test_package='Monkey')
[email protected]3dbdfa42013-08-08 01:08:14792
jama47ca85c2014-12-03 18:38:07793 if args.json_results_file:
jbudorickeb7ea71c2015-09-28 16:40:20794 json_results.GenerateJsonResultsFile([results], args.json_results_file)
jbudorickb8c42072014-12-01 18:07:54795
[email protected]3dbdfa42013-08-08 01:08:14796 return exit_code
797
798
jbudorickdde688fb2015-08-27 03:00:17799def _RunPerfTests(args, active_devices):
[email protected]ec3170b2013-08-14 14:39:47800 """Subcommand of RunTestsCommands which runs perf tests."""
jama47ca85c2014-12-03 18:38:07801 perf_options = ProcessPerfTestOptions(args)
[email protected]61487ed2014-06-09 12:33:56802
803 # Just save a simple json with a list of test names.
804 if perf_options.output_json_list:
805 return perf_test_runner.OutputJsonList(
806 perf_options.steps, perf_options.output_json_list)
807
[email protected]ad32f312013-11-13 04:03:29808 # Just print the results from a single previously executed step.
[email protected]ec3170b2013-08-14 14:39:47809 if perf_options.print_step:
simonhatch9b9256d2015-01-07 18:03:42810 return perf_test_runner.PrintTestOutput(
perezju67cf7f12015-09-29 11:39:05811 perf_options.print_step, perf_options.output_chartjson_data,
812 perf_options.get_output_dir_archive)
[email protected]ec3170b2013-08-14 14:39:47813
jbudorickdde688fb2015-08-27 03:00:17814 runner_factory, tests, devices = perf_setup.Setup(
815 perf_options, active_devices)
[email protected]ec3170b2013-08-14 14:39:47816
[email protected]a72f0752014-06-03 23:52:34817 # shard=False means that each device will get the full list of tests
818 # and then each one will decide their own affinity.
819 # shard=True means each device will pop the next test available from a queue,
820 # which increases throughput but have no affinity.
[email protected]86184c7b2013-08-15 15:06:57821 results, _ = test_dispatcher.RunTests(
[email protected]a72f0752014-06-03 23:52:34822 tests, runner_factory, devices, shard=False, test_timeout=None,
jama47ca85c2014-12-03 18:38:07823 num_retries=args.num_retries)
[email protected]ec3170b2013-08-14 14:39:47824
825 report_results.LogFull(
826 results=results,
827 test_type='Perf',
[email protected]865a47a2013-08-16 14:01:12828 test_package='Perf')
[email protected]def4bce2013-11-12 12:59:52829
jama47ca85c2014-12-03 18:38:07830 if args.json_results_file:
jbudorickeb7ea71c2015-09-28 16:40:20831 json_results.GenerateJsonResultsFile([results], args.json_results_file)
jbudorickb8c42072014-12-01 18:07:54832
[email protected]def4bce2013-11-12 12:59:52833 if perf_options.single_step:
834 return perf_test_runner.PrintTestOutput('single_step')
835
[email protected]11ce8452014-02-17 10:55:03836 perf_test_runner.PrintSummary(tests)
837
[email protected]86184c7b2013-08-15 15:06:57838 # Always return 0 on the sharding stage. Individual tests exit_code
839 # will be returned on the print_step stage.
840 return 0
[email protected]ec3170b2013-08-14 14:39:47841
[email protected]3dbdfa42013-08-08 01:08:14842
jama47ca85c2014-12-03 18:38:07843def _RunPythonTests(args):
jbudorick256fd532014-10-24 01:50:13844 """Subcommand of RunTestsCommand which runs python unit tests."""
jama47ca85c2014-12-03 18:38:07845 suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name]
jbudorick256fd532014-10-24 01:50:13846 suite_path = suite_vars['path']
847 suite_test_modules = suite_vars['test_modules']
848
849 sys.path = [suite_path] + sys.path
850 try:
851 suite = unittest.TestSuite()
852 suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m)
853 for m in suite_test_modules)
jama47ca85c2014-12-03 18:38:07854 runner = unittest.TextTestRunner(verbosity=1+args.verbose_count)
jbudorick256fd532014-10-24 01:50:13855 return 0 if runner.run(suite).wasSuccessful() else 1
856 finally:
857 sys.path = sys.path[1:]
858
859
agrievea538a142015-10-09 15:45:56860def _GetAttachedDevices(blacklist_file, test_device, enable_cache):
[email protected]f7148dd42013-08-20 14:24:57861 """Get all attached devices.
862
863 Args:
agrievea538a142015-10-09 15:45:56864 blacklist_file: Path to device blacklist.
[email protected]f7148dd42013-08-20 14:24:57865 test_device: Name of a specific device to use.
agrievea538a142015-10-09 15:45:56866 enable_cache: Whether to enable checksum caching.
[email protected]f7148dd42013-08-20 14:24:57867
868 Returns:
869 A list of attached devices.
870 """
jbudoricka583ba32015-09-11 17:23:19871 blacklist = (device_blacklist.Blacklist(blacklist_file)
872 if blacklist_file
873 else None)
jbudorickdde688fb2015-08-27 03:00:17874
agrievea538a142015-10-09 15:45:56875 attached_devices = device_utils.DeviceUtils.HealthyDevices(
876 blacklist, enable_device_files_cache=enable_cache)
aberent6a02a6182015-04-29 11:07:55877 if test_device:
jbudorick4551d0dc2015-04-29 16:07:06878 test_device = [d for d in attached_devices if d == test_device]
879 if not test_device:
880 raise device_errors.DeviceUnreachableError(
881 'Did not find device %s among attached device. Attached devices: %s'
882 % (test_device, ', '.join(attached_devices)))
883 return test_device
aberent6a02a6182015-04-29 11:07:55884
jbudorick4551d0dc2015-04-29 16:07:06885 else:
886 if not attached_devices:
887 raise device_errors.NoDevicesError()
888 return sorted(attached_devices)
[email protected]f7148dd42013-08-20 14:24:57889
890
jbudorick58b4d362015-09-08 16:44:59891def RunTestsCommand(args, parser): # pylint: disable=too-many-return-statements
[email protected]fbe29322013-07-09 09:03:26892 """Checks test type and dispatches to the appropriate function.
893
894 Args:
jama47ca85c2014-12-03 18:38:07895 args: argparse.Namespace object.
896 parser: argparse.ArgumentParser object.
[email protected]fbe29322013-07-09 09:03:26897
898 Returns:
899 Integer indicated exit code.
[email protected]b3873892013-07-10 04:57:10900
901 Raises:
902 Exception: Unknown command name passed in, or an exception from an
903 individual test runner.
[email protected]fbe29322013-07-09 09:03:26904 """
jama47ca85c2014-12-03 18:38:07905 command = args.command
[email protected]fbe29322013-07-09 09:03:26906
jama47ca85c2014-12-03 18:38:07907 ProcessCommonOptions(args)
[email protected]d82f0252013-07-12 23:22:57908
jama47ca85c2014-12-03 18:38:07909 if args.enable_platform_mode:
rnephew5c499782014-12-12 19:08:55910 return RunTestsInPlatformMode(args, parser)
jbudorick66dc3722014-11-06 21:33:51911
[email protected]c0662e092013-11-12 11:51:25912 forwarder.Forwarder.RemoveHostLog()
[email protected]6b11583b2013-11-21 16:18:40913 if not ports.ResetTestServerPortAllocation():
914 raise Exception('Failed to reset test server port.')
[email protected]c0662e092013-11-12 11:51:25915
agrieve18930bd2015-10-09 17:41:42916 def get_devices():
917 return _GetAttachedDevices(args.blacklist_file, args.test_device,
918 args.enable_device_cache)
919
[email protected]fbe29322013-07-09 09:03:26920 if command == 'gtest':
jbudorick566592ab2015-09-21 15:32:47921 return RunTestsInPlatformMode(args, parser)
[email protected]6b6abac6d2013-10-03 11:56:38922 elif command == 'linker':
agrieve18930bd2015-10-09 17:41:42923 return _RunLinkerTests(args, get_devices())
[email protected]fbe29322013-07-09 09:03:26924 elif command == 'instrumentation':
agrieve18930bd2015-10-09 17:41:42925 return _RunInstrumentationTests(args, get_devices())
jbudorick9a6b7b332014-09-20 00:01:07926 elif command == 'junit':
jama47ca85c2014-12-03 18:38:07927 return _RunJUnitTests(args)
[email protected]3dbdfa42013-08-08 01:08:14928 elif command == 'monkey':
agrieve18930bd2015-10-09 17:41:42929 return _RunMonkeyTests(args, get_devices())
[email protected]ec3170b2013-08-14 14:39:47930 elif command == 'perf':
agrieve18930bd2015-10-09 17:41:42931 return _RunPerfTests(args, get_devices())
jbudorick256fd532014-10-24 01:50:13932 elif command == 'python':
jama47ca85c2014-12-03 18:38:07933 return _RunPythonTests(args)
[email protected]fbe29322013-07-09 09:03:26934 else:
[email protected]6bc1bda22013-07-19 22:08:37935 raise Exception('Unknown test type.')
[email protected]fbe29322013-07-09 09:03:26936
[email protected]fbe29322013-07-09 09:03:26937
jbudorick66dc3722014-11-06 21:33:51938_SUPPORTED_IN_PLATFORM_MODE = [
939 # TODO(jbudorick): Add support for more test types.
jbudorick911be58d2015-01-13 02:51:06940 'gtest',
941 'instrumentation',
942 'uirobot',
jbudorick66dc3722014-11-06 21:33:51943]
944
945
jama47ca85c2014-12-03 18:38:07946def RunTestsInPlatformMode(args, parser):
jbudorick66dc3722014-11-06 21:33:51947
jbudorick566592ab2015-09-21 15:32:47948 def infra_error(message):
949 parser.exit(status=constants.INFRA_EXIT_CODE, message=message)
jbudorickb9b0ada2015-09-17 22:52:58950
jbudorick566592ab2015-09-21 15:32:47951 if args.command not in _SUPPORTED_IN_PLATFORM_MODE:
952 infra_error('%s is not yet supported in platform mode' % args.command)
953
954 with environment_factory.CreateEnvironment(args, infra_error) as env:
955 with test_instance_factory.CreateTestInstance(args, infra_error) as test:
jbudorick66dc3722014-11-06 21:33:51956 with test_run_factory.CreateTestRun(
jbudorick566592ab2015-09-21 15:32:47957 args, env, test, infra_error) as test_run:
jbudorickeb7ea71c2015-09-28 16:40:20958 results = []
959 repetitions = (xrange(args.repeat + 1) if args.repeat >= 0
960 else itertools.count())
961 for _ in repetitions:
962 iteration_results = test_run.RunTests()
jbudorick66dc3722014-11-06 21:33:51963
jbudorickeb7ea71c2015-09-28 16:40:20964 if iteration_results is not None:
jbudorickd4f77982015-09-28 21:09:18965 results.append(iteration_results)
jbudorickeb7ea71c2015-09-28 16:40:20966 report_results.LogFull(
967 results=iteration_results,
968 test_type=test.TestType(),
969 test_package=test_run.TestPackage(),
970 annotation=getattr(args, 'annotations', None),
971 flakiness_server=getattr(args, 'flakiness_dashboard_server',
972 None))
alexandermonta3f03bf2015-12-02 18:56:45973 if args.break_on_failure and not iteration_results.DidRunPass():
974 break
jbudorick66dc3722014-11-06 21:33:51975
jama47ca85c2014-12-03 18:38:07976 if args.json_results_file:
jbudorickb8c42072014-12-01 18:07:54977 json_results.GenerateJsonResultsFile(
jama47ca85c2014-12-03 18:38:07978 results, args.json_results_file)
jbudorickb8c42072014-12-01 18:07:54979
jbudorickeb7ea71c2015-09-28 16:40:20980 return (0 if all(r.DidRunPass() for r in results)
981 else constants.ERROR_EXIT_CODE)
jbudorick66dc3722014-11-06 21:33:51982
983
jama47ca85c2014-12-03 18:38:07984CommandConfigTuple = collections.namedtuple(
985 'CommandConfigTuple',
986 ['add_options_func', 'help_txt'])
[email protected]fbe29322013-07-09 09:03:26987VALID_COMMANDS = {
jama47ca85c2014-12-03 18:38:07988 'gtest': CommandConfigTuple(
989 AddGTestOptions,
990 'googletest-based C++ tests'),
991 'instrumentation': CommandConfigTuple(
992 AddInstrumentationTestOptions,
993 'InstrumentationTestCase-based Java tests'),
jama47ca85c2014-12-03 18:38:07994 'junit': CommandConfigTuple(
995 AddJUnitTestOptions,
996 'JUnit4-based Java tests'),
997 'monkey': CommandConfigTuple(
998 AddMonkeyTestOptions,
999 "Tests based on Android's monkey"),
1000 'perf': CommandConfigTuple(
1001 AddPerfTestOptions,
1002 'Performance tests'),
1003 'python': CommandConfigTuple(
1004 AddPythonTestOptions,
1005 'Python tests based on unittest.TestCase'),
1006 'linker': CommandConfigTuple(
1007 AddLinkerTestOptions,
1008 'Linker tests'),
rnephew5c499782014-12-12 19:08:551009 'uirobot': CommandConfigTuple(
1010 AddUirobotTestOptions,
1011 'Uirobot test'),
jama47ca85c2014-12-03 18:38:071012}
[email protected]fbe29322013-07-09 09:03:261013
1014
[email protected]7c53a602014-03-24 16:21:441015def DumpThreadStacks(_signal, _frame):
[email protected]71aec4b2013-11-20 00:35:241016 for thread in threading.enumerate():
1017 reraiser_thread.LogThreadStack(thread)
[email protected]83bb8152013-11-19 15:02:211018
1019
[email protected]7c53a602014-03-24 16:21:441020def main():
[email protected]83bb8152013-11-19 15:02:211021 signal.signal(signal.SIGUSR1, DumpThreadStacks)
jama47ca85c2014-12-03 18:38:071022
1023 parser = argparse.ArgumentParser()
1024 command_parsers = parser.add_subparsers(title='test types',
1025 dest='command')
1026
1027 for test_type, config in sorted(VALID_COMMANDS.iteritems(),
1028 key=lambda x: x[0]):
1029 subparser = command_parsers.add_parser(
1030 test_type, usage='%(prog)s [options]', help=config.help_txt)
1031 config.add_options_func(subparser)
1032
1033 args = parser.parse_args()
mikecasee74051022015-02-26 23:08:221034
1035 try:
1036 return RunTestsCommand(args, parser)
1037 except base_error.BaseError as e:
1038 logging.exception('Error occurred.')
1039 if e.is_infra_error:
1040 return constants.INFRA_EXIT_CODE
mswecce6732015-06-06 00:31:331041 return constants.ERROR_EXIT_CODE
mikecasee74051022015-02-26 23:08:221042 except: # pylint: disable=W0702
1043 logging.exception('Unrecognized error occurred.')
1044 return constants.ERROR_EXIT_CODE
[email protected]fbe29322013-07-09 09:03:261045
[email protected]fbe29322013-07-09 09:03:261046
1047if __name__ == '__main__':
[email protected]7c53a602014-03-24 16:21:441048 sys.exit(main())