blob: f38b76e6af8a64d9a5da93c06b84cf2862f454a9 [file] [log] [blame]
[email protected]fbe29322013-07-09 09:03:261#!/usr/bin/env python
2#
3# Copyright 2013 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
[email protected]181a5c92013-09-06 17:11:467"""Runs all types of tests from one unified interface."""
[email protected]fbe29322013-07-09 09:03:268
9import collections
[email protected]f7148dd42013-08-20 14:24:5710import logging
[email protected]fbe29322013-07-09 09:03:2611import optparse
12import os
[email protected]6bc1bda22013-07-19 22:08:3713import shutil
[email protected]83bb8152013-11-19 15:02:2114import signal
[email protected]fbe29322013-07-09 09:03:2615import sys
[email protected]83bb8152013-11-19 15:02:2116import threading
jbudorick256fd532014-10-24 01:50:1317import unittest
[email protected]fbe29322013-07-09 09:03:2618
[email protected]f7148dd42013-08-20 14:24:5719from pylib import android_commands
[email protected]fbe29322013-07-09 09:03:2620from pylib import constants
[email protected]c0662e092013-11-12 11:51:2521from pylib import forwarder
[email protected]fbe29322013-07-09 09:03:2622from pylib import ports
23from pylib.base import base_test_result
jbudorick66dc3722014-11-06 21:33:5124from pylib.base import environment_factory
[email protected]6bc1bda22013-07-19 22:08:3725from pylib.base import test_dispatcher
jbudorick66dc3722014-11-06 21:33:5126from pylib.base import test_instance_factory
27from pylib.base import test_run_factory
[email protected]6bc1bda22013-07-19 22:08:3728from pylib.gtest import gtest_config
[email protected]2a684222013-08-01 16:59:2229from pylib.gtest import setup as gtest_setup
30from pylib.gtest import test_options as gtest_test_options
[email protected]6b6abac6d2013-10-03 11:56:3831from pylib.linker import setup as linker_setup
[email protected]37ee0c792013-08-06 19:10:1332from pylib.host_driven import setup as host_driven_setup
[email protected]6bc1bda22013-07-19 22:08:3733from pylib.instrumentation import setup as instrumentation_setup
[email protected]2a684222013-08-01 16:59:2234from pylib.instrumentation import test_options as instrumentation_test_options
jbudorick9a6b7b332014-09-20 00:01:0735from pylib.junit import setup as junit_setup
36from pylib.junit import test_dispatcher as junit_dispatcher
[email protected]3dbdfa42013-08-08 01:08:1437from pylib.monkey import setup as monkey_setup
38from pylib.monkey import test_options as monkey_test_options
[email protected]ec3170b2013-08-14 14:39:4739from pylib.perf import setup as perf_setup
40from pylib.perf import test_options as perf_test_options
41from pylib.perf import test_runner as perf_test_runner
jbudorickb8c42072014-12-01 18:07:5442from pylib.results import json_results
43from pylib.results import report_results
[email protected]6bc1bda22013-07-19 22:08:3744from pylib.uiautomator import setup as uiautomator_setup
[email protected]2a684222013-08-01 16:59:2245from pylib.uiautomator import test_options as uiautomator_test_options
[email protected]2eea4872014-07-28 23:06:1746from pylib.utils import apk_helper
[email protected]803f65a72013-08-20 19:11:3047from pylib.utils import command_option_parser
[email protected]71aec4b2013-11-20 00:35:2448from pylib.utils import reraiser_thread
[email protected]6bc1bda22013-07-19 22:08:3749from pylib.utils import run_tests_helper
[email protected]fbe29322013-07-09 09:03:2650
51
[email protected]fbe29322013-07-09 09:03:2652def AddCommonOptions(option_parser):
53 """Adds all common options to |option_parser|."""
54
[email protected]dfffbcbc2013-09-17 22:06:0155 group = optparse.OptionGroup(option_parser, 'Common Options')
56 default_build_type = os.environ.get('BUILDTYPE', 'Debug')
57 group.add_option('--debug', action='store_const', const='Debug',
58 dest='build_type', default=default_build_type,
59 help=('If set, run test suites under out/Debug. '
60 'Default is env var BUILDTYPE or Debug.'))
61 group.add_option('--release', action='store_const',
62 const='Release', dest='build_type',
63 help=('If set, run test suites under out/Release.'
64 ' Default is env var BUILDTYPE or Debug.'))
r.kasibhatla3d57cba2014-10-09 10:55:5765 group.add_option('--build-directory', dest='build_directory',
66 help=('Path to the directory in which build files are'
67 ' located (should not include build type)'))
qsrd783e802014-11-12 11:05:0468 group.add_option('--output-directory', dest='output_directory',
69 help=('Path to the directory in which build files are'
70 ' located (must include build type). This will take'
71 ' precedence over --debug, --release and'
72 ' --build-directory'))
[email protected]dfffbcbc2013-09-17 22:06:0173 group.add_option('--num_retries', dest='num_retries', type='int',
74 default=2,
75 help=('Number of retries for a test before '
76 'giving up.'))
77 group.add_option('-v',
78 '--verbose',
79 dest='verbose_count',
80 default=0,
81 action='count',
82 help='Verbose level (multiple times for more)')
[email protected]dfffbcbc2013-09-17 22:06:0183 group.add_option('--flakiness-dashboard-server',
84 dest='flakiness_dashboard_server',
85 help=('Address of the server that is hosting the '
86 'Chrome for Android flakiness dashboard.'))
jbudorick66dc3722014-11-06 21:33:5187 group.add_option('--enable-platform-mode', action='store_true',
88 help=('Run the test scripts in platform mode, which '
89 'conceptually separates the test runner from the '
90 '"device" (local or remote, real or emulated) on '
91 'which the tests are running. [experimental]'))
92 group.add_option('-e', '--environment', default='local',
93 help=('Test environment to run in. Must be one of: %s' %
94 ', '.join(constants.VALID_ENVIRONMENTS)))
mikecase48e16bf2014-11-19 22:46:4595 group.add_option('--adb-path',
96 help=('Specify the absolute path of the adb binary that '
97 'should be used.'))
jbudorickb8c42072014-12-01 18:07:5498 group.add_option('--json-results-file', dest='json_results_file',
99 help='If set, will dump results in JSON format '
100 'to specified file.')
[email protected]dfffbcbc2013-09-17 22:06:01101 option_parser.add_option_group(group)
[email protected]fbe29322013-07-09 09:03:26102
103
jbudorick66dc3722014-11-06 21:33:51104def ProcessCommonOptions(options, error_func):
[email protected]fbe29322013-07-09 09:03:26105 """Processes and handles all common options."""
[email protected]fbe29322013-07-09 09:03:26106 run_tests_helper.SetLogLevel(options.verbose_count)
[email protected]14b3b1202013-08-15 22:25:28107 constants.SetBuildType(options.build_type)
r.kasibhatla3d57cba2014-10-09 10:55:57108 if options.build_directory:
109 constants.SetBuildDirectory(options.build_directory)
qsrd783e802014-11-12 11:05:04110 if options.output_directory:
111 constants.SetOutputDirectort(options.output_directory)
mikecase48e16bf2014-11-19 22:46:45112 if options.adb_path:
113 constants.SetAdbPath(options.adb_path)
114 # Some things such as Forwarder require ADB to be in the environment path.
115 adb_dir = os.path.dirname(constants.GetAdbPath())
116 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep):
117 os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
jbudorick66dc3722014-11-06 21:33:51118 if options.environment not in constants.VALID_ENVIRONMENTS:
119 error_func('--environment must be one of: %s' %
120 ', '.join(constants.VALID_ENVIRONMENTS))
[email protected]fbe29322013-07-09 09:03:26121
122
jbudorick256fd532014-10-24 01:50:13123def AddDeviceOptions(option_parser):
124 group = optparse.OptionGroup(option_parser, 'Device Options')
125 group.add_option('-c', dest='cleanup_test_files',
126 help='Cleanup test files on the device after run',
127 action='store_true')
128 group.add_option('--tool',
129 dest='tool',
130 help=('Run the test under a tool '
131 '(use --tool help to list them)'))
jbudorick256fd532014-10-24 01:50:13132 group.add_option('-d', '--device', dest='test_device',
133 help=('Target device for the test suite '
134 'to run on.'))
135 option_parser.add_option_group(group)
136
137
[email protected]fbe29322013-07-09 09:03:26138def AddGTestOptions(option_parser):
139 """Adds gtest options to |option_parser|."""
140
141 option_parser.usage = '%prog gtest [options]'
[email protected]dfffbcbc2013-09-17 22:06:01142 option_parser.commands_dict = {}
[email protected]fbe29322013-07-09 09:03:26143 option_parser.example = '%prog gtest -s base_unittests'
144
[email protected]6bc1bda22013-07-19 22:08:37145 # TODO(gkanwar): Make this option required
146 option_parser.add_option('-s', '--suite', dest='suite_name',
[email protected]fbe29322013-07-09 09:03:26147 help=('Executable name of the test suite to run '
148 '(use -s help to list them).'))
[email protected]c53dc4332013-11-20 04:38:03149 option_parser.add_option('-f', '--gtest_filter', '--gtest-filter',
150 dest='test_filter',
[email protected]9e689252013-07-30 20:14:36151 help='googletest-style filter string.')
[email protected]c53dc4332013-11-20 04:38:03152 option_parser.add_option('--gtest_also_run_disabled_tests',
153 '--gtest-also-run-disabled-tests',
[email protected]dfffbcbc2013-09-17 22:06:01154 dest='run_disabled', action='store_true',
155 help='Also run disabled tests if applicable.')
156 option_parser.add_option('-a', '--test-arguments', dest='test_arguments',
157 default='',
[email protected]9e689252013-07-30 20:14:36158 help='Additional arguments to pass to the test.')
159 option_parser.add_option('-t', dest='timeout',
160 help='Timeout to wait for each test',
161 type='int',
162 default=60)
[email protected]5b8b8742014-05-22 08:18:50163 option_parser.add_option('--isolate_file_path',
164 '--isolate-file-path',
165 dest='isolate_file_path',
166 help='.isolate file path to override the default '
167 'path')
jbudorickb8c42072014-12-01 18:07:54168
[email protected]fbe29322013-07-09 09:03:26169 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13170 AddDeviceOptions(option_parser)
[email protected]fbe29322013-07-09 09:03:26171
172
[email protected]6b6abac6d2013-10-03 11:56:38173def AddLinkerTestOptions(option_parser):
174 option_parser.usage = '%prog linker'
175 option_parser.commands_dict = {}
176 option_parser.example = '%prog linker'
177
[email protected]98c4feef2013-10-08 01:19:05178 option_parser.add_option('-f', '--gtest-filter', dest='test_filter',
179 help='googletest-style filter string.')
[email protected]6b6abac6d2013-10-03 11:56:38180 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13181 AddDeviceOptions(option_parser)
[email protected]6b6abac6d2013-10-03 11:56:38182
183
[email protected]6bc1bda22013-07-19 22:08:37184def ProcessGTestOptions(options):
185 """Intercept test suite help to list test suites.
186
187 Args:
188 options: Command line options.
[email protected]6bc1bda22013-07-19 22:08:37189 """
190 if options.suite_name == 'help':
191 print 'Available test suites are:'
[email protected]9e689252013-07-30 20:14:36192 for test_suite in (gtest_config.STABLE_TEST_SUITES +
193 gtest_config.EXPERIMENTAL_TEST_SUITES):
194 print test_suite
[email protected]2a684222013-08-01 16:59:22195 sys.exit(0)
[email protected]6bc1bda22013-07-19 22:08:37196
197 # Convert to a list, assuming all test suites if nothing was specified.
198 # TODO(gkanwar): Require having a test suite
199 if options.suite_name:
200 options.suite_name = [options.suite_name]
201 else:
[email protected]9e689252013-07-30 20:14:36202 options.suite_name = [s for s in gtest_config.STABLE_TEST_SUITES]
[email protected]6bc1bda22013-07-19 22:08:37203
204
[email protected]fbe29322013-07-09 09:03:26205def AddJavaTestOptions(option_parser):
206 """Adds the Java test options to |option_parser|."""
207
[email protected]dfffbcbc2013-09-17 22:06:01208 option_parser.add_option('-f', '--test-filter', dest='test_filter',
[email protected]fbe29322013-07-09 09:03:26209 help=('Test filter (if not fully qualified, '
210 'will run all matches).'))
211 option_parser.add_option(
212 '-A', '--annotation', dest='annotation_str',
213 help=('Comma-separated list of annotations. Run only tests with any of '
214 'the given annotations. An annotation can be either a key or a '
215 'key-values pair. A test that has no annotation is considered '
216 '"SmallTest".'))
217 option_parser.add_option(
218 '-E', '--exclude-annotation', dest='exclude_annotation_str',
219 help=('Comma-separated list of annotations. Exclude tests with these '
220 'annotations.'))
jbudorickcbcc115d2014-09-18 17:50:59221 option_parser.add_option(
222 '--screenshot', dest='screenshot_failures', action='store_true',
223 help='Capture screenshots of test failures')
224 option_parser.add_option(
225 '--save-perf-json', action='store_true',
226 help='Saves the JSON file for each UI Perf test.')
227 option_parser.add_option(
228 '--official-build', action='store_true', help='Run official build tests.')
229 option_parser.add_option(
230 '--test_data', '--test-data', action='append', default=[],
231 help=('Each instance defines a directory of test data that should be '
232 'copied to the target(s) before running the tests. The argument '
233 'should be of the form <target>:<source>, <target> is relative to '
234 'the device data directory, and <source> is relative to the '
235 'chromium build directory.'))
[email protected]fbe29322013-07-09 09:03:26236
237
[email protected]7c53a602014-03-24 16:21:44238def ProcessJavaTestOptions(options):
[email protected]fbe29322013-07-09 09:03:26239 """Processes options/arguments and populates |options| with defaults."""
240
[email protected]fbe29322013-07-09 09:03:26241 if options.annotation_str:
242 options.annotations = options.annotation_str.split(',')
243 elif options.test_filter:
244 options.annotations = []
245 else:
[email protected]6bc1bda22013-07-19 22:08:37246 options.annotations = ['Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
[email protected]4f777ca2014-08-08 01:45:59247 'EnormousTest', 'IntegrationTest']
[email protected]fbe29322013-07-09 09:03:26248
249 if options.exclude_annotation_str:
250 options.exclude_annotations = options.exclude_annotation_str.split(',')
251 else:
252 options.exclude_annotations = []
253
[email protected]fbe29322013-07-09 09:03:26254
255def AddInstrumentationTestOptions(option_parser):
256 """Adds Instrumentation test options to |option_parser|."""
257
258 option_parser.usage = '%prog instrumentation [options]'
[email protected]dfffbcbc2013-09-17 22:06:01259 option_parser.commands_dict = {}
[email protected]fb7ab5e82013-07-26 18:31:20260 option_parser.example = ('%prog instrumentation '
[email protected]efeb59e2014-03-12 01:31:26261 '--test-apk=ChromeShellTest')
[email protected]fbe29322013-07-09 09:03:26262
263 AddJavaTestOptions(option_parser)
264 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13265 AddDeviceOptions(option_parser)
[email protected]fbe29322013-07-09 09:03:26266
[email protected]dfffbcbc2013-09-17 22:06:01267 option_parser.add_option('-j', '--java-only', action='store_true',
[email protected]37ee0c792013-08-06 19:10:13268 default=False, help='Run only the Java tests.')
[email protected]dfffbcbc2013-09-17 22:06:01269 option_parser.add_option('-p', '--python-only', action='store_true',
[email protected]37ee0c792013-08-06 19:10:13270 default=False,
271 help='Run only the host-driven tests.')
[email protected]a69e85bc2013-08-16 18:07:26272 option_parser.add_option('--host-driven-root',
[email protected]37ee0c792013-08-06 19:10:13273 help='Root of the host-driven tests.')
[email protected]fbe29322013-07-09 09:03:26274 option_parser.add_option('-w', '--wait_debugger', dest='wait_for_debugger',
275 action='store_true',
276 help='Wait for debugger.')
[email protected]fbe29322013-07-09 09:03:26277 option_parser.add_option(
278 '--test-apk', dest='test_apk',
279 help=('The name of the apk containing the tests '
[email protected]ae68d4a2013-09-24 21:57:15280 '(without the .apk extension; e.g. "ContentShellTest").'))
[email protected]803f65a72013-08-20 19:11:30281 option_parser.add_option('--coverage-dir',
282 help=('Directory in which to place all generated '
283 'EMMA coverage files.'))
[email protected]4f777ca2014-08-08 01:45:59284 option_parser.add_option('--device-flags', dest='device_flags', default='',
285 help='The relative filepath to a file containing '
286 'command-line flags to set on the device')
mikecase526d68e2014-11-19 20:02:05287 option_parser.add_option('--isolate_file_path',
288 '--isolate-file-path',
289 dest='isolate_file_path',
290 help='.isolate file path to override the default '
291 'path')
[email protected]fbe29322013-07-09 09:03:26292
293
294def ProcessInstrumentationOptions(options, error_func):
[email protected]2a684222013-08-01 16:59:22295 """Processes options/arguments and populate |options| with defaults.
296
297 Args:
298 options: optparse.Options object.
299 error_func: Function to call with the error message in case of an error.
300
301 Returns:
302 An InstrumentationOptions named tuple which contains all options relevant to
303 instrumentation tests.
304 """
[email protected]fbe29322013-07-09 09:03:26305
[email protected]7c53a602014-03-24 16:21:44306 ProcessJavaTestOptions(options)
[email protected]fbe29322013-07-09 09:03:26307
[email protected]37ee0c792013-08-06 19:10:13308 if options.java_only and options.python_only:
309 error_func('Options java_only (-j) and python_only (-p) '
310 'are mutually exclusive.')
311 options.run_java_tests = True
312 options.run_python_tests = True
313 if options.java_only:
314 options.run_python_tests = False
315 elif options.python_only:
316 options.run_java_tests = False
317
[email protected]67954f822013-08-14 18:09:08318 if not options.host_driven_root:
[email protected]37ee0c792013-08-06 19:10:13319 options.run_python_tests = False
320
[email protected]fbe29322013-07-09 09:03:26321 if not options.test_apk:
322 error_func('--test-apk must be specified.')
323
[email protected]ae68d4a2013-09-24 21:57:15324
[email protected]2eea4872014-07-28 23:06:17325 options.test_apk_path = os.path.join(
326 constants.GetOutDirectory(),
327 constants.SDK_BUILD_APKS_DIR,
328 '%s.apk' % options.test_apk)
[email protected]ae68d4a2013-09-24 21:57:15329 options.test_apk_jar_path = os.path.join(
330 constants.GetOutDirectory(),
331 constants.SDK_BUILD_TEST_JAVALIB_DIR,
332 '%s.jar' % options.test_apk)
[email protected]5e2f3f62014-06-23 12:31:46333 options.test_support_apk_path = '%sSupport%s' % (
[email protected]2eea4872014-07-28 23:06:17334 os.path.splitext(options.test_apk_path))
[email protected]5e2f3f62014-06-23 12:31:46335
[email protected]2eea4872014-07-28 23:06:17336 options.test_runner = apk_helper.GetInstrumentationName(options.test_apk_path)
[email protected]5e2f3f62014-06-23 12:31:46337
[email protected]2a684222013-08-01 16:59:22338 return instrumentation_test_options.InstrumentationOptions(
[email protected]2a684222013-08-01 16:59:22339 options.tool,
340 options.cleanup_test_files,
[email protected]2a684222013-08-01 16:59:22341 options.annotations,
342 options.exclude_annotations,
343 options.test_filter,
344 options.test_data,
345 options.save_perf_json,
346 options.screenshot_failures,
[email protected]2a684222013-08-01 16:59:22347 options.wait_for_debugger,
[email protected]803f65a72013-08-20 19:11:30348 options.coverage_dir,
[email protected]2a684222013-08-01 16:59:22349 options.test_apk,
350 options.test_apk_path,
[email protected]5e2f3f62014-06-23 12:31:46351 options.test_apk_jar_path,
[email protected]65bd8fb2014-08-02 17:02:02352 options.test_runner,
[email protected]4f777ca2014-08-08 01:45:59353 options.test_support_apk_path,
mikecase526d68e2014-11-19 20:02:05354 options.device_flags,
355 options.isolate_file_path
[email protected]5e2f3f62014-06-23 12:31:46356 )
[email protected]2a684222013-08-01 16:59:22357
[email protected]fbe29322013-07-09 09:03:26358
359def AddUIAutomatorTestOptions(option_parser):
360 """Adds UI Automator test options to |option_parser|."""
361
362 option_parser.usage = '%prog uiautomator [options]'
[email protected]dfffbcbc2013-09-17 22:06:01363 option_parser.commands_dict = {}
[email protected]fbe29322013-07-09 09:03:26364 option_parser.example = (
[email protected]efeb59e2014-03-12 01:31:26365 '%prog uiautomator --test-jar=chrome_shell_uiautomator_tests'
366 ' --package=chrome_shell')
[email protected]fbe29322013-07-09 09:03:26367 option_parser.add_option(
[email protected]a8886c8a92013-10-08 17:29:30368 '--package',
369 help=('Package under test. Possible values: %s' %
370 constants.PACKAGE_INFO.keys()))
[email protected]fbe29322013-07-09 09:03:26371 option_parser.add_option(
372 '--test-jar', dest='test_jar',
373 help=('The name of the dexed jar containing the tests (without the '
374 '.dex.jar extension). Alternatively, this can be a full path '
375 'to the jar.'))
376
377 AddJavaTestOptions(option_parser)
378 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13379 AddDeviceOptions(option_parser)
[email protected]fbe29322013-07-09 09:03:26380
381
382def ProcessUIAutomatorOptions(options, error_func):
[email protected]2a684222013-08-01 16:59:22383 """Processes UIAutomator options/arguments.
384
385 Args:
386 options: optparse.Options object.
387 error_func: Function to call with the error message in case of an error.
388
389 Returns:
390 A UIAutomatorOptions named tuple which contains all options relevant to
[email protected]3dbdfa42013-08-08 01:08:14391 uiautomator tests.
[email protected]2a684222013-08-01 16:59:22392 """
[email protected]fbe29322013-07-09 09:03:26393
[email protected]7c53a602014-03-24 16:21:44394 ProcessJavaTestOptions(options)
[email protected]fbe29322013-07-09 09:03:26395
[email protected]a8886c8a92013-10-08 17:29:30396 if not options.package:
397 error_func('--package is required.')
398
399 if options.package not in constants.PACKAGE_INFO:
400 error_func('Invalid package.')
[email protected]fbe29322013-07-09 09:03:26401
402 if not options.test_jar:
403 error_func('--test-jar must be specified.')
404
405 if os.path.exists(options.test_jar):
406 # The dexed JAR is fully qualified, assume the info JAR lives along side.
407 options.uiautomator_jar = options.test_jar
408 else:
409 options.uiautomator_jar = os.path.join(
[email protected]ae68d4a2013-09-24 21:57:15410 constants.GetOutDirectory(),
411 constants.SDK_BUILD_JAVALIB_DIR,
[email protected]fbe29322013-07-09 09:03:26412 '%s.dex.jar' % options.test_jar)
413 options.uiautomator_info_jar = (
414 options.uiautomator_jar[:options.uiautomator_jar.find('.dex.jar')] +
415 '_java.jar')
416
[email protected]2a684222013-08-01 16:59:22417 return uiautomator_test_options.UIAutomatorOptions(
[email protected]2a684222013-08-01 16:59:22418 options.tool,
419 options.cleanup_test_files,
[email protected]2a684222013-08-01 16:59:22420 options.annotations,
421 options.exclude_annotations,
422 options.test_filter,
423 options.test_data,
424 options.save_perf_json,
425 options.screenshot_failures,
[email protected]2a684222013-08-01 16:59:22426 options.uiautomator_jar,
427 options.uiautomator_info_jar,
[email protected]a8886c8a92013-10-08 17:29:30428 options.package)
[email protected]2a684222013-08-01 16:59:22429
[email protected]fbe29322013-07-09 09:03:26430
jbudorick9a6b7b332014-09-20 00:01:07431def AddJUnitTestOptions(option_parser):
432 """Adds junit test options to |option_parser|."""
433 option_parser.usage = '%prog junit -s [test suite name]'
434 option_parser.commands_dict = {}
435
436 option_parser.add_option(
437 '-s', '--test-suite', dest='test_suite',
438 help=('JUnit test suite to run.'))
439 option_parser.add_option(
440 '-f', '--test-filter', dest='test_filter',
441 help='Filters tests googletest-style.')
442 option_parser.add_option(
443 '--package-filter', dest='package_filter',
444 help='Filters tests by package.')
445 option_parser.add_option(
446 '--runner-filter', dest='runner_filter',
447 help='Filters tests by runner class. Must be fully qualified.')
448 option_parser.add_option(
449 '--sdk-version', dest='sdk_version', type="int",
450 help='The Android SDK version.')
451 AddCommonOptions(option_parser)
452
453
454def ProcessJUnitTestOptions(options, error_func):
455 """Processes all JUnit test options."""
456 if not options.test_suite:
457 error_func('No test suite specified.')
458 return options
459
460
[email protected]3dbdfa42013-08-08 01:08:14461def AddMonkeyTestOptions(option_parser):
462 """Adds monkey test options to |option_parser|."""
[email protected]fb81b982013-08-09 00:07:12463
464 option_parser.usage = '%prog monkey [options]'
[email protected]dfffbcbc2013-09-17 22:06:01465 option_parser.commands_dict = {}
[email protected]fb81b982013-08-09 00:07:12466 option_parser.example = (
[email protected]efeb59e2014-03-12 01:31:26467 '%prog monkey --package=chrome_shell')
[email protected]fb81b982013-08-09 00:07:12468
[email protected]3dbdfa42013-08-08 01:08:14469 option_parser.add_option(
[email protected]a8886c8a92013-10-08 17:29:30470 '--package',
471 help=('Package under test. Possible values: %s' %
472 constants.PACKAGE_INFO.keys()))
[email protected]3dbdfa42013-08-08 01:08:14473 option_parser.add_option(
474 '--event-count', default=10000, type='int',
475 help='Number of events to generate [default: %default].')
476 option_parser.add_option(
477 '--category', default='',
[email protected]fb81b982013-08-09 00:07:12478 help='A list of allowed categories.')
[email protected]3dbdfa42013-08-08 01:08:14479 option_parser.add_option(
480 '--throttle', default=100, type='int',
481 help='Delay between events (ms) [default: %default]. ')
482 option_parser.add_option(
483 '--seed', type='int',
484 help=('Seed value for pseudo-random generator. Same seed value generates '
485 'the same sequence of events. Seed is randomized by default.'))
486 option_parser.add_option(
487 '--extra-args', default='',
488 help=('String of other args to pass to the command verbatim '
489 '[default: "%default"].'))
490
491 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13492 AddDeviceOptions(option_parser)
[email protected]3dbdfa42013-08-08 01:08:14493
494
495def ProcessMonkeyTestOptions(options, error_func):
496 """Processes all monkey test options.
497
498 Args:
499 options: optparse.Options object.
500 error_func: Function to call with the error message in case of an error.
501
502 Returns:
503 A MonkeyOptions named tuple which contains all options relevant to
504 monkey tests.
505 """
[email protected]a8886c8a92013-10-08 17:29:30506 if not options.package:
507 error_func('--package is required.')
508
509 if options.package not in constants.PACKAGE_INFO:
510 error_func('Invalid package.')
[email protected]3dbdfa42013-08-08 01:08:14511
512 category = options.category
513 if category:
514 category = options.category.split(',')
515
516 return monkey_test_options.MonkeyOptions(
[email protected]3dbdfa42013-08-08 01:08:14517 options.verbose_count,
[email protected]a8886c8a92013-10-08 17:29:30518 options.package,
[email protected]3dbdfa42013-08-08 01:08:14519 options.event_count,
520 category,
521 options.throttle,
522 options.seed,
523 options.extra_args)
524
525
[email protected]ec3170b2013-08-14 14:39:47526def AddPerfTestOptions(option_parser):
527 """Adds perf test options to |option_parser|."""
528
529 option_parser.usage = '%prog perf [options]'
[email protected]dfffbcbc2013-09-17 22:06:01530 option_parser.commands_dict = {}
[email protected]def4bce2013-11-12 12:59:52531 option_parser.example = ('%prog perf '
[email protected]ad32f312013-11-13 04:03:29532 '[--single-step -- command args] or '
[email protected]def4bce2013-11-12 12:59:52533 '[--steps perf_steps.json] or '
[email protected]ad32f312013-11-13 04:03:29534 '[--print-step step]')
[email protected]ec3170b2013-08-14 14:39:47535
[email protected]181a5c92013-09-06 17:11:46536 option_parser.add_option(
[email protected]def4bce2013-11-12 12:59:52537 '--single-step',
[email protected]ad32f312013-11-13 04:03:29538 action='store_true',
[email protected]def4bce2013-11-12 12:59:52539 help='Execute the given command with retries, but only print the result '
540 'for the "most successful" round.')
541 option_parser.add_option(
[email protected]181a5c92013-09-06 17:11:46542 '--steps',
[email protected]def4bce2013-11-12 12:59:52543 help='JSON file containing the list of commands to run.')
[email protected]181a5c92013-09-06 17:11:46544 option_parser.add_option(
545 '--flaky-steps',
546 help=('A JSON file containing steps that are flaky '
547 'and will have its exit code ignored.'))
548 option_parser.add_option(
[email protected]61487ed2014-06-09 12:33:56549 '--output-json-list',
550 help='Write a simple list of names from --steps into the given file.')
551 option_parser.add_option(
simonhatchbe8da0c2014-11-27 23:33:03552 '--collect-chartjson-data',
553 action='store_true',
554 help='Cache the chartjson output from each step for later use.')
555 option_parser.add_option(
556 '--output-chartjson-data',
557 default='',
558 help='Write out chartjson into the given file.')
559 option_parser.add_option(
[email protected]181a5c92013-09-06 17:11:46560 '--print-step',
561 help='The name of a previously executed perf step to print.')
562 option_parser.add_option(
563 '--no-timeout', action='store_true',
564 help=('Do not impose a timeout. Each perf step is responsible for '
565 'implementing the timeout logic.'))
[email protected]650487c2013-09-30 11:40:49566 option_parser.add_option(
567 '-f', '--test-filter',
568 help=('Test filter (will match against the names listed in --steps).'))
569 option_parser.add_option(
570 '--dry-run',
571 action='store_true',
572 help='Just print the steps without executing.')
[email protected]ec3170b2013-08-14 14:39:47573 AddCommonOptions(option_parser)
jbudorick256fd532014-10-24 01:50:13574 AddDeviceOptions(option_parser)
[email protected]ec3170b2013-08-14 14:39:47575
576
[email protected]ad32f312013-11-13 04:03:29577def ProcessPerfTestOptions(options, args, error_func):
[email protected]ec3170b2013-08-14 14:39:47578 """Processes all perf test options.
579
580 Args:
581 options: optparse.Options object.
582 error_func: Function to call with the error message in case of an error.
583
584 Returns:
585 A PerfOptions named tuple which contains all options relevant to
586 perf tests.
587 """
[email protected]def4bce2013-11-12 12:59:52588 # Only one of steps, print_step or single_step must be provided.
589 count = len(filter(None,
590 [options.steps, options.print_step, options.single_step]))
591 if count != 1:
592 error_func('Please specify one of: --steps, --print-step, --single-step.')
[email protected]ad32f312013-11-13 04:03:29593 single_step = None
594 if options.single_step:
595 single_step = ' '.join(args[2:])
[email protected]ec3170b2013-08-14 14:39:47596 return perf_test_options.PerfOptions(
[email protected]61487ed2014-06-09 12:33:56597 options.steps, options.flaky_steps, options.output_json_list,
598 options.print_step, options.no_timeout, options.test_filter,
simonhatchbe8da0c2014-11-27 23:33:03599 options.dry_run, single_step, options.collect_chartjson_data,
600 options.output_chartjson_data)
[email protected]ec3170b2013-08-14 14:39:47601
602
jbudorick256fd532014-10-24 01:50:13603def AddPythonTestOptions(option_parser):
604 option_parser.add_option('-s', '--suite', dest='suite_name',
605 help=('Name of the test suite to run'
606 '(use -s help to list them).'))
607 AddCommonOptions(option_parser)
608
609
610def ProcessPythonTestOptions(options, error_func):
611 if options.suite_name not in constants.PYTHON_UNIT_TEST_SUITES:
612 available = ('Available test suites: [%s]' %
613 ', '.join(constants.PYTHON_UNIT_TEST_SUITES.iterkeys()))
614 if options.suite_name == 'help':
615 print available
616 else:
617 error_func('"%s" is not a valid suite. %s' %
618 (options.suite_name, available))
619
620
[email protected]7c53a602014-03-24 16:21:44621def _RunGTests(options, devices):
[email protected]6bc1bda22013-07-19 22:08:37622 """Subcommand of RunTestsCommands which runs gtests."""
[email protected]2a684222013-08-01 16:59:22623 ProcessGTestOptions(options)
[email protected]6bc1bda22013-07-19 22:08:37624
625 exit_code = 0
626 for suite_name in options.suite_name:
[email protected]2a684222013-08-01 16:59:22627 # TODO(gkanwar): Move this into ProcessGTestOptions once we require -s for
628 # the gtest command.
629 gtest_options = gtest_test_options.GTestOptions(
[email protected]2a684222013-08-01 16:59:22630 options.tool,
631 options.cleanup_test_files,
[email protected]2a684222013-08-01 16:59:22632 options.test_filter,
[email protected]dfffbcbc2013-09-17 22:06:01633 options.run_disabled,
[email protected]2a684222013-08-01 16:59:22634 options.test_arguments,
635 options.timeout,
[email protected]5b8b8742014-05-22 08:18:50636 options.isolate_file_path,
[email protected]2a684222013-08-01 16:59:22637 suite_name)
[email protected]f7148dd42013-08-20 14:24:57638 runner_factory, tests = gtest_setup.Setup(gtest_options, devices)
[email protected]6bc1bda22013-07-19 22:08:37639
640 results, test_exit_code = test_dispatcher.RunTests(
[email protected]f7148dd42013-08-20 14:24:57641 tests, runner_factory, devices, shard=True, test_timeout=None,
[email protected]6bc1bda22013-07-19 22:08:37642 num_retries=options.num_retries)
643
644 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE:
645 exit_code = test_exit_code
646
647 report_results.LogFull(
648 results=results,
649 test_type='Unit test',
650 test_package=suite_name,
[email protected]6bc1bda22013-07-19 22:08:37651 flakiness_server=options.flakiness_dashboard_server)
652
jbudorickb8c42072014-12-01 18:07:54653 if options.json_results_file:
654 json_results.GenerateJsonResultsFile(results, options.json_results_file)
655
[email protected]6bc1bda22013-07-19 22:08:37656 if os.path.isdir(constants.ISOLATE_DEPS_DIR):
657 shutil.rmtree(constants.ISOLATE_DEPS_DIR)
658
659 return exit_code
660
661
[email protected]7c53a602014-03-24 16:21:44662def _RunLinkerTests(options, devices):
[email protected]6b6abac6d2013-10-03 11:56:38663 """Subcommand of RunTestsCommands which runs linker tests."""
664 runner_factory, tests = linker_setup.Setup(options, devices)
665
666 results, exit_code = test_dispatcher.RunTests(
667 tests, runner_factory, devices, shard=True, test_timeout=60,
668 num_retries=options.num_retries)
669
670 report_results.LogFull(
671 results=results,
672 test_type='Linker test',
[email protected]93c9f9b2014-02-10 16:19:22673 test_package='ChromiumLinkerTest')
[email protected]6b6abac6d2013-10-03 11:56:38674
jbudorickb8c42072014-12-01 18:07:54675 if options.json_results_file:
676 json_results.GenerateJsonResultsFile(results, options.json_results_file)
677
[email protected]6b6abac6d2013-10-03 11:56:38678 return exit_code
679
680
[email protected]f7148dd42013-08-20 14:24:57681def _RunInstrumentationTests(options, error_func, devices):
[email protected]6bc1bda22013-07-19 22:08:37682 """Subcommand of RunTestsCommands which runs instrumentation tests."""
[email protected]2a684222013-08-01 16:59:22683 instrumentation_options = ProcessInstrumentationOptions(options, error_func)
[email protected]6bc1bda22013-07-19 22:08:37684
[email protected]f7148dd42013-08-20 14:24:57685 if len(devices) > 1 and options.wait_for_debugger:
686 logging.warning('Debugger can not be sharded, using first available device')
687 devices = devices[:1]
688
[email protected]6bc1bda22013-07-19 22:08:37689 results = base_test_result.TestRunResults()
690 exit_code = 0
691
692 if options.run_java_tests:
mikecase526d68e2014-11-19 20:02:05693 runner_factory, tests = instrumentation_setup.Setup(
694 instrumentation_options, devices)
[email protected]6bc1bda22013-07-19 22:08:37695
696 test_results, exit_code = test_dispatcher.RunTests(
[email protected]f7148dd42013-08-20 14:24:57697 tests, runner_factory, devices, shard=True, test_timeout=None,
[email protected]6bc1bda22013-07-19 22:08:37698 num_retries=options.num_retries)
699
700 results.AddTestRunResults(test_results)
701
702 if options.run_python_tests:
[email protected]37ee0c792013-08-06 19:10:13703 runner_factory, tests = host_driven_setup.InstrumentationSetup(
[email protected]67954f822013-08-14 18:09:08704 options.host_driven_root, options.official_build,
[email protected]37ee0c792013-08-06 19:10:13705 instrumentation_options)
706
[email protected]34020022013-08-06 23:35:34707 if tests:
708 test_results, test_exit_code = test_dispatcher.RunTests(
[email protected]f7148dd42013-08-20 14:24:57709 tests, runner_factory, devices, shard=True, test_timeout=None,
[email protected]34020022013-08-06 23:35:34710 num_retries=options.num_retries)
[email protected]6bc1bda22013-07-19 22:08:37711
[email protected]34020022013-08-06 23:35:34712 results.AddTestRunResults(test_results)
[email protected]6bc1bda22013-07-19 22:08:37713
[email protected]34020022013-08-06 23:35:34714 # Only allow exit code escalation
715 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE:
716 exit_code = test_exit_code
[email protected]6bc1bda22013-07-19 22:08:37717
[email protected]4f777ca2014-08-08 01:45:59718 if options.device_flags:
719 options.device_flags = os.path.join(constants.DIR_SOURCE_ROOT,
720 options.device_flags)
721
[email protected]6bc1bda22013-07-19 22:08:37722 report_results.LogFull(
723 results=results,
724 test_type='Instrumentation',
725 test_package=os.path.basename(options.test_apk),
726 annotation=options.annotations,
[email protected]6bc1bda22013-07-19 22:08:37727 flakiness_server=options.flakiness_dashboard_server)
728
jbudorickb8c42072014-12-01 18:07:54729 if options.json_results_file:
730 json_results.GenerateJsonResultsFile(results, options.json_results_file)
731
[email protected]6bc1bda22013-07-19 22:08:37732 return exit_code
733
734
[email protected]f7148dd42013-08-20 14:24:57735def _RunUIAutomatorTests(options, error_func, devices):
[email protected]6bc1bda22013-07-19 22:08:37736 """Subcommand of RunTestsCommands which runs uiautomator tests."""
[email protected]2a684222013-08-01 16:59:22737 uiautomator_options = ProcessUIAutomatorOptions(options, error_func)
[email protected]6bc1bda22013-07-19 22:08:37738
[email protected]37ee0c792013-08-06 19:10:13739 runner_factory, tests = uiautomator_setup.Setup(uiautomator_options)
[email protected]6bc1bda22013-07-19 22:08:37740
[email protected]37ee0c792013-08-06 19:10:13741 results, exit_code = test_dispatcher.RunTests(
[email protected]f7148dd42013-08-20 14:24:57742 tests, runner_factory, devices, shard=True, test_timeout=None,
[email protected]37ee0c792013-08-06 19:10:13743 num_retries=options.num_retries)
[email protected]6bc1bda22013-07-19 22:08:37744
745 report_results.LogFull(
746 results=results,
747 test_type='UIAutomator',
748 test_package=os.path.basename(options.test_jar),
749 annotation=options.annotations,
[email protected]6bc1bda22013-07-19 22:08:37750 flakiness_server=options.flakiness_dashboard_server)
751
jbudorickb8c42072014-12-01 18:07:54752 if options.json_results_file:
753 json_results.GenerateJsonResultsFile(results, options.json_results_file)
754
[email protected]6bc1bda22013-07-19 22:08:37755 return exit_code
756
757
jbudorick9a6b7b332014-09-20 00:01:07758def _RunJUnitTests(options, error_func):
759 """Subcommand of RunTestsCommand which runs junit tests."""
760 junit_options = ProcessJUnitTestOptions(options, error_func)
761 runner_factory, tests = junit_setup.Setup(junit_options)
762 _, exit_code = junit_dispatcher.RunTests(tests, runner_factory)
763
764 return exit_code
765
766
[email protected]f7148dd42013-08-20 14:24:57767def _RunMonkeyTests(options, error_func, devices):
[email protected]3dbdfa42013-08-08 01:08:14768 """Subcommand of RunTestsCommands which runs monkey tests."""
769 monkey_options = ProcessMonkeyTestOptions(options, error_func)
770
771 runner_factory, tests = monkey_setup.Setup(monkey_options)
772
773 results, exit_code = test_dispatcher.RunTests(
[email protected]181a5c92013-09-06 17:11:46774 tests, runner_factory, devices, shard=False, test_timeout=None,
775 num_retries=options.num_retries)
[email protected]3dbdfa42013-08-08 01:08:14776
777 report_results.LogFull(
778 results=results,
779 test_type='Monkey',
[email protected]14b3b1202013-08-15 22:25:28780 test_package='Monkey')
[email protected]3dbdfa42013-08-08 01:08:14781
jbudorickb8c42072014-12-01 18:07:54782 if options.json_results_file:
783 json_results.GenerateJsonResultsFile(results, options.json_results_file)
784
[email protected]3dbdfa42013-08-08 01:08:14785 return exit_code
786
787
[email protected]a72f0752014-06-03 23:52:34788def _RunPerfTests(options, args, error_func):
[email protected]ec3170b2013-08-14 14:39:47789 """Subcommand of RunTestsCommands which runs perf tests."""
[email protected]ad32f312013-11-13 04:03:29790 perf_options = ProcessPerfTestOptions(options, args, error_func)
[email protected]61487ed2014-06-09 12:33:56791
792 # Just save a simple json with a list of test names.
793 if perf_options.output_json_list:
794 return perf_test_runner.OutputJsonList(
795 perf_options.steps, perf_options.output_json_list)
796
simonhatchbe8da0c2014-11-27 23:33:03797 if perf_options.output_chartjson_data:
798 return perf_test_runner.OutputChartjson(
799 perf_options.print_step, perf_options.output_chartjson_data)
800
[email protected]ad32f312013-11-13 04:03:29801 # Just print the results from a single previously executed step.
[email protected]ec3170b2013-08-14 14:39:47802 if perf_options.print_step:
803 return perf_test_runner.PrintTestOutput(perf_options.print_step)
804
[email protected]a72f0752014-06-03 23:52:34805 runner_factory, tests, devices = perf_setup.Setup(perf_options)
[email protected]ec3170b2013-08-14 14:39:47806
[email protected]a72f0752014-06-03 23:52:34807 # shard=False means that each device will get the full list of tests
808 # and then each one will decide their own affinity.
809 # shard=True means each device will pop the next test available from a queue,
810 # which increases throughput but have no affinity.
[email protected]86184c7b2013-08-15 15:06:57811 results, _ = test_dispatcher.RunTests(
[email protected]a72f0752014-06-03 23:52:34812 tests, runner_factory, devices, shard=False, test_timeout=None,
[email protected]181a5c92013-09-06 17:11:46813 num_retries=options.num_retries)
[email protected]ec3170b2013-08-14 14:39:47814
815 report_results.LogFull(
816 results=results,
817 test_type='Perf',
[email protected]865a47a2013-08-16 14:01:12818 test_package='Perf')
[email protected]def4bce2013-11-12 12:59:52819
jbudorickb8c42072014-12-01 18:07:54820 if options.json_results_file:
821 json_results.GenerateJsonResultsFile(results, options.json_results_file)
822
[email protected]def4bce2013-11-12 12:59:52823 if perf_options.single_step:
824 return perf_test_runner.PrintTestOutput('single_step')
825
[email protected]11ce8452014-02-17 10:55:03826 perf_test_runner.PrintSummary(tests)
827
[email protected]86184c7b2013-08-15 15:06:57828 # Always return 0 on the sharding stage. Individual tests exit_code
829 # will be returned on the print_step stage.
830 return 0
[email protected]ec3170b2013-08-14 14:39:47831
[email protected]3dbdfa42013-08-08 01:08:14832
jbudorick256fd532014-10-24 01:50:13833def _RunPythonTests(options, error_func):
834 """Subcommand of RunTestsCommand which runs python unit tests."""
835 ProcessPythonTestOptions(options, error_func)
836
837 suite_vars = constants.PYTHON_UNIT_TEST_SUITES[options.suite_name]
838 suite_path = suite_vars['path']
839 suite_test_modules = suite_vars['test_modules']
840
841 sys.path = [suite_path] + sys.path
842 try:
843 suite = unittest.TestSuite()
844 suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m)
845 for m in suite_test_modules)
846 runner = unittest.TextTestRunner(verbosity=1+options.verbose_count)
847 return 0 if runner.run(suite).wasSuccessful() else 1
848 finally:
849 sys.path = sys.path[1:]
850
851
[email protected]f7148dd42013-08-20 14:24:57852def _GetAttachedDevices(test_device=None):
853 """Get all attached devices.
854
855 Args:
856 test_device: Name of a specific device to use.
857
858 Returns:
859 A list of attached devices.
860 """
861 attached_devices = []
862
863 attached_devices = android_commands.GetAttachedDevices()
864 if test_device:
865 assert test_device in attached_devices, (
866 'Did not find device %s among attached device. Attached devices: %s'
867 % (test_device, ', '.join(attached_devices)))
868 attached_devices = [test_device]
869
870 assert attached_devices, 'No devices attached.'
871
872 return sorted(attached_devices)
873
874
[email protected]fbe29322013-07-09 09:03:26875def RunTestsCommand(command, options, args, option_parser):
876 """Checks test type and dispatches to the appropriate function.
877
878 Args:
879 command: String indicating the command that was received to trigger
880 this function.
881 options: optparse options dictionary.
882 args: List of extra args from optparse.
883 option_parser: optparse.OptionParser object.
884
885 Returns:
886 Integer indicated exit code.
[email protected]b3873892013-07-10 04:57:10887
888 Raises:
889 Exception: Unknown command name passed in, or an exception from an
890 individual test runner.
[email protected]fbe29322013-07-09 09:03:26891 """
892
[email protected]d82f0252013-07-12 23:22:57893 # Check for extra arguments
[email protected]ad32f312013-11-13 04:03:29894 if len(args) > 2 and command != 'perf':
[email protected]d82f0252013-07-12 23:22:57895 option_parser.error('Unrecognized arguments: %s' % (' '.join(args[2:])))
896 return constants.ERROR_EXIT_CODE
[email protected]ad32f312013-11-13 04:03:29897 if command == 'perf':
898 if ((options.single_step and len(args) <= 2) or
899 (not options.single_step and len(args) > 2)):
900 option_parser.error('Unrecognized arguments: %s' % (' '.join(args)))
901 return constants.ERROR_EXIT_CODE
[email protected]d82f0252013-07-12 23:22:57902
jbudorick66dc3722014-11-06 21:33:51903 ProcessCommonOptions(options, option_parser.error)
[email protected]fbe29322013-07-09 09:03:26904
jbudorick66dc3722014-11-06 21:33:51905 if options.enable_platform_mode:
906 return RunTestsInPlatformMode(command, options, option_parser)
907
908 if command in constants.LOCAL_MACHINE_TESTS:
jbudorick256fd532014-10-24 01:50:13909 devices = []
910 else:
911 devices = _GetAttachedDevices(options.test_device)
[email protected]f7148dd42013-08-20 14:24:57912
[email protected]c0662e092013-11-12 11:51:25913 forwarder.Forwarder.RemoveHostLog()
[email protected]6b11583b2013-11-21 16:18:40914 if not ports.ResetTestServerPortAllocation():
915 raise Exception('Failed to reset test server port.')
[email protected]c0662e092013-11-12 11:51:25916
[email protected]fbe29322013-07-09 09:03:26917 if command == 'gtest':
[email protected]7c53a602014-03-24 16:21:44918 return _RunGTests(options, devices)
[email protected]6b6abac6d2013-10-03 11:56:38919 elif command == 'linker':
[email protected]7c53a602014-03-24 16:21:44920 return _RunLinkerTests(options, devices)
[email protected]fbe29322013-07-09 09:03:26921 elif command == 'instrumentation':
[email protected]f7148dd42013-08-20 14:24:57922 return _RunInstrumentationTests(options, option_parser.error, devices)
[email protected]fbe29322013-07-09 09:03:26923 elif command == 'uiautomator':
[email protected]f7148dd42013-08-20 14:24:57924 return _RunUIAutomatorTests(options, option_parser.error, devices)
jbudorick9a6b7b332014-09-20 00:01:07925 elif command == 'junit':
926 return _RunJUnitTests(options, option_parser.error)
[email protected]3dbdfa42013-08-08 01:08:14927 elif command == 'monkey':
[email protected]f7148dd42013-08-20 14:24:57928 return _RunMonkeyTests(options, option_parser.error, devices)
[email protected]ec3170b2013-08-14 14:39:47929 elif command == 'perf':
[email protected]a72f0752014-06-03 23:52:34930 return _RunPerfTests(options, args, option_parser.error)
jbudorick256fd532014-10-24 01:50:13931 elif command == 'python':
932 return _RunPythonTests(options, option_parser.error)
[email protected]fbe29322013-07-09 09:03:26933 else:
[email protected]6bc1bda22013-07-19 22:08:37934 raise Exception('Unknown test type.')
[email protected]fbe29322013-07-09 09:03:26935
[email protected]fbe29322013-07-09 09:03:26936
jbudorick66dc3722014-11-06 21:33:51937_SUPPORTED_IN_PLATFORM_MODE = [
938 # TODO(jbudorick): Add support for more test types.
939 'gtest',
940]
941
942
943def RunTestsInPlatformMode(command, options, option_parser):
944
945 if command not in _SUPPORTED_IN_PLATFORM_MODE:
946 option_parser.error('%s is not yet supported in platform mode' % command)
947
948 with environment_factory.CreateEnvironment(
949 command, options, option_parser.error) as env:
950 with test_instance_factory.CreateTestInstance(
951 command, options, option_parser.error) as test:
952 with test_run_factory.CreateTestRun(
953 options, env, test, option_parser.error) as test_run:
954 results = test_run.RunTests()
955
956 report_results.LogFull(
957 results=results,
958 test_type=test.TestType(),
959 test_package=test_run.TestPackage(),
960 annotation=options.annotations,
961 flakiness_server=options.flakiness_dashboard_server)
962
jbudorickb8c42072014-12-01 18:07:54963 if options.json_results_file:
964 json_results.GenerateJsonResultsFile(
965 results, options.json_results_file)
966
jbudorick66dc3722014-11-06 21:33:51967 return results
968
969
[email protected]7c53a602014-03-24 16:21:44970def HelpCommand(command, _options, args, option_parser):
[email protected]fbe29322013-07-09 09:03:26971 """Display help for a certain command, or overall help.
972
973 Args:
974 command: String indicating the command that was received to trigger
975 this function.
[email protected]7c53a602014-03-24 16:21:44976 options: optparse options dictionary. unused.
[email protected]fbe29322013-07-09 09:03:26977 args: List of extra args from optparse.
978 option_parser: optparse.OptionParser object.
979
980 Returns:
981 Integer indicated exit code.
982 """
983 # If we don't have any args, display overall help
984 if len(args) < 3:
985 option_parser.print_help()
986 return 0
[email protected]d82f0252013-07-12 23:22:57987 # If we have too many args, print an error
988 if len(args) > 3:
989 option_parser.error('Unrecognized arguments: %s' % (' '.join(args[3:])))
990 return constants.ERROR_EXIT_CODE
[email protected]fbe29322013-07-09 09:03:26991
992 command = args[2]
993
994 if command not in VALID_COMMANDS:
995 option_parser.error('Unrecognized command.')
996
997 # Treat the help command as a special case. We don't care about showing a
998 # specific help page for itself.
999 if command == 'help':
1000 option_parser.print_help()
1001 return 0
1002
1003 VALID_COMMANDS[command].add_options_func(option_parser)
1004 option_parser.usage = '%prog ' + command + ' [options]'
[email protected]dfffbcbc2013-09-17 22:06:011005 option_parser.commands_dict = {}
[email protected]fbe29322013-07-09 09:03:261006 option_parser.print_help()
1007
1008 return 0
1009
1010
1011# Define a named tuple for the values in the VALID_COMMANDS dictionary so the
1012# syntax is a bit prettier. The tuple is two functions: (add options, run
1013# command).
1014CommandFunctionTuple = collections.namedtuple(
1015 'CommandFunctionTuple', ['add_options_func', 'run_command_func'])
1016VALID_COMMANDS = {
1017 'gtest': CommandFunctionTuple(AddGTestOptions, RunTestsCommand),
[email protected]fbe29322013-07-09 09:03:261018 'instrumentation': CommandFunctionTuple(
1019 AddInstrumentationTestOptions, RunTestsCommand),
1020 'uiautomator': CommandFunctionTuple(
1021 AddUIAutomatorTestOptions, RunTestsCommand),
jbudorick9a6b7b332014-09-20 00:01:071022 'junit': CommandFunctionTuple(
1023 AddJUnitTestOptions, RunTestsCommand),
[email protected]3dbdfa42013-08-08 01:08:141024 'monkey': CommandFunctionTuple(
1025 AddMonkeyTestOptions, RunTestsCommand),
[email protected]ec3170b2013-08-14 14:39:471026 'perf': CommandFunctionTuple(
1027 AddPerfTestOptions, RunTestsCommand),
jbudorick256fd532014-10-24 01:50:131028 'python': CommandFunctionTuple(
1029 AddPythonTestOptions, RunTestsCommand),
[email protected]6b6abac6d2013-10-03 11:56:381030 'linker': CommandFunctionTuple(
1031 AddLinkerTestOptions, RunTestsCommand),
[email protected]fbe29322013-07-09 09:03:261032 'help': CommandFunctionTuple(lambda option_parser: None, HelpCommand)
1033 }
1034
1035
[email protected]7c53a602014-03-24 16:21:441036def DumpThreadStacks(_signal, _frame):
[email protected]71aec4b2013-11-20 00:35:241037 for thread in threading.enumerate():
1038 reraiser_thread.LogThreadStack(thread)
[email protected]83bb8152013-11-19 15:02:211039
1040
[email protected]7c53a602014-03-24 16:21:441041def main():
[email protected]83bb8152013-11-19 15:02:211042 signal.signal(signal.SIGUSR1, DumpThreadStacks)
[email protected]803f65a72013-08-20 19:11:301043 option_parser = command_option_parser.CommandOptionParser(
1044 commands_dict=VALID_COMMANDS)
1045 return command_option_parser.ParseAndExecute(option_parser)
[email protected]fbe29322013-07-09 09:03:261046
[email protected]fbe29322013-07-09 09:03:261047
1048if __name__ == '__main__':
[email protected]7c53a602014-03-24 16:21:441049 sys.exit(main())