| OLD | NEW |
| 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 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 devil_chromium.Initialize( | 140 devil_chromium.Initialize( |
| 141 output_directory=constants.GetOutDirectory(), | 141 output_directory=constants.GetOutDirectory(), |
| 142 adb_path=args.adb_path) | 142 adb_path=args.adb_path) |
| 143 | 143 |
| 144 # Some things such as Forwarder require ADB to be in the environment path. | 144 # Some things such as Forwarder require ADB to be in the environment path. |
| 145 adb_dir = os.path.dirname(constants.GetAdbPath()) | 145 adb_dir = os.path.dirname(constants.GetAdbPath()) |
| 146 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): | 146 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): |
| 147 os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH'] | 147 os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH'] |
| 148 | 148 |
| 149 | 149 |
| 150 def AddRemoteDeviceOptions(parser): | |
| 151 group = parser.add_argument_group('Remote Device Options') | |
| 152 | |
| 153 group.add_argument('--trigger', | |
| 154 help=('Only triggers the test if set. Stores test_run_id ' | |
| 155 'in given file path. ')) | |
| 156 group.add_argument('--collect', | |
| 157 help=('Only collects the test results if set. ' | |
| 158 'Gets test_run_id from given file path.')) | |
| 159 group.add_argument('--remote-device', action='append', | |
| 160 help='Device type to run test on.') | |
| 161 group.add_argument('--results-path', | |
| 162 help='File path to download results to.') | |
| 163 group.add_argument('--api-protocol', | |
| 164 help='HTTP protocol to use. (http or https)') | |
| 165 group.add_argument('--api-address', | |
| 166 help='Address to send HTTP requests.') | |
| 167 group.add_argument('--api-port', | |
| 168 help='Port to send HTTP requests to.') | |
| 169 group.add_argument('--runner-type', | |
| 170 help='Type of test to run as.') | |
| 171 group.add_argument('--runner-package', | |
| 172 help='Package name of test.') | |
| 173 group.add_argument('--device-type', | |
| 174 choices=constants.VALID_DEVICE_TYPES, | |
| 175 help=('Type of device to run on. iOS or android')) | |
| 176 group.add_argument('--device-oem', action='append', | |
| 177 help='Device OEM to run on.') | |
| 178 group.add_argument('--remote-device-file', | |
| 179 help=('File with JSON to select remote device. ' | |
| 180 'Overrides all other flags.')) | |
| 181 group.add_argument('--remote-device-timeout', type=int, | |
| 182 help='Times to retry finding remote device') | |
| 183 group.add_argument('--network-config', type=int, | |
| 184 help='Integer that specifies the network environment ' | |
| 185 'that the tests will be run in.') | |
| 186 group.add_argument('--test-timeout', type=int, | |
| 187 help='Test run timeout in seconds.') | |
| 188 | |
| 189 device_os_group = group.add_mutually_exclusive_group() | |
| 190 device_os_group.add_argument('--remote-device-minimum-os', | |
| 191 help='Minimum OS on device.') | |
| 192 device_os_group.add_argument('--remote-device-os', action='append', | |
| 193 help='OS to have on the device.') | |
| 194 | |
| 195 api_secret_group = group.add_mutually_exclusive_group() | |
| 196 api_secret_group.add_argument('--api-secret', default='', | |
| 197 help='API secret for remote devices.') | |
| 198 api_secret_group.add_argument('--api-secret-file', default='', | |
| 199 help='Path to file that contains API secret.') | |
| 200 | |
| 201 api_key_group = group.add_mutually_exclusive_group() | |
| 202 api_key_group.add_argument('--api-key', default='', | |
| 203 help='API key for remote devices.') | |
| 204 api_key_group.add_argument('--api-key-file', default='', | |
| 205 help='Path to file that contains API key.') | |
| 206 | |
| 207 | |
| 208 def AddDeviceOptions(parser): | 150 def AddDeviceOptions(parser): |
| 209 """Adds device options to |parser|.""" | 151 """Adds device options to |parser|.""" |
| 210 group = parser.add_argument_group(title='Device Options') | 152 group = parser.add_argument_group(title='Device Options') |
| 211 group.add_argument('--tool', | 153 group.add_argument('--tool', |
| 212 dest='tool', | 154 dest='tool', |
| 213 help=('Run the test under a tool ' | 155 help=('Run the test under a tool ' |
| 214 '(use --tool help to list them)')) | 156 '(use --tool help to list them)')) |
| 215 group.add_argument('-d', '--device', dest='test_device', | 157 group.add_argument('-d', '--device', dest='test_device', |
| 216 help=('Target device for the test suite ' | 158 help=('Target device for the test suite ' |
| 217 'to run on.')) | 159 'to run on.')) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 dest='test_filter', | 236 dest='test_filter', |
| 295 help='googletest-style filter string.') | 237 help='googletest-style filter string.') |
| 296 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file', | 238 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file', |
| 297 type=os.path.realpath, | 239 type=os.path.realpath, |
| 298 help='Path to file that contains googletest-style ' | 240 help='Path to file that contains googletest-style ' |
| 299 'filter strings. (Lines will be joined with ' | 241 'filter strings. (Lines will be joined with ' |
| 300 '":" to create a single filter string.)') | 242 '":" to create a single filter string.)') |
| 301 | 243 |
| 302 AddDeviceOptions(parser) | 244 AddDeviceOptions(parser) |
| 303 AddCommonOptions(parser) | 245 AddCommonOptions(parser) |
| 304 AddRemoteDeviceOptions(parser) | |
| 305 | 246 |
| 306 | 247 |
| 307 def AddLinkerTestOptions(parser): | 248 def AddLinkerTestOptions(parser): |
| 308 group = parser.add_argument_group('Linker Test Options') | 249 group = parser.add_argument_group('Linker Test Options') |
| 309 group.add_argument('-f', '--gtest-filter', dest='test_filter', | 250 group.add_argument('-f', '--gtest-filter', dest='test_filter', |
| 310 help='googletest-style filter string.') | 251 help='googletest-style filter string.') |
| 311 AddCommonOptions(parser) | 252 AddCommonOptions(parser) |
| 312 AddDeviceOptions(parser) | 253 AddDeviceOptions(parser) |
| 313 | 254 |
| 314 | 255 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 action='store_true', | 378 action='store_true', |
| 438 help='Causes the render tests to not fail when a check' | 379 help='Causes the render tests to not fail when a check' |
| 439 'fails or the golden image is missing but to render' | 380 'fails or the golden image is missing but to render' |
| 440 'the view and carry on.') | 381 'the view and carry on.') |
| 441 group.add_argument('--store-tombstones', dest='store_tombstones', | 382 group.add_argument('--store-tombstones', dest='store_tombstones', |
| 442 action='store_true', | 383 action='store_true', |
| 443 help='Add tombstones in results if crash.') | 384 help='Add tombstones in results if crash.') |
| 444 | 385 |
| 445 AddCommonOptions(parser) | 386 AddCommonOptions(parser) |
| 446 AddDeviceOptions(parser) | 387 AddDeviceOptions(parser) |
| 447 AddRemoteDeviceOptions(parser) | |
| 448 | 388 |
| 449 | 389 |
| 450 def AddJUnitTestOptions(parser): | 390 def AddJUnitTestOptions(parser): |
| 451 """Adds junit test options to |parser|.""" | 391 """Adds junit test options to |parser|.""" |
| 452 | 392 |
| 453 group = parser.add_argument_group('JUnit Test Options') | 393 group = parser.add_argument_group('JUnit Test Options') |
| 454 group.add_argument( | 394 group.add_argument( |
| 455 '-s', '--test-suite', dest='test_suite', required=True, | 395 '-s', '--test-suite', dest='test_suite', required=True, |
| 456 help=('JUnit test suite to run.')) | 396 help=('JUnit test suite to run.')) |
| 457 group.add_argument( | 397 group.add_argument( |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 # TODO(jbudorick): Get rid of MonkeyOptions. | 457 # TODO(jbudorick): Get rid of MonkeyOptions. |
| 518 return monkey_test_options.MonkeyOptions( | 458 return monkey_test_options.MonkeyOptions( |
| 519 args.verbose_count, | 459 args.verbose_count, |
| 520 args.package, | 460 args.package, |
| 521 args.event_count, | 461 args.event_count, |
| 522 category, | 462 category, |
| 523 args.throttle, | 463 args.throttle, |
| 524 args.seed, | 464 args.seed, |
| 525 args.extra_args) | 465 args.extra_args) |
| 526 | 466 |
| 527 def AddUirobotTestOptions(parser): | |
| 528 """Adds uirobot test options to |option_parser|.""" | |
| 529 group = parser.add_argument_group('Uirobot Test Options') | |
| 530 | |
| 531 group.add_argument('--app-under-test', required=True, | |
| 532 help='APK to run tests on.') | |
| 533 group.add_argument( | |
| 534 '--repeat', dest='repeat', type=int, default=0, | |
| 535 help='Number of times to repeat the uirobot test.') | |
| 536 group.add_argument( | |
| 537 '--minutes', default=5, type=int, | |
| 538 help='Number of minutes to run uirobot test [default: %(default)s].') | |
| 539 | |
| 540 AddCommonOptions(parser) | |
| 541 AddDeviceOptions(parser) | |
| 542 AddRemoteDeviceOptions(parser) | |
| 543 | 467 |
| 544 def AddPerfTestOptions(parser): | 468 def AddPerfTestOptions(parser): |
| 545 """Adds perf test options to |parser|.""" | 469 """Adds perf test options to |parser|.""" |
| 546 | 470 |
| 547 group = parser.add_argument_group('Perf Test Options') | 471 group = parser.add_argument_group('Perf Test Options') |
| 548 | 472 |
| 549 class SingleStepAction(argparse.Action): | 473 class SingleStepAction(argparse.Action): |
| 550 def __call__(self, parser, namespace, values, option_string=None): | 474 def __call__(self, parser, namespace, values, option_string=None): |
| 551 if values and not namespace.single_step: | 475 if values and not namespace.single_step: |
| 552 parser.error('single step command provided, ' | 476 parser.error('single step command provided, ' |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 return _RunPythonTests(args) | 715 return _RunPythonTests(args) |
| 792 else: | 716 else: |
| 793 raise Exception('Unknown test type.') | 717 raise Exception('Unknown test type.') |
| 794 | 718 |
| 795 | 719 |
| 796 _SUPPORTED_IN_PLATFORM_MODE = [ | 720 _SUPPORTED_IN_PLATFORM_MODE = [ |
| 797 # TODO(jbudorick): Add support for more test types. | 721 # TODO(jbudorick): Add support for more test types. |
| 798 'gtest', | 722 'gtest', |
| 799 'instrumentation', | 723 'instrumentation', |
| 800 'perf', | 724 'perf', |
| 801 'uirobot', | |
| 802 ] | 725 ] |
| 803 | 726 |
| 804 | 727 |
| 805 def RunTestsInPlatformMode(args): | 728 def RunTestsInPlatformMode(args): |
| 806 | 729 |
| 807 def infra_error(message): | 730 def infra_error(message): |
| 808 logging.fatal(message) | 731 logging.fatal(message) |
| 809 sys.exit(constants.INFRA_EXIT_CODE) | 732 sys.exit(constants.INFRA_EXIT_CODE) |
| 810 | 733 |
| 811 if args.command not in _SUPPORTED_IN_PLATFORM_MODE: | 734 if args.command not in _SUPPORTED_IN_PLATFORM_MODE: |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 "Tests based on Android's monkey"), | 835 "Tests based on Android's monkey"), |
| 913 'perf': CommandConfigTuple( | 836 'perf': CommandConfigTuple( |
| 914 AddPerfTestOptions, | 837 AddPerfTestOptions, |
| 915 'Performance tests'), | 838 'Performance tests'), |
| 916 'python': CommandConfigTuple( | 839 'python': CommandConfigTuple( |
| 917 AddPythonTestOptions, | 840 AddPythonTestOptions, |
| 918 'Python tests based on unittest.TestCase'), | 841 'Python tests based on unittest.TestCase'), |
| 919 'linker': CommandConfigTuple( | 842 'linker': CommandConfigTuple( |
| 920 AddLinkerTestOptions, | 843 AddLinkerTestOptions, |
| 921 'Linker tests'), | 844 'Linker tests'), |
| 922 'uirobot': CommandConfigTuple( | |
| 923 AddUirobotTestOptions, | |
| 924 'Uirobot test'), | |
| 925 } | 845 } |
| 926 | 846 |
| 927 | 847 |
| 928 def DumpThreadStacks(_signal, _frame): | 848 def DumpThreadStacks(_signal, _frame): |
| 929 for thread in threading.enumerate(): | 849 for thread in threading.enumerate(): |
| 930 reraiser_thread.LogThreadStack(thread) | 850 reraiser_thread.LogThreadStack(thread) |
| 931 | 851 |
| 932 | 852 |
| 933 def main(): | 853 def main(): |
| 934 signal.signal(signal.SIGUSR1, DumpThreadStacks) | 854 signal.signal(signal.SIGUSR1, DumpThreadStacks) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 952 if e.is_infra_error: | 872 if e.is_infra_error: |
| 953 return constants.INFRA_EXIT_CODE | 873 return constants.INFRA_EXIT_CODE |
| 954 return constants.ERROR_EXIT_CODE | 874 return constants.ERROR_EXIT_CODE |
| 955 except: # pylint: disable=W0702 | 875 except: # pylint: disable=W0702 |
| 956 logging.exception('Unrecognized error occurred.') | 876 logging.exception('Unrecognized error occurred.') |
| 957 return constants.ERROR_EXIT_CODE | 877 return constants.ERROR_EXIT_CODE |
| 958 | 878 |
| 959 | 879 |
| 960 if __name__ == '__main__': | 880 if __name__ == '__main__': |
| 961 sys.exit(main()) | 881 sys.exit(main()) |
| OLD | NEW |