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

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

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

Powered by Google App Engine
This is Rietveld 408576698