Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: build/android/test_runner.py

Issue 2605083002: [android] Clean up test_runner.py arguments. (Closed)
Patch Set: mikecase comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/pylib/local/machine/local_machine_environment.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved. 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 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Runs all types of tests from one unified interface.""" 7 """Runs all types of tests from one unified interface."""
8 8
9 import argparse 9 import argparse
10 import collections 10 import collections
11 import contextlib 11 import contextlib
12 import itertools 12 import itertools
13 import logging 13 import logging
14 import os 14 import os
15 import signal 15 import signal
16 import sys 16 import sys
17 import threading 17 import threading
18 import traceback 18 import traceback
19 import unittest 19 import unittest
20 20
21 import devil_chromium 21 from pylib.constants import host_paths
22
23 if host_paths.DEVIL_PATH not in sys.path:
24 sys.path.append(host_paths.DEVIL_PATH)
25
22 from devil import base_error 26 from devil import base_error
23 from devil.android import device_blacklist
24 from devil.android import device_errors
25 from devil.android import device_utils
26 from devil.android import forwarder
27 from devil.android import ports
28 from devil.utils import reraiser_thread 27 from devil.utils import reraiser_thread
29 from devil.utils import run_tests_helper 28 from devil.utils import run_tests_helper
30 29
31 from pylib import constants 30 from pylib import constants
32 from pylib.base import base_test_result 31 from pylib.base import base_test_result
33 from pylib.base import environment_factory 32 from pylib.base import environment_factory
34 from pylib.base import test_instance_factory 33 from pylib.base import test_instance_factory
35 from pylib.base import test_run_factory 34 from pylib.base import test_run_factory
36 from pylib.constants import host_paths
37 from pylib.results import json_results 35 from pylib.results import json_results
38 from pylib.results import report_results 36 from pylib.results import report_results
39 37
40 from py_utils import contextlib_ext 38 from py_utils import contextlib_ext
41 39
42 40
43 _DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join( 41 _DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join(
44 host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json')) 42 host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json'))
45 43
46 44
45 def AddTestLauncherArgs(parser):
46 """Adds arguments mirroring //base/test/launcher.
47
48 Args:
49 parser: The parser to which arguments should be added.
50 Returns:
51 The given parser.
52 """
53 parser.add_argument(
54 '--test-launcher-retry-limit',
55 '--test_launcher_retry_limit',
56 '--num_retries', '--num-retries',
57 dest='num_retries', type=int, default=2,
58 help='Number of retries for a test before '
59 'giving up (default: %(default)s).')
60 parser.add_argument(
61 '--test-launcher-summary-output',
62 '--json-results-file',
63 dest='json_results_file', type=os.path.realpath,
64 help='If set, will dump results in JSON form '
65 'to specified file.')
66
67 return parser
68
69
70 def AddTracingOptions(parser):
71 # TODO(shenghuazhang): Move this into AddCommonOptions once it's supported
72 # for all test types.
73 parser.add_argument(
74 '--trace-output',
75 metavar='FILENAME', type=os.path.realpath,
76 help='Path to save test_runner trace data to.')
77
78
47 def AddCommonOptions(parser): 79 def AddCommonOptions(parser):
48 """Adds all common options to |parser|.""" 80 """Adds all common options to |parser|."""
49 81
50 group = parser.add_argument_group('Common Options')
51
52 default_build_type = os.environ.get('BUILDTYPE', 'Debug') 82 default_build_type = os.environ.get('BUILDTYPE', 'Debug')
53 83
54 debug_or_release_group = group.add_mutually_exclusive_group() 84 debug_or_release_group = parser.add_mutually_exclusive_group()
55 debug_or_release_group.add_argument( 85 debug_or_release_group.add_argument(
56 '--debug', action='store_const', const='Debug', dest='build_type', 86 '--debug',
87 action='store_const', const='Debug', dest='build_type',
57 default=default_build_type, 88 default=default_build_type,
58 help=('If set, run test suites under out/Debug. ' 89 help='If set, run test suites under out/Debug. '
59 'Default is env var BUILDTYPE or Debug.')) 90 'Default is env var BUILDTYPE or Debug.')
60 debug_or_release_group.add_argument( 91 debug_or_release_group.add_argument(
61 '--release', action='store_const', const='Release', dest='build_type', 92 '--release',
62 help=('If set, run test suites under out/Release. ' 93 action='store_const', const='Release', dest='build_type',
63 'Default is env var BUILDTYPE or Debug.')) 94 help='If set, run test suites under out/Release. '
95 'Default is env var BUILDTYPE or Debug.')
64 96
65 # TODO(jbudorick): Remove --build-directory once no bots use it. 97 parser.add_argument(
66 group.add_argument('--build-directory', dest='build_directory', 98 '--break-on-failure', '--break_on_failure',
67 help='DEPRECATED') 99 dest='break_on_failure', action='store_true',
68 group.add_argument('--output-directory', dest='output_directory', 100 help='Whether to break on failure.')
69 type=os.path.realpath,
70 help=('Path to the directory in which build files are'
71 ' located (must include build type). This will take'
72 ' precedence over --debug, --release and'
73 ' --build-directory'))
74 group.add_argument('--num_retries', '--num-retries',
75 '--test_launcher_retry_limit',
76 '--test-launcher-retry-limit',
77 dest='num_retries',
78 type=int, default=2,
79 help=('Number of retries for a test before '
80 'giving up (default: %(default)s).'))
81 group.add_argument('--repeat', '--gtest_repeat', '--gtest-repeat',
82 dest='repeat', type=int, default=0,
83 help='Number of times to repeat the specified set of '
84 'tests.')
85 group.add_argument('--break-on-failure', '--break_on_failure',
86 dest='break_on_failure', action='store_true',
87 help='Whether to break on failure.')
88 group.add_argument('-v',
89 '--verbose',
90 dest='verbose_count',
91 default=0,
92 action='count',
93 help='Verbose level (multiple times for more)')
94 group.add_argument('--flakiness-dashboard-server',
95 dest='flakiness_dashboard_server',
96 help=('Address of the server that is hosting the '
97 'Chrome for Android flakiness dashboard.'))
98 group.add_argument('--enable-platform-mode', action='store_true',
99 help=('Run the test scripts in platform mode, which '
100 'conceptually separates the test runner from the '
101 '"device" (local or remote, real or emulated) on '
102 'which the tests are running. [experimental]'))
103 group.add_argument('-e', '--environment', default='local',
104 choices=constants.VALID_ENVIRONMENTS,
105 help='Test environment to run in (default: %(default)s).')
106 group.add_argument('--adb-path', type=os.path.realpath,
107 help=('Specify the absolute path of the adb binary that '
108 'should be used.'))
109 group.add_argument('--json-results-file', '--test-launcher-summary-output',
110 dest='json_results_file', type=os.path.realpath,
111 help='If set, will dump results in JSON form '
112 'to specified file.')
113 group.add_argument('--trace-output', metavar='FILENAME',
114 type=os.path.realpath,
115 help='Path to save test_runner trace data to. This option '
116 'has been implemented for gtest, instrumentation '
117 'test and perf test.')
118 101
119 logcat_output_group = group.add_mutually_exclusive_group() 102 # TODO(jbudorick): Remove this once everything has switched to platform
120 logcat_output_group.add_argument( 103 # mode.
121 '--logcat-output-dir', type=os.path.realpath, 104 parser.add_argument(
122 help='If set, will dump logcats recorded during test run to directory. ' 105 '--enable-platform-mode',
123 'File names will be the device ids with timestamps.') 106 action='store_true',
124 logcat_output_group.add_argument( 107 help='Run the test scripts in platform mode, which '
125 '--logcat-output-file', type=os.path.realpath, 108 'conceptually separates the test runner from the '
126 help='If set, will merge logcats recorded during test run and dump them ' 109 '"device" (local or remote, real or emulated) on '
127 'to the specified file.') 110 'which the tests are running. [experimental]')
111
112 parser.add_argument(
113 '-e', '--environment',
114 default='local', choices=constants.VALID_ENVIRONMENTS,
115 help='Test environment to run in (default: %(default)s).')
128 116
129 class FastLocalDevAction(argparse.Action): 117 class FastLocalDevAction(argparse.Action):
130 def __call__(self, parser, namespace, values, option_string=None): 118 def __call__(self, parser, namespace, values, option_string=None):
131 namespace.verbose_count = max(namespace.verbose_count, 1) 119 namespace.verbose_count = max(namespace.verbose_count, 1)
132 namespace.num_retries = 0 120 namespace.num_retries = 0
133 namespace.enable_device_cache = True 121 namespace.enable_device_cache = True
134 namespace.enable_concurrent_adb = True 122 namespace.enable_concurrent_adb = True
135 namespace.skip_clear_data = True 123 namespace.skip_clear_data = True
136 namespace.extract_test_list_from_filter = True 124 namespace.extract_test_list_from_filter = True
137 125
138 group.add_argument('--fast-local-dev', type=bool, nargs=0, 126 parser.add_argument(
139 action=FastLocalDevAction, 127 '--fast-local-dev',
140 help='Alias for: --verbose --num-retries=0 ' 128 type=bool, nargs=0, action=FastLocalDevAction,
141 '--enable-device-cache --enable-concurrent-adb ' 129 help='Alias for: --verbose --num-retries=0 '
142 '--skip-clear-data --extract-test-list-from-filter') 130 '--enable-device-cache --enable-concurrent-adb '
131 '--skip-clear-data --extract-test-list-from-filter')
132
133 # TODO(jbudorick): Remove this once downstream bots have switched to
134 # api.test_results.
135 parser.add_argument(
136 '--flakiness-dashboard-server',
137 dest='flakiness_dashboard_server',
138 help=argparse.SUPPRESS)
139
140 parser.add_argument(
141 '--output-directory',
142 dest='output_directory', type=os.path.realpath,
143 help='Path to the directory in which build files are'
144 ' located (must include build type). This will take'
145 ' precedence over --debug and --release')
146 parser.add_argument(
147 '--repeat', '--gtest_repeat', '--gtest-repeat',
148 dest='repeat', type=int, default=0,
149 help='Number of times to repeat the specified set of tests.')
150 parser.add_argument(
151 '-v', '--verbose',
152 dest='verbose_count', default=0, action='count',
153 help='Verbose level (multiple times for more)')
154
155 AddTestLauncherArgs(parser)
156
143 157
144 def ProcessCommonOptions(args): 158 def ProcessCommonOptions(args):
145 """Processes and handles all common options.""" 159 """Processes and handles all common options."""
146 run_tests_helper.SetLogLevel(args.verbose_count) 160 run_tests_helper.SetLogLevel(args.verbose_count)
147 constants.SetBuildType(args.build_type) 161 constants.SetBuildType(args.build_type)
148 if args.build_directory:
149 constants.SetBuildDirectory(args.build_directory)
150 if args.output_directory: 162 if args.output_directory:
151 constants.SetOutputDirectory(args.output_directory) 163 constants.SetOutputDirectory(args.output_directory)
152 164
153 devil_chromium.Initialize(
154 output_directory=constants.GetOutDirectory(),
155 adb_path=args.adb_path)
156
157 # Some things such as Forwarder require ADB to be in the environment path.
158 adb_dir = os.path.dirname(constants.GetAdbPath())
159 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep):
160 os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
161
162 165
163 def AddDeviceOptions(parser): 166 def AddDeviceOptions(parser):
164 """Adds device options to |parser|.""" 167 """Adds device options to |parser|."""
165 group = parser.add_argument_group(title='Device Options') 168
166 group.add_argument('--tool', 169 parser = parser.add_argument_group('device arguments')
167 dest='tool', 170
168 help=('Run the test under a tool ' 171 parser.add_argument(
169 '(use --tool help to list them)')) 172 '--adb-path',
170 group.add_argument('-d', '--device', dest='test_device', 173 type=os.path.realpath,
171 help=('Target device for the test suite ' 174 help='Specify the absolute path of the adb binary that '
172 'to run on.')) 175 'should be used.')
173 group.add_argument('--blacklist-file', type=os.path.realpath, 176 parser.add_argument(
174 help='Device blacklist file.') 177 '--blacklist-file',
175 group.add_argument('--enable-device-cache', action='store_true', 178 type=os.path.realpath,
176 help='Cache device state to disk between runs') 179 help='Device blacklist file.')
177 group.add_argument('--enable-concurrent-adb', action='store_true', 180 parser.add_argument(
178 help='Run multiple adb commands at the same time, even ' 181 '-d', '--device',
179 'for the same device.') 182 dest='test_device',
180 group.add_argument('--skip-clear-data', action='store_true', 183 help='Target device for the test suite to run on.')
181 help='Do not wipe app data between tests. Use this to ' 184 parser.add_argument(
182 'speed up local development and never on bots ' 185 '--enable-concurrent-adb',
186 action='store_true',
187 help='Run multiple adb commands at the same time, even '
188 'for the same device.')
189 parser.add_argument(
190 '--enable-device-cache',
191 action='store_true',
192 help='Cache device state to disk between runs')
193 parser.add_argument(
194 '--skip-clear-data',
195 action='store_true',
196 help='Do not wipe app data between tests. Use this to '
197 'speed up local development and never on bots '
183 '(increases flakiness)') 198 '(increases flakiness)')
184 group.add_argument('--target-devices-file', type=os.path.realpath, 199 parser.add_argument(
185 help='Path to file with json list of device serials to ' 200 '--target-devices-file',
186 'run tests on. When not specified, all available ' 201 type=os.path.realpath,
187 'devices are used.') 202 help='Path to file with json list of device serials to '
203 'run tests on. When not specified, all available '
204 'devices are used.')
205 parser.add_argument(
206 '--tool',
207 dest='tool',
208 help='Run the test under a tool '
209 '(use --tool help to list them)')
210
211 logcat_output_group = parser.add_mutually_exclusive_group()
212 logcat_output_group.add_argument(
213 '--logcat-output-dir', type=os.path.realpath,
214 help='If set, will dump logcats recorded during test run to directory. '
215 'File names will be the device ids with timestamps.')
216 logcat_output_group.add_argument(
217 '--logcat-output-file', type=os.path.realpath,
218 help='If set, will merge logcats recorded during test run and dump them '
219 'to the specified file.')
188 220
189 221
190 def AddGTestOptions(parser): 222 def AddGTestOptions(parser):
191 """Adds gtest options to |parser|.""" 223 """Adds gtest options to |parser|."""
192 224
193 group = parser.add_argument_group('GTest Options') 225 parser = parser.add_argument_group('gtest arguments')
194 group.add_argument('-s', '--suite', dest='suite_name', 226
195 nargs='+', metavar='SUITE_NAME', required=True, 227 parser.add_argument(
196 help='Executable name of the test suite to run.') 228 '--app-data-file',
197 group.add_argument('--executable-dist-dir', type=os.path.realpath, 229 action='append', dest='app_data_files',
198 help="Path to executable's dist directory for native" 230 help='A file path relative to the app data directory '
199 " (non-apk) tests.") 231 'that should be saved to the host.')
200 group.add_argument('--test-apk-incremental-install-script', 232 parser.add_argument(
201 type=os.path.realpath, 233 '--app-data-file-dir',
202 help='Path to install script for the test apk.') 234 help='Host directory to which app data files will be'
203 group.add_argument('--gtest_also_run_disabled_tests', 235 ' saved. Used with --app-data-file.')
204 '--gtest-also-run-disabled-tests', 236 parser.add_argument(
205 dest='run_disabled', action='store_true', 237 '--delete-stale-data',
206 help='Also run disabled tests if applicable.') 238 dest='delete_stale_data', action='store_true',
207 group.add_argument('-a', '--test-arguments', dest='test_arguments', 239 help='Delete stale test data on the device.')
208 default='', 240 parser.add_argument(
209 help='Additional arguments to pass to the test.') 241 '--enable-xml-result-parsing',
210 group.add_argument('-t', '--shard-timeout', 242 action='store_true', help=argparse.SUPPRESS)
211 dest='shard_timeout', type=int, default=120, 243 parser.add_argument(
212 help='Timeout to wait for each test ' 244 '--executable-dist-dir',
213 '(default: %(default)s).') 245 type=os.path.realpath,
214 # TODO(jbudorick): Remove this after ensuring nothing else uses it. 246 help="Path to executable's dist directory for native"
215 group.add_argument('--isolate_file_path', 247 " (non-apk) tests.")
216 '--isolate-file-path', 248 parser.add_argument(
217 dest='isolate_file_path', 249 '--extract-test-list-from-filter',
218 type=os.path.realpath, 250 action='store_true',
219 help=argparse.SUPPRESS) 251 help='When a test filter is specified, and the list of '
220 group.add_argument('--runtime-deps-path', 252 'tests can be determined from it, skip querying the '
221 dest='runtime_deps_path', 253 'device for the list of all tests. Speeds up local '
222 type=os.path.realpath, 254 'development, but is not safe to use on bots ('
223 help='Runtime data dependency file from GN.') 255 'http://crbug.com/549214')
224 group.add_argument('--app-data-file', action='append', dest='app_data_files', 256 parser.add_argument(
225 help='A file path relative to the app data directory '
226 'that should be saved to the host.')
227 group.add_argument('--app-data-file-dir',
228 help='Host directory to which app data files will be'
229 ' saved. Used with --app-data-file.')
230 group.add_argument('--delete-stale-data', dest='delete_stale_data',
231 action='store_true',
232 help='Delete stale test data on the device.')
233 group.add_argument('--extract-test-list-from-filter',
234 action='store_true',
235 help='When a test filter is specified, and the list of '
236 'tests can be determined from it, skip querying the '
237 'device for the list of all tests. Speeds up local '
238 'development, but is not safe to use on bots ('
239 'http://crbug.com/549214')
240 group.add_argument('--enable-xml-result-parsing',
241 action='store_true',
242 help=argparse.SUPPRESS)
243 group.add_argument('--store-tombstones', dest='store_tombstones',
244 action='store_true',
245 help='Add tombstones in results if crash.')
246
247 filter_group = group.add_mutually_exclusive_group()
248 filter_group.add_argument('-f', '--gtest_filter', '--gtest-filter',
249 dest='test_filter',
250 help='googletest-style filter string.')
251 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file',
252 type=os.path.realpath,
253 help='Path to file that contains googletest-style '
254 'filter strings. See also '
255 '//testing/buildbot/filters/README.md.')
256
257 AddDeviceOptions(parser)
258 AddCommonOptions(parser)
259
260
261 def AddLinkerTestOptions(parser):
262 group = parser.add_argument_group('Linker Test Options')
263 group.add_argument('-f', '--gtest-filter', dest='test_filter',
264 help='googletest-style filter string.')
265 group.add_argument('--test-apk', type=os.path.realpath,
266 help='Path to the linker test APK.')
267 AddCommonOptions(parser)
268 AddDeviceOptions(parser)
269
270
271 def AddJavaTestOptions(argument_group):
272 """Adds the Java test options to |option_parser|."""
273
274 argument_group.add_argument(
275 '-f', '--test-filter', '--gtest_filter', '--gtest-filter',
276 dest='test_filter',
277 help=('Test filter (if not fully qualified, will run all matches).'))
278 argument_group.add_argument(
279 '-A', '--annotation', dest='annotation_str',
280 help=('Comma-separated list of annotations. Run only tests with any of '
281 'the given annotations. An annotation can be either a key or a '
282 'key-values pair. A test that has no annotation is considered '
283 '"SmallTest".'))
284 argument_group.add_argument(
285 '-E', '--exclude-annotation', dest='exclude_annotation_str',
286 help=('Comma-separated list of annotations. Exclude tests with these '
287 'annotations.'))
288 argument_group.add_argument(
289 '--screenshot-directory', dest='screenshot_dir', type=os.path.realpath,
290 help='Capture screenshots of test failures')
291 argument_group.add_argument(
292 '--save-perf-json', action='store_true',
293 help='Saves the JSON file for each UI Perf test.')
294 argument_group.add_argument(
295 '--official-build', action='store_true', help='Run official build tests.')
296 argument_group.add_argument(
297 '--disable-dalvik-asserts', dest='set_asserts', action='store_false',
298 default=True, help='Removes the dalvik.vm.enableassertions property')
299 argument_group.add_argument(
300 '--gtest_also_run_disabled_tests', '--gtest-also-run-disabled-tests', 257 '--gtest_also_run_disabled_tests', '--gtest-also-run-disabled-tests',
301 dest='run_disabled', action='store_true', 258 dest='run_disabled', action='store_true',
302 help='Also run disabled tests if applicable.') 259 help='Also run disabled tests if applicable.')
303 260 parser.add_argument(
304 261 '--runtime-deps-path',
305 262 dest='runtime_deps_path', type=os.path.realpath,
306 def ProcessJavaTestOptions(args): 263 help='Runtime data dependency file from GN.')
307 """Processes options/arguments and populates |options| with defaults.""" 264 parser.add_argument(
308 265 '-t', '--shard-timeout',
309 # TODO(jbudorick): Handle most of this function in argparse. 266 dest='shard_timeout', type=int, default=120,
310 if args.annotation_str: 267 help='Timeout to wait for each test (default: %(default)s).')
311 args.annotations = args.annotation_str.split(',') 268 parser.add_argument(
312 elif args.test_filter: 269 '--store-tombstones',
313 args.annotations = [] 270 dest='store_tombstones', action='store_true',
314 else: 271 help='Add tombstones in results if crash.')
315 args.annotations = ['SmallTest', 'MediumTest', 'LargeTest', 'EnormousTest', 272 parser.add_argument(
316 'IntegrationTest'] 273 '-s', '--suite',
317 274 dest='suite_name', nargs='+', metavar='SUITE_NAME', required=True,
318 if args.exclude_annotation_str: 275 help='Executable name of the test suite to run.')
319 args.exclude_annotations = args.exclude_annotation_str.split(',') 276 parser.add_argument(
320 else: 277 '--test-apk-incremental-install-script',
321 args.exclude_annotations = [] 278 type=os.path.realpath,
279 help='Path to install script for the test apk.')
280 parser.add_argument(
281 '-a', '--test-arguments',
282 dest='test_arguments', default='',
283 help='Additional arguments to pass to the test.')
284
285 filter_group = parser.add_mutually_exclusive_group()
286 filter_group.add_argument(
287 '-f', '--gtest_filter', '--gtest-filter',
288 dest='test_filter',
289 help='googletest-style filter string.')
290 filter_group.add_argument(
291 '--gtest-filter-file',
292 dest='test_filter_file', type=os.path.realpath,
293 help='Path to file that contains googletest-style filter strings. '
294 'See also //testing/buildbot/filters/README.md.')
322 295
323 296
324 def AddInstrumentationTestOptions(parser): 297 def AddInstrumentationTestOptions(parser):
325 """Adds Instrumentation test options to |parser|.""" 298 """Adds Instrumentation test options to |parser|."""
326 299
327 parser.usage = '%(prog)s [options]' 300 parser.add_argument_group('instrumentation arguments')
328 301
329 group = parser.add_argument_group('Instrumentation Test Options') 302 parser.add_argument(
330 AddJavaTestOptions(group) 303 '--additional-apk',
331 304 action='append', dest='additional_apks', default=[],
332 java_or_python_group = group.add_mutually_exclusive_group() 305 type=os.path.realpath,
333 java_or_python_group.add_argument( 306 help='Additional apk that must be installed on '
334 '-j', '--java-only', action='store_false', 307 'the device when the tests are run')
335 dest='run_python_tests', default=True, help='Run only the Java tests.') 308 parser.add_argument(
336 java_or_python_group.add_argument( 309 '-A', '--annotation',
337 '-p', '--python-only', action='store_false', 310 dest='annotation_str',
338 dest='run_java_tests', default=True, 311 help='Comma-separated list of annotations. Run only tests with any of '
339 help='DEPRECATED') 312 'the given annotations. An annotation can be either a key or a '
340 313 'key-values pair. A test that has no annotation is considered '
341 group.add_argument('--host-driven-root', 314 '"SmallTest".')
342 help='DEPRECATED')
343 group.add_argument('-w', '--wait_debugger', dest='wait_for_debugger',
344 action='store_true',
345 help='Wait for debugger.')
346 # TODO(jbudorick): Remove support for name-style APK specification once 315 # TODO(jbudorick): Remove support for name-style APK specification once
347 # bots are no longer doing it. 316 # bots are no longer doing it.
348 group.add_argument('--apk-under-test', 317 parser.add_argument(
349 help='Path or name of the apk under test.') 318 '--apk-under-test',
350 group.add_argument('--apk-under-test-incremental-install-script', 319 help='Path or name of the apk under test.')
351 help='Path to install script for the --apk-under-test.') 320 parser.add_argument(
352 group.add_argument('--test-apk', required=True, 321 '--coverage-dir',
353 help='Path or name of the apk containing the tests ' 322 type=os.path.realpath,
354 '(name is without the .apk extension; ' 323 help='Directory in which to place all generated '
355 'e.g. "ContentShellTest").') 324 'EMMA coverage files.')
356 group.add_argument('--test-jar', 325 parser.add_argument(
357 help='Path of jar containing test java files.') 326 '--delete-stale-data',
358 group.add_argument('--test-apk-incremental-install-script', 327 action='store_true', dest='delete_stale_data',
359 type=os.path.realpath, 328 help='Delete stale test data on the device.')
360 help='Path to install script for the --test-apk.') 329 parser.add_argument(
361 group.add_argument('--additional-apk', action='append', 330 '--device-flags',
362 dest='additional_apks', default=[], 331 dest='device_flags',
363 type=os.path.realpath, 332 type=os.path.realpath,
364 help='Additional apk that must be installed on ' 333 help='The relative filepath to a file containing '
365 'the device when the tests are run') 334 'command-line flags to set on the device')
366 group.add_argument('--coverage-dir', type=os.path.realpath, 335 parser.add_argument(
367 help=('Directory in which to place all generated ' 336 '--device-flags-file',
368 'EMMA coverage files.')) 337 type=os.path.realpath,
369 group.add_argument('--device-flags', dest='device_flags', 338 help='The relative filepath to a file containing '
370 type=os.path.realpath, 339 'command-line flags to set on the device')
371 help='The relative filepath to a file containing ' 340 parser.add_argument(
372 'command-line flags to set on the device') 341 '--disable-dalvik-asserts',
373 group.add_argument('--device-flags-file', type=os.path.realpath, 342 dest='set_asserts', action='store_false', default=True,
374 help='The relative filepath to a file containing ' 343 help='Removes the dalvik.vm.enableassertions property')
375 'command-line flags to set on the device') 344 parser.add_argument(
376 # TODO(jbudorick): Remove this after ensuring nothing else uses it. 345 '-E', '--exclude-annotation',
377 group.add_argument('--isolate_file_path', 346 dest='exclude_annotation_str',
378 '--isolate-file-path', 347 help='Comma-separated list of annotations. Exclude tests with these '
379 dest='isolate_file_path', 348 'annotations.')
380 type=os.path.realpath, 349 parser.add_argument(
381 help=argparse.SUPPRESS) 350 '-f', '--test-filter', '--gtest_filter', '--gtest-filter',
382 group.add_argument('--runtime-deps-path', 351 dest='test_filter',
383 dest='runtime_deps_path', 352 help='Test filter (if not fully qualified, will run all matches).')
384 type=os.path.realpath, 353 parser.add_argument(
385 help='Runtime data dependency file from GN.') 354 '--gtest_also_run_disabled_tests', '--gtest-also-run-disabled-tests',
386 group.add_argument('--delete-stale-data', dest='delete_stale_data', 355 dest='run_disabled', action='store_true',
387 action='store_true', 356 help='Also run disabled tests if applicable.')
388 help='Delete stale test data on the device.') 357 parser.add_argument(
389 group.add_argument('--timeout-scale', type=float, 358 '--regenerate-goldens',
390 help='Factor by which timeouts should be scaled.') 359 action='store_true', dest='regenerate_goldens',
391 group.add_argument('--strict-mode', dest='strict_mode', default='testing', 360 help='Causes the render tests to not fail when a check'
392 help='StrictMode command-line flag set on the device, ' 361 'fails or the golden image is missing but to render'
393 'death/testing to kill the process, off to stop ' 362 'the view and carry on.')
394 'checking, flash to flash only. Default testing.') 363 parser.add_argument(
395 group.add_argument('--regenerate-goldens', dest='regenerate_goldens', 364 '--runtime-deps-path',
396 action='store_true', 365 dest='runtime_deps_path', type=os.path.realpath,
397 help='Causes the render tests to not fail when a check' 366 help='Runtime data dependency file from GN.')
398 'fails or the golden image is missing but to render' 367 parser.add_argument(
399 'the view and carry on.') 368 '--save-perf-json',
400 group.add_argument('--store-tombstones', dest='store_tombstones', 369 action='store_true',
401 action='store_true', 370 help='Saves the JSON file for each UI Perf test.')
402 help='Add tombstones in results if crash.') 371 parser.add_argument(
403 group.add_argument('--shared-prefs-file', dest='shared_prefs_file', 372 '--screenshot-directory',
404 type=os.path.realpath, 373 dest='screenshot_dir', type=os.path.realpath,
405 help='The relative path to a file containing JSON list ' 374 help='Capture screenshots of test failures')
406 'of shared preference files to edit and how to do ' 375 parser.add_argument(
407 'so. Example list: ' 376 '--shared-prefs-file',
408 '[{' 377 dest='shared_prefs_file', type=os.path.realpath,
409 ' "package": "com.package.example",' 378 help='The relative path to a file containing JSON list of shared '
410 ' "filename": "ExampleSettings.xml",' 379 'preference files to edit and how to do so. Example list: '
411 ' "set": {' 380 '[{'
412 ' "boolean_key_in_xml": true,' 381 ' "package": "com.package.example",'
413 ' "string_key_in_xml": "string_value"' 382 ' "filename": "ExampleSettings.xml",'
414 ' },' 383 ' "set": {'
415 ' "remove": [' 384 ' "boolean_key_in_xml": true,'
416 ' "key_in_xml_to_remove"' 385 ' "string_key_in_xml": "string_value"'
417 ' ]' 386 ' },'
418 '}]') 387 ' "remove": ['
419 388 ' "key_in_xml_to_remove"'
420 AddCommonOptions(parser) 389 ' ]'
421 AddDeviceOptions(parser) 390 '}]')
391 parser.add_argument(
392 '--store-tombstones',
393 action='store_true', dest='store_tombstones',
394 help='Add tombstones in results if crash.')
395 parser.add_argument(
396 '--strict-mode',
397 dest='strict_mode', default='testing',
398 help='StrictMode command-line flag set on the device, '
399 'death/testing to kill the process, off to stop '
400 'checking, flash to flash only. (default: %(default)s)')
401 parser.add_argument(
402 '--test-apk',
403 required=True,
404 help='Path or name of the apk containing the tests.')
405 parser.add_argument(
406 '--test-jar',
407 help='Path of jar containing test java files.')
408 parser.add_argument(
409 '--timeout-scale',
410 type=float,
411 help='Factor by which timeouts should be scaled.')
412 parser.add_argument(
413 '-w', '--wait_debugger',
414 action='store_true', dest='wait_for_debugger',
415 help='Wait for debugger.')
416
417 # These arguments are suppressed from the help text because they should
418 # only ever be specified by an intermediate script.
419 parser.add_argument(
420 '--apk-under-test-incremental-install-script',
421 help=argparse.SUPPRESS)
422 parser.add_argument(
423 '--test-apk-incremental-install-script',
424 type=os.path.realpath,
425 help=argparse.SUPPRESS)
422 426
423 427
424 def AddJUnitTestOptions(parser): 428 def AddJUnitTestOptions(parser):
425 """Adds junit test options to |parser|.""" 429 """Adds junit test options to |parser|."""
426 430
427 group = parser.add_argument_group('JUnit Test Options') 431 parser = parser.add_argument_group('junit arguments')
428 group.add_argument( 432
429 '-s', '--test-suite', dest='test_suite', required=True, 433 parser.add_argument(
430 help=('JUnit test suite to run.')) 434 '--coverage-dir',
431 group.add_argument( 435 dest='coverage_dir', type=os.path.realpath,
432 '-f', '--test-filter', dest='test_filter', 436 help='Directory to store coverage info.')
437 parser.add_argument(
438 '--package-filter',
439 dest='package_filter',
440 help='Filters tests by package.')
441 parser.add_argument(
442 '--runner-filter',
443 dest='runner_filter',
444 help='Filters tests by runner class. Must be fully qualified.')
445 parser.add_argument(
446 '-f', '--test-filter',
447 dest='test_filter',
433 help='Filters tests googletest-style.') 448 help='Filters tests googletest-style.')
434 group.add_argument( 449 parser.add_argument(
435 '--package-filter', dest='package_filter', 450 '-s', '--test-suite',
436 help='Filters tests by package.') 451 dest='test_suite', required=True,
437 group.add_argument( 452 help='JUnit test suite to run.')
438 '--runner-filter', dest='runner_filter', 453
439 help='Filters tests by runner class. Must be fully qualified.') 454
440 group.add_argument( 455 def AddLinkerTestOptions(parser):
441 '--coverage-dir', dest='coverage_dir', type=os.path.realpath, 456
442 help='Directory to store coverage info.') 457 parser.add_argument_group('linker arguments')
443 AddCommonOptions(parser) 458
459 parser.add_argument(
460 '-f', '--gtest-filter',
461 dest='test_filter',
462 help='googletest-style filter string.')
463 parser.add_argument(
464 '--test-apk',
465 type=os.path.realpath,
466 help='Path to the linker test APK.')
444 467
445 468
446 def AddMonkeyTestOptions(parser): 469 def AddMonkeyTestOptions(parser):
447 """Adds monkey test options to |parser|.""" 470 """Adds monkey test options to |parser|."""
448 471
449 group = parser.add_argument_group('Monkey Test Options') 472 parser = parser.add_argument_group('monkey arguments')
450 group.add_argument( 473
451 '--browser', required=True, choices=constants.PACKAGE_INFO.keys(), 474 parser.add_argument(
475 '--browser',
476 required=True, choices=constants.PACKAGE_INFO.keys(),
452 metavar='BROWSER', help='Browser under test.') 477 metavar='BROWSER', help='Browser under test.')
453 group.add_argument( 478 parser.add_argument(
454 '--event-count', default=10000, type=int, 479 '--category',
455 help='Number of events to generate (default: %(default)s).') 480 nargs='*', dest='categories', default=[],
456 group.add_argument(
457 '--category', nargs='*', dest='categories', default=[],
458 help='A list of allowed categories. Monkey will only visit activities ' 481 help='A list of allowed categories. Monkey will only visit activities '
459 'that are listed with one of the specified categories.') 482 'that are listed with one of the specified categories.')
460 group.add_argument( 483 parser.add_argument(
461 '--throttle', default=100, type=int, 484 '--event-count',
462 help='Delay between events (ms) (default: %(default)s). ') 485 default=10000, type=int,
463 group.add_argument( 486 help='Number of events to generate (default: %(default)s).')
464 '--seed', type=int, 487 parser.add_argument(
488 '--seed',
489 type=int,
465 help='Seed value for pseudo-random generator. Same seed value generates ' 490 help='Seed value for pseudo-random generator. Same seed value generates '
466 'the same sequence of events. Seed is randomized by default.') 491 'the same sequence of events. Seed is randomized by default.')
467 AddCommonOptions(parser) 492 parser.add_argument(
468 AddDeviceOptions(parser) 493 '--throttle',
494 default=100, type=int,
495 help='Delay between events (ms) (default: %(default)s). ')
469 496
470 497
471 def AddPerfTestOptions(parser): 498 def AddPerfTestOptions(parser):
472 """Adds perf test options to |parser|.""" 499 """Adds perf test options to |parser|."""
473 500
474 group = parser.add_argument_group('Perf Test Options') 501 parser = parser.add_argument_group('perf arguments')
475 502
476 class SingleStepAction(argparse.Action): 503 class SingleStepAction(argparse.Action):
477 def __call__(self, parser, namespace, values, option_string=None): 504 def __call__(self, parser, namespace, values, option_string=None):
478 if values and not namespace.single_step: 505 if values and not namespace.single_step:
479 parser.error('single step command provided, ' 506 parser.error('single step command provided, '
480 'but --single-step not specified.') 507 'but --single-step not specified.')
481 elif namespace.single_step and not values: 508 elif namespace.single_step and not values:
482 parser.error('--single-step specified, ' 509 parser.error('--single-step specified, '
483 'but no single step command provided.') 510 'but no single step command provided.')
484 setattr(namespace, self.dest, values) 511 setattr(namespace, self.dest, values)
485 512
486 step_group = group.add_mutually_exclusive_group(required=True) 513 step_group = parser.add_mutually_exclusive_group(required=True)
487 # TODO(jbudorick): Revise --single-step to use argparse.REMAINDER. 514 # TODO(jbudorick): Revise --single-step to use argparse.REMAINDER.
488 # This requires removing "--" from client calls. 515 # This requires removing "--" from client calls.
489 step_group.add_argument( 516 step_group.add_argument(
490 '--single-step', action='store_true', 517 '--print-step',
518 help='The name of a previously executed perf step to print.')
519 step_group.add_argument(
520 '--single-step',
521 action='store_true',
491 help='Execute the given command with retries, but only print the result ' 522 help='Execute the given command with retries, but only print the result '
492 'for the "most successful" round.') 523 'for the "most successful" round.')
493 step_group.add_argument( 524 step_group.add_argument(
494 '--steps', 525 '--steps',
495 help='JSON file containing the list of commands to run.') 526 help='JSON file containing the list of commands to run.')
496 step_group.add_argument(
497 '--print-step',
498 help='The name of a previously executed perf step to print.')
499 527
500 group.add_argument( 528 parser.add_argument(
501 '--output-json-list', type=os.path.realpath, 529 '--collect-chartjson-data',
530 action='store_true',
531 help='Cache the telemetry chartjson output from each step for later use.')
532 parser.add_argument(
533 '--collect-json-data',
534 action='store_true',
535 help='Cache the telemetry JSON output from each step for later use.')
536 parser.add_argument(
537 '--dry-run',
538 action='store_true',
539 help='Just print the steps without executing.')
540 parser.add_argument(
541 '--flaky-steps',
542 type=os.path.realpath,
543 help='A JSON file containing steps that are flaky '
544 'and will have its exit code ignored.')
545 # TODO(rnephew): Remove this when everything moves to new option in platform
546 # mode.
547 parser.add_argument(
548 '--get-output-dir-archive',
549 metavar='FILENAME', type=os.path.realpath,
550 help='Write the cached output directory archived by a step into the'
551 ' given ZIP file.')
552 parser.add_argument(
553 '--known-devices-file',
554 help='Path to known device list.')
555 # Uses 0.1 degrees C because that's what Android does.
556 parser.add_argument(
557 '--max-battery-temp',
558 type=int,
559 help='Only start tests when the battery is at or below the given '
560 'temperature (0.1 C)')
561 parser.add_argument(
562 '--min-battery-level',
563 type=int,
564 help='Only starts tests when the battery is charged above '
565 'given level.')
566 parser.add_argument(
567 '--no-timeout',
568 action='store_true',
569 help='Do not impose a timeout. Each perf step is responsible for '
570 'implementing the timeout logic.')
571 parser.add_argument(
572 '--output-chartjson-data',
573 type=os.path.realpath,
574 help='Writes telemetry chartjson formatted output into the given file.')
575 parser.add_argument(
576 '--output-dir-archive-path',
577 metavar='FILENAME', type=os.path.realpath,
578 help='Write the cached output directory archived by a step into the'
579 ' given ZIP file.')
580 parser.add_argument(
581 '--output-json-data',
582 type=os.path.realpath,
583 help='Writes telemetry JSON formatted output into the given file.')
584 parser.add_argument(
585 '--output-json-list',
586 type=os.path.realpath,
502 help='Writes a JSON list of information for each --steps into the given ' 587 help='Writes a JSON list of information for each --steps into the given '
503 'file. Information includes runtime and device affinity for each ' 588 'file. Information includes runtime and device affinity for each '
504 '--steps.') 589 '--steps.')
505 group.add_argument( 590 parser.add_argument(
506 '--collect-chartjson-data', 591 '-f', '--test-filter',
592 help='Test filter (will match against the names listed in --steps).')
593 parser.add_argument(
594 '--write-buildbot-json',
507 action='store_true', 595 action='store_true',
508 help='Cache the telemetry chartjson output from each step for later use.') 596 help='Whether to output buildbot json.')
509 group.add_argument( 597
510 '--output-chartjson-data', 598 parser.add_argument(
511 type=os.path.realpath, 599 'single_step_command',
512 help='Writes telemetry chartjson formatted output into the given file.') 600 nargs='*', action=SingleStepAction,
513 group.add_argument(
514 '--collect-json-data',
515 action='store_true',
516 help='Cache the telemetry JSON output from each step for later use.')
517 group.add_argument(
518 '--output-json-data',
519 type=os.path.realpath,
520 help='Writes telemetry JSON formatted output into the given file.')
521 # TODO(rnephew): Remove this when everything moves to new option in platform
522 # mode.
523 group.add_argument(
524 '--get-output-dir-archive', metavar='FILENAME', type=os.path.realpath,
525 help='Write the cached output directory archived by a step into the'
526 ' given ZIP file.')
527 group.add_argument(
528 '--output-dir-archive-path', metavar='FILENAME', type=os.path.realpath,
529 help='Write the cached output directory archived by a step into the'
530 ' given ZIP file.')
531 group.add_argument(
532 '--flaky-steps', type=os.path.realpath,
533 help=('A JSON file containing steps that are flaky '
534 'and will have its exit code ignored.'))
535 group.add_argument(
536 '--no-timeout', action='store_true',
537 help=('Do not impose a timeout. Each perf step is responsible for '
538 'implementing the timeout logic.'))
539 group.add_argument(
540 '-f', '--test-filter',
541 help=('Test filter (will match against the names listed in --steps).'))
542 group.add_argument(
543 '--dry-run', action='store_true',
544 help='Just print the steps without executing.')
545 # Uses 0.1 degrees C because that's what Android does.
546 group.add_argument(
547 '--max-battery-temp', type=int,
548 help='Only start tests when the battery is at or below the given '
549 'temperature (0.1 C)')
550 group.add_argument(
551 'single_step_command', nargs='*', action=SingleStepAction,
552 help='If --single-step is specified, the command to run.') 601 help='If --single-step is specified, the command to run.')
553 group.add_argument(
554 '--min-battery-level', type=int,
555 help='Only starts tests when the battery is charged above '
556 'given level.')
557 group.add_argument('--known-devices-file', help='Path to known device list.')
558 group.add_argument(
559 '--write-buildbot-json', action='store_true',
560 help='Whether to output buildbot json.')
561 AddCommonOptions(parser)
562 AddDeviceOptions(parser)
563 602
564 603
565 def AddPythonTestOptions(parser): 604 def AddPythonTestOptions(parser):
566 group = parser.add_argument_group('Python Test Options') 605
567 group.add_argument( 606 parser = parser.add_argument_group('python arguments')
568 '-s', '--suite', dest='suite_name', metavar='SUITE_NAME', 607
608 parser.add_argument(
609 '-s', '--suite',
610 dest='suite_name', metavar='SUITE_NAME',
569 choices=constants.PYTHON_UNIT_TEST_SUITES.keys(), 611 choices=constants.PYTHON_UNIT_TEST_SUITES.keys(),
570 help='Name of the test suite to run.') 612 help='Name of the test suite to run.')
571 AddCommonOptions(parser)
572 613
573 614
574 def _RunPythonTests(args): 615 def _RunPythonTests(args):
575 """Subcommand of RunTestsCommand which runs python unit tests.""" 616 """Subcommand of RunTestsCommand which runs python unit tests."""
576 suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name] 617 suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name]
577 suite_path = suite_vars['path'] 618 suite_path = suite_vars['path']
578 suite_test_modules = suite_vars['test_modules'] 619 suite_test_modules = suite_vars['test_modules']
579 620
580 sys.path = [suite_path] + sys.path 621 sys.path = [suite_path] + sys.path
581 try: 622 try:
582 suite = unittest.TestSuite() 623 suite = unittest.TestSuite()
583 suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m) 624 suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m)
584 for m in suite_test_modules) 625 for m in suite_test_modules)
585 runner = unittest.TextTestRunner(verbosity=1+args.verbose_count) 626 runner = unittest.TextTestRunner(verbosity=1+args.verbose_count)
586 return 0 if runner.run(suite).wasSuccessful() else 1 627 return 0 if runner.run(suite).wasSuccessful() else 1
587 finally: 628 finally:
588 sys.path = sys.path[1:] 629 sys.path = sys.path[1:]
589 630
590 631
591 def _GetAttachedDevices(blacklist_file, test_device, enable_cache, num_retries):
592 """Get all attached devices.
593
594 Args:
595 blacklist_file: Path to device blacklist.
596 test_device: Name of a specific device to use.
597 enable_cache: Whether to enable checksum caching.
598
599 Returns:
600 A list of attached devices.
601 """
602 blacklist = (device_blacklist.Blacklist(blacklist_file)
603 if blacklist_file
604 else None)
605
606 attached_devices = device_utils.DeviceUtils.HealthyDevices(
607 blacklist, enable_device_files_cache=enable_cache,
608 default_retries=num_retries)
609 if test_device:
610 test_device = [d for d in attached_devices if d == test_device]
611 if not test_device:
612 raise device_errors.DeviceUnreachableError(
613 'Did not find device %s among attached device. Attached devices: %s'
614 % (test_device, ', '.join(attached_devices)))
615 return test_device
616
617 else:
618 if not attached_devices:
619 raise device_errors.NoDevicesError()
620 return sorted(attached_devices)
621
622
623 _DEFAULT_PLATFORM_MODE_TESTS = ['gtest', 'instrumentation', 'junit', 632 _DEFAULT_PLATFORM_MODE_TESTS = ['gtest', 'instrumentation', 'junit',
624 'linker', 'monkey', 'perf'] 633 'linker', 'monkey', 'perf']
625 634
626 635
627 def RunTestsCommand(args): # pylint: disable=too-many-return-statements 636 def RunTestsCommand(args):
628 """Checks test type and dispatches to the appropriate function. 637 """Checks test type and dispatches to the appropriate function.
629 638
630 Args: 639 Args:
631 args: argparse.Namespace object. 640 args: argparse.Namespace object.
632 641
633 Returns: 642 Returns:
634 Integer indicated exit code. 643 Integer indicated exit code.
635 644
636 Raises: 645 Raises:
637 Exception: Unknown command name passed in, or an exception from an 646 Exception: Unknown command name passed in, or an exception from an
638 individual test runner. 647 individual test runner.
639 """ 648 """
640 command = args.command 649 command = args.command
641 650
642 ProcessCommonOptions(args) 651 ProcessCommonOptions(args)
643 logging.info('command: %s', ' '.join(sys.argv)) 652 logging.info('command: %s', ' '.join(sys.argv))
644 if args.enable_platform_mode or command in _DEFAULT_PLATFORM_MODE_TESTS: 653 if args.enable_platform_mode or command in _DEFAULT_PLATFORM_MODE_TESTS:
645 return RunTestsInPlatformMode(args) 654 return RunTestsInPlatformMode(args)
646 655
647 forwarder.Forwarder.RemoveHostLog()
648 if not ports.ResetTestServerPortAllocation():
649 raise Exception('Failed to reset test server port.')
650
651 # pylint: disable=protected-access
652 if os.path.exists(ports._TEST_SERVER_PORT_LOCKFILE):
653 os.unlink(ports._TEST_SERVER_PORT_LOCKFILE)
654 # pylint: enable=protected-access
655
656 if command == 'python': 656 if command == 'python':
657 return _RunPythonTests(args) 657 return _RunPythonTests(args)
658 else: 658 else:
659 raise Exception('Unknown test type.') 659 raise Exception('Unknown test type.')
660 660
661 661
662 _SUPPORTED_IN_PLATFORM_MODE = [ 662 _SUPPORTED_IN_PLATFORM_MODE = [
663 # TODO(jbudorick): Add support for more test types. 663 # TODO(jbudorick): Add support for more test types.
664 'gtest', 664 'gtest',
665 'instrumentation', 665 'instrumentation',
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 str(tot_tests), 791 str(tot_tests),
792 str(iteration_count)) 792 str(iteration_count))
793 793
794 if args.command == 'perf' and (args.steps or args.single_step): 794 if args.command == 'perf' and (args.steps or args.single_step):
795 return 0 795 return 0
796 796
797 return (0 if all(r.DidRunPass() for r in all_iteration_results) 797 return (0 if all(r.DidRunPass() for r in all_iteration_results)
798 else constants.ERROR_EXIT_CODE) 798 else constants.ERROR_EXIT_CODE)
799 799
800 800
801 CommandConfigTuple = collections.namedtuple(
802 'CommandConfigTuple',
803 ['add_options_func', 'help_txt'])
804 VALID_COMMANDS = {
805 'gtest': CommandConfigTuple(
806 AddGTestOptions,
807 'googletest-based C++ tests'),
808 'instrumentation': CommandConfigTuple(
809 AddInstrumentationTestOptions,
810 'InstrumentationTestCase-based Java tests'),
811 'junit': CommandConfigTuple(
812 AddJUnitTestOptions,
813 'JUnit4-based Java tests'),
814 'monkey': CommandConfigTuple(
815 AddMonkeyTestOptions,
816 "Tests based on Android's monkey"),
817 'perf': CommandConfigTuple(
818 AddPerfTestOptions,
819 'Performance tests'),
820 'python': CommandConfigTuple(
821 AddPythonTestOptions,
822 'Python tests based on unittest.TestCase'),
823 'linker': CommandConfigTuple(
824 AddLinkerTestOptions,
825 'Linker tests'),
826 }
827
828
829 def DumpThreadStacks(_signal, _frame): 801 def DumpThreadStacks(_signal, _frame):
830 for thread in threading.enumerate(): 802 for thread in threading.enumerate():
831 reraiser_thread.LogThreadStack(thread) 803 reraiser_thread.LogThreadStack(thread)
832 804
833 805
834 def main(): 806 def main():
835 signal.signal(signal.SIGUSR1, DumpThreadStacks) 807 signal.signal(signal.SIGUSR1, DumpThreadStacks)
836 808
837 parser = argparse.ArgumentParser() 809 parser = argparse.ArgumentParser()
838 command_parsers = parser.add_subparsers(title='test types', 810 command_parsers = parser.add_subparsers(
839 dest='command') 811 title='test types', dest='command')
840 812
841 for test_type, config in sorted(VALID_COMMANDS.iteritems(), 813 subp = command_parsers.add_parser(
842 key=lambda x: x[0]): 814 'gtest',
843 subparser = command_parsers.add_parser( 815 help='googletest-based C++ tests')
844 test_type, usage='%(prog)s [options]', help=config.help_txt) 816 AddCommonOptions(subp)
845 config.add_options_func(subparser) 817 AddDeviceOptions(subp)
818 AddGTestOptions(subp)
819 AddTracingOptions(subp)
820
821 subp = command_parsers.add_parser(
822 'instrumentation',
823 help='InstrumentationTestCase-based Java tests')
824 AddCommonOptions(subp)
825 AddDeviceOptions(subp)
826 AddInstrumentationTestOptions(subp)
827 AddTracingOptions(subp)
828
829 subp = command_parsers.add_parser(
830 'junit',
831 help='JUnit4-based Java tests')
832 AddCommonOptions(subp)
833 AddJUnitTestOptions(subp)
834
835 subp = command_parsers.add_parser(
836 'linker',
837 help='linker tests')
838 AddCommonOptions(subp)
839 AddDeviceOptions(subp)
840 AddLinkerTestOptions(subp)
841
842 subp = command_parsers.add_parser(
843 'monkey',
844 help="tests based on Android's monkey command")
845 AddCommonOptions(subp)
846 AddDeviceOptions(subp)
847 AddMonkeyTestOptions(subp)
848
849 subp = command_parsers.add_parser(
850 'perf',
851 help='performance tests')
852 AddCommonOptions(subp)
853 AddDeviceOptions(subp)
854 AddPerfTestOptions(subp)
855 AddTracingOptions(subp)
856
857 subp = command_parsers.add_parser(
858 'python',
859 help='python tests based on unittest.TestCase')
860 AddCommonOptions(subp)
861 AddPythonTestOptions(subp)
846 862
847 args = parser.parse_args() 863 args = parser.parse_args()
848 864
849 try: 865 try:
850 return RunTestsCommand(args) 866 return RunTestsCommand(args)
851 except base_error.BaseError as e: 867 except base_error.BaseError as e:
852 logging.exception('Error occurred.') 868 logging.exception('Error occurred.')
853 if e.is_infra_error: 869 if e.is_infra_error:
854 return constants.INFRA_EXIT_CODE 870 return constants.INFRA_EXIT_CODE
855 return constants.ERROR_EXIT_CODE 871 return constants.ERROR_EXIT_CODE
856 except: # pylint: disable=W0702 872 except: # pylint: disable=W0702
857 logging.exception('Unrecognized error occurred.') 873 logging.exception('Unrecognized error occurred.')
858 return constants.ERROR_EXIT_CODE 874 return constants.ERROR_EXIT_CODE
859 875
860 876
861 if __name__ == '__main__': 877 if __name__ == '__main__':
862 sys.exit(main()) 878 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/pylib/local/machine/local_machine_environment.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698