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

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

Issue 15942016: Creates a new test running script test_runner.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: A few more updates from code review Created 7 years, 6 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/utils/test_options_parser.py ('k') | build/android/run_browser_tests.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Runs all types of tests from one unified interface.
8
9 Types of tests supported:
10 1. GTest native unit tests (gtests)
11 Example: ./run_all_tests.py gtests -s android_webview_unittests
12 2. ContentBrowser unit tests (content_browsertests)
13 Example: ./run_all_tests.py content_browsertests
14 3. Instrumentation tests (instrumentation): Both Python host-driven and
15 Java instrumentation tests are run by default. Use --python_only or
16 --java_only to select one or the other.
17 Example: ./run_all_tests.py instrumentation -I
18 --test-apk=ChromiumTestShellTest
19 4. UIAutomator tests (uiautomator): Both Python host-driven and Java
20 UIAutomator tests are run by default. Use --python_only or --java_only to
21 select one or the other.
22 Example: ./run_all_tests.py uiautomator
23 --test-jar=chromium_testshell_uiautomator_tests
24 --package-name=org.chromium.chrome.testshell
25
26 TODO(gkanwar):
27 * Add options to run Monkey tests.
28 """
29
30 import optparse
31 import os
32 import sys
33
34 from pylib import cmd_helper
35 from pylib import constants
36 from pylib import ports
37 from pylib.browsertests import dispatch as browsertests_dispatch
38 from pylib.gtest import dispatch as gtest_dispatch
39 from pylib.host_driven import run_python_tests as python_dispatch
40 from pylib.instrumentation import dispatch as instrumentation_dispatch
41 from pylib.uiautomator import dispatch as uiautomator_dispatch
42 from pylib.utils import emulator
43 from pylib.utils import run_tests_helper
44
45 _SDK_OUT_DIR = os.path.join(constants.DIR_SOURCE_ROOT, 'out')
46 VALID_TEST_TYPES = ['gtests', 'content_browsertests', 'instrumentation',
47 'uiautomator']
48
49
50 def ProcessTestTypeArg(options, args, errorf):
51 """Processes that the first arg is a valid test type keyword."""
52 if len(args) < 2:
53 errorf('You must specify a test type. Options are: ' +
craigdh 2013/06/17 22:37:05 Let's stick a newline in here before "Options". Th
gkanwar 2013/06/20 20:48:47 Done.
54 ', '.join(VALID_TEST_TYPES))
55 if args[1] not in VALID_TEST_TYPES:
56 errorf('Invalid test type. The test type must be one of: ' +
craigdh 2013/06/17 22:37:05 ditto
gkanwar 2013/06/20 20:48:47 Done.
57 ', '.join(VALID_TEST_TYPES))
58 options.test_type = args[1]
59
60
61 def AddBuildTypeOption(option_container):
62 """Adds the build type option to the OptionContainer."""
63 default_build_type = 'Debug'
64 if 'BUILDTYPE' in os.environ:
65 default_build_type = os.environ['BUILDTYPE']
66 option_container.add_option('--debug', action='store_const', const='Debug',
67 dest='build_type', default=default_build_type,
68 help=('If set, run test suites under out/Debug. '
69 'Default is env var BUILDTYPE or Debug.'))
70 option_container.add_option('--release', action='store_const',
71 const='Release', dest='build_type',
72 help=('If set, run test suites under out/Release.'
73 ' Default is env var BUILDTYPE or Debug.'))
74
75
76 def AddDeviceOptions(option_container):
77 """Adds all device-related options to the OptionContainer."""
78
79 option_container.add_option('-d', '--device', dest='test_device',
80 help=('Target device for the test suite '
81 'to run on.'))
82 option_container.add_option('-e', '--emulator', dest='use_emulator',
83 action='store_true',
84 help='Run tests in a new instance of emulator.')
85 option_container.add_option('-n', '--emulator-count',
86 type='int', default=1,
87 help=('Number of emulators to launch for '
88 'running the tests.'))
89 option_container.add_option('--abi', default='armeabi-v7a',
90 help='Platform of emulators to launch.')
91
92
93 def ProcessDeviceOptions(options):
94 """Processes emulator and device options."""
95 if options.use_emulator:
96 emulator.DeleteAllTempAVDs()
97
98
99 def AddCommonOptions(option_parser, default_timeout=60):
100 """Adds all common options to option_parser."""
101
102 option_group = optparse.OptionGroup(option_parser, 'Common Options',
craigdh 2013/06/17 22:37:05 Also print the list of valid test_type first thing
gkanwar 2013/06/20 20:48:47 Done.
103 'Options that apply to all test types.')
104
105 AddBuildTypeOption(option_group)
106
107 # --gtest_filter is DEPRECATED. Added for backwards compatibility
108 # with the syntax of the old run_tests.py script.
109 option_group.add_option('-f', '--test_filter', '--gtest_filter',
110 dest='test_filter',
111 help=('Test filter (if not fully qualified, '
112 'will run all matches).'))
113 option_group.add_option('--out-directory', dest='out_directory',
114 help=('Path to the out/ directory, irrespective of '
115 'the build type. Only for non-Chromium uses.'))
116 option_group.add_option('-t', dest='timeout',
craigdh 2013/06/17 22:37:05 Does this actually work for all test types?
gkanwar 2013/06/20 20:48:47 Ah, you're right, this only works for gtests at th
117 help='Timeout to wait for each test',
118 type='int',
119 default=default_timeout)
120 option_group.add_option('-c', dest='cleanup_test_files',
121 help='Cleanup test files on the device after run',
122 action='store_true')
123 option_group.add_option('--num_retries', dest='num_retries', type='int',
craigdh 2013/06/17 22:37:05 Does this actually work for all test types?
gkanwar 2013/06/20 20:48:47 This was used by all test types except UIAutomator
124 default=2,
125 help=('Number of retries for a test before '
126 'giving up.'))
127 option_group.add_option('-v',
128 '--verbose',
129 dest='verbose_count',
130 default=0,
131 action='count',
132 help='Verbose level (multiple times for more)')
133 profilers = ['devicestatsmonitor', 'chrometrace', 'dumpheap', 'smaps',
134 'traceview']
135 option_group.add_option('--profiler', dest='profilers', action='append',
136 choices=profilers,
137 help=('Profiling tool to run during test. Pass '
138 'multiple times to run multiple profilers. '
139 'Available profilers: %s' % profilers))
140 option_group.add_option('--tool',
craigdh 2013/06/17 22:37:05 Let's come up with a list of options we'd like to
gkanwar 2013/06/20 20:48:47 Done for most options. I'm still waiting on Peter
141 dest='tool',
142 help=('Run the test under a tool '
143 '(use --tool help to list them)'))
144 option_group.add_option('--flakiness-dashboard-server',
145 dest='flakiness_dashboard_server',
146 help=('Address of the server that is hosting the '
147 'Chrome for Android flakiness dashboard.'))
148 option_group.add_option('--skip-deps-push', dest='push_deps',
149 action='store_false', default=True,
150 help=('Do not push dependencies to the device. '
151 'Use this at own risk for speeding up test '
152 'execution on local machine.'))
153 option_group.add_option('--exit-code', action='store_true',
154 help=('If set, the exit code will be total number '
155 'of failures.'))
156 option_group.add_option('--buildbot-step-failure',
157 action='store_true',
158 help=('If present, will set the buildbot status '
159 'as STEP_FAILURE, otherwise as STEP_WARNINGS '
160 'when test(s) fail.'))
161 option_parser.add_option_group(option_group)
162
163
164 def ProcessCommonOptions(options):
165 """Processes and handles all common options."""
166 if options.out_directory:
167 cmd_helper.OutDirectory.set(options.out_directory)
168 run_tests_helper.SetLogLevel(options.verbose_count)
169
170
171 def AddContentBrowserOptions(option_parser):
172 """Adds an option group to option_parser for Content Browser tests.
173
174 There are currently no options to be added for Content Browser tests, but we
175 create an option group anyway so that we can add an example for Content
176 Browser tests.
177 """
178
179 option_group = optparse.OptionGroup(
180 option_parser, 'Content Browser Test Options', 'There are no Content '
181 'Browser specific options currently! Example usage: ./run_all_tests.py '
craigdh 2013/06/17 22:37:05 No !
gkanwar 2013/06/20 20:48:47 Done.
182 'content_browsertests')
183 option_parser.add_option_group(option_group)
184
185
186 def AddGTestOptions(option_parser):
187 """Adds gtest options to option_parser."""
188
189 option_group = optparse.OptionGroup(
190 option_parser, 'GTest Options', 'Use these options to choose which '
191 'test suites to run and how. Example usage: ./run_all_tests.py gtests -s '
192 'android_webview_unittests')
193
194 option_group.add_option('-s', '--suite', dest='test_suite',
195 help=('Executable name of the test suite to run '
196 '(use -s help to list them).'))
197 option_group.add_option('-a', '--test_arguments', dest='test_arguments',
198 help='Additional arguments to pass to the test.')
199 option_group.add_option('-x', '--xvfb', dest='use_xvfb',
craigdh 2013/06/17 22:37:05 Do these also work for content_browsertests?
gkanwar 2013/06/20 20:48:47 Most of these do (--suite, --test_arguments, --web
200 action='store_true',
201 help='Use Xvfb around tests (ignored if not Linux).')
202 option_group.add_option('--webkit', action='store_true',
203 help='Run the tests from a WebKit checkout.')
204 option_group.add_option('--exe', action='store_true',
205 help='If set, use the exe test runner instead of '
206 'the APK.')
207
208 # TODO(gkanwar): Move these to Common Options once we have the plumbing
209 # in our other test types to handle these commands
210 AddDeviceOptions(option_group)
211
212 option_parser.add_option_group(option_group)
213
214
215 def AddJavaTestOptions(option_parser):
216 """Adds the Java test options to option_parser."""
217
218 option_group = optparse.OptionGroup(option_parser,
219 'Java Test Options',
220 'These options are shared between both '
221 'Instrumentation and UIAutomator tests. '
222 'See the specific options for one or the '
craigdh 2013/06/17 22:37:05 Try to use as few words as possible. People tend t
gkanwar 2013/06/20 20:48:47 Done.
223 'other for an example of how to run each '
224 'type of test.')
225 option_group.add_option(
226 '-A', '--annotation', dest='annotation_str',
227 help=('Comma-separated list of annotations. Run only tests with any of '
228 'the given annotations. An annotation can be either a key or a '
229 'key-values pair. A test that has no annotation is considered '
230 '"SmallTest".'))
231 option_group.add_option(
232 '-E', '--exclude-annotation', dest='exclude_annotation_str',
233 help=('Comma-separated list of annotations. Exclude tests with these '
234 'annotations.'))
235 option_group.add_option('-j', '--java_only', action='store_true',
236 default=False, help='Run only the Java tests.')
237 option_group.add_option('-p', '--python_only', action='store_true',
238 default=False, help='Run only the host-driven tests.')
239 option_group.add_option('--screenshot', dest='screenshot_failures',
240 action='store_true',
241 help='Capture screenshots of test failures')
242 option_group.add_option('--save-perf-json', action='store_true',
243 help='Saves the JSON file for each UI Perf test.')
244 # TODO(gkanwar): Remove this option. It is not used anywhere.
245 option_group.add_option('--shard_retries', type=int, default=1,
craigdh 2013/06/17 22:37:05 What's the difference between this and the common
gkanwar 2013/06/20 20:48:47 This option is currently only used in host_driven
246 help=('Number of times to retry each failure when '
247 'sharding.'))
248 option_group.add_option('--official-build', help='Run official build tests.')
249 option_group.add_option('--python_test_root',
250 help='Root of the host-driven tests.')
251 option_group.add_option('--keep_test_server_ports',
252 action='store_true',
253 help=('Indicates the test server ports must be '
254 'kept. When this is run via a sharder '
255 'the test server ports should be kept and '
256 'should not be reset.'))
257 option_group.add_option('--disable_assertions', action='store_true',
258 help='Run with java assertions disabled.')
259 option_group.add_option('--test_data', action='append', default=[],
260 help=('Each instance defines a directory of test '
261 'data that should be copied to the target(s) '
262 'before running the tests. The argument '
263 'should be of the form <target>:<source>, '
264 '<target> is relative to the device data'
265 'directory, and <source> is relative to the '
266 'chromium build directory.'))
267
268 option_parser.add_option_group(option_group)
269
270
271 def ProcessJavaTestOptions(options, errorf):
272 """Processes options/arguments and populates options with defaults."""
273
274 if options.java_only and options.python_only:
275 errorf('Options java_only (-j) and python_only (-p) '
276 'are mutually exclusive.')
277 options.run_java_tests = True
278 options.run_python_tests = True
279 if options.java_only:
280 options.run_python_tests = False
281 elif options.python_only:
282 options.run_java_tests = False
283
284 if not options.python_test_root:
285 options.run_python_tests = False
286
287 if options.annotation_str:
288 options.annotations = options.annotation_str.split(',')
289 elif options.test_filter:
290 options.annotations = []
291 else:
292 options.annotations = ['Smoke', 'SmallTest', 'MediumTest', 'LargeTest']
293
294 if options.exclude_annotation_str:
295 options.exclude_annotations = options.exclude_annotation_str.split(',')
296 else:
297 options.exclude_annotations = []
298
299 if not options.keep_test_server_ports:
300 if not ports.ResetTestServerPortAllocation():
301 raise Exception('Failed to reset test server port.')
302
303
304 def AddInstrumentationOptions(option_parser):
305 """Adds Instrumentation test options to option_parser."""
306 option_group = optparse.OptionGroup(
307 option_parser, 'Instrumentation Test Options',
308 'Options specific to Instrumentation Tests. Example usage: '
craigdh 2013/06/17 22:37:05 Clarify here that these are in addition to the jav
gkanwar 2013/06/20 20:48:47 Done.
309 './run_all_tests.py instrumentation -I --test-apk=ChromiumTestShellTest')
310
311 option_group.add_option('-w', '--wait_debugger', dest='wait_for_debugger',
312 action='store_true',
313 help='(Instrumentation only) Wait for debugger.')
314 option_group.add_option('-I', dest='install_apk', action='store_true',
315 help='(Instrumentation only) Install test APK.')
316 option_group.add_option(
317 '--test-apk', dest='test_apk',
318 help=('(Instrumentation only) The name of the apk containing the tests '
319 '(without the .apk extension; e.g. "ContentShellTest"). '
320 'Alternatively, this can be a full path to the apk.'))
321 option_parser.add_option_group(option_group)
322
323
324 def ProcessInstrumentationOptions(options, errorf):
325 """Processes options/arguments and populate options with defaults."""
326
327 ProcessJavaTestOptions(options, errorf)
328
329 if not options.test_apk:
330 errorf('--test-apk must be specified.')
331
332 if os.path.exists(options.test_apk):
333 # The APK is fully qualified, assume the JAR lives along side.
334 options.test_apk_path = options.test_apk
335 options.test_apk_jar_path = (os.path.splitext(options.test_apk_path)[0] +
336 '.jar')
337 else:
338 options.test_apk_path = os.path.join(_SDK_OUT_DIR,
339 options.build_type,
340 constants.SDK_BUILD_APKS_DIR,
341 '%s.apk' % options.test_apk)
342 options.test_apk_jar_path = os.path.join(
343 _SDK_OUT_DIR, options.build_type, constants.SDK_BUILD_TEST_JAVALIB_DIR,
344 '%s.jar' % options.test_apk)
345
346
347 def AddUIAutomatorOptions(option_parser):
348 """Adds UI Automator test options to option_parser."""
349 option_group = optparse.OptionGroup(
350 option_parser, 'UIAutomator Test Options',
351 'Options specific to UIAutomator tests. Example usage: ./run_all_tests.py'
craigdh 2013/06/17 22:37:05 ditto
gkanwar 2013/06/20 20:48:47 Done.
352 ' uiautomator --test-jar=chromium_testshell_uiautomator_tests '
353 '--package-name=org.chromium.chrome.testshell')
354 option_group.add_option(
355 '--package-name',
356 help=('(UIAutomator only) The package name used by the apk '
craigdh 2013/06/17 22:37:05 No longer need all the "UIAutomator only" and "Ins
gkanwar 2013/06/20 20:48:47 Done.
357 'containing the application.'))
358 option_group.add_option(
359 '--test-jar', dest='test_jar',
360 help=('(UIAutomator only) The name of the dexed jar containing the tests '
361 '(without the .dex.jar extension). Alternatively, this can be a '
362 'full path to the jar.'))
363 option_parser.add_option_group(option_group)
364
365
366 def ProcessUIAutomatorOptions(options, errorf):
367 """Processes UIAutomator options/arguments."""
368
369 ProcessJavaTestOptions(options, errorf)
370
371 if not options.package_name:
372 errorf('--package-name must be specified.')
373
374 if not options.test_jar:
375 errorf('--test-jar must be specified.')
376
377 if os.path.exists(options.test_jar):
378 # The dexed JAR is fully qualified, assume the info JAR lives along side.
379 options.uiautomator_jar = options.test_jar
380 else:
381 options.uiautomator_jar = os.path.join(
382 _SDK_OUT_DIR, options.build_type, constants.SDK_BUILD_JAVALIB_DIR,
383 '%s.dex.jar' % options.test_jar)
384 options.uiautomator_info_jar = (
385 options.uiautomator_jar[:options.uiautomator_jar.find('.dex.jar')] +
386 '_java.jar')
387
388
389 def RunTests(options, option_parser):
390 """Checks test type and dispatches to the appropriate function."""
391
392 total_failed = 0
393 if options.test_type == 'gtests':
394 # TODO(gkanwar): Once we move Device Options to Common, this should get
395 # moved out into main.
396 ProcessDeviceOptions(options)
397 total_failed = gtest_dispatch.Dispatch(options)
398 elif options.test_type == 'content_browsertests':
399 total_failed = browsertests_dispatch.Dispatch(options)
400 elif options.test_type == 'instrumentation':
401 ProcessInstrumentationOptions(options, option_parser.error)
402 if options.run_java_tests:
403 total_failed += instrumentation_dispatch.Dispatch(options)
404 if options.run_python_tests:
405 total_failed += python_dispatch.Dispatch(options)
406 elif options.test_type == 'uiautomator':
407 ProcessUIAutomatorOptions(options, option_parser.error)
408 if options.run_java_tests:
409 total_failed += uiautomator_dispatch.Dispatch(options)
410 if options.run_python_tests:
411 total_failed += python_dispatch.Dispatch(options)
412 else:
413 raise Exception('Unknown test type state')
414
415 return total_failed
416
417
418 def main(argv):
419 option_parser = optparse.OptionParser(
420 usage='Usage: %prog test_type [options]')
421 AddCommonOptions(option_parser)
422 AddContentBrowserOptions(option_parser)
423 AddGTestOptions(option_parser)
424 AddJavaTestOptions(option_parser)
425 AddInstrumentationOptions(option_parser)
426 AddUIAutomatorOptions(option_parser)
427 options, args = option_parser.parse_args(argv)
428
429 ProcessTestTypeArg(options, args, option_parser.error)
430 ProcessCommonOptions(options)
431
432 failed_tests_count = RunTests(options, option_parser)
433
434 # Failures of individual test suites are communicated by printing a
435 # STEP_FAILURE message.
436 # Returning a success exit status also prevents the buildbot from incorrectly
437 # marking the last suite as failed if there were failures in other suites in
438 # the batch (this happens because the exit status is a sum of all failures
439 # from all suites, but the buildbot associates the exit status only with the
440 # most recent step).
441 if options.exit_code:
442 return failed_tests_count
443 return 0
444
445
446 if __name__ == '__main__':
447 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/pylib/utils/test_options_parser.py ('k') | build/android/run_browser_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698