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 |
11 import logging | 11 import logging |
12 import os | 12 import os |
13 import shutil | 13 import shutil |
14 import signal | 14 import signal |
15 import sys | 15 import sys |
16 import threading | 16 import threading |
17 import unittest | 17 import unittest |
18 | 18 |
19 from pylib import constants | 19 from pylib import constants |
20 from pylib import forwarder | 20 from pylib import forwarder |
21 from pylib import ports | 21 from pylib import ports |
22 from pylib.base import base_test_result | 22 from pylib.base import base_test_result |
23 from pylib.base import environment_factory | 23 from pylib.base import environment_factory |
24 from pylib.base import test_dispatcher | 24 from pylib.base import test_dispatcher |
25 from pylib.base import test_instance_factory | 25 from pylib.base import test_instance_factory |
26 from pylib.base import test_run_factory | 26 from pylib.base import test_run_factory |
27 from pylib.device import device_errors | 27 from pylib.device import device_errors |
28 from pylib.device import device_utils | 28 from pylib.device import device_utils |
29 from pylib.gtest import gtest_config | 29 from pylib.gtest import gtest_config |
| 30 # TODO(jbudorick): Remove this once we stop selectively enabling platform mode. |
| 31 from pylib.gtest import gtest_test_instance |
30 from pylib.gtest import setup as gtest_setup | 32 from pylib.gtest import setup as gtest_setup |
31 from pylib.gtest import test_options as gtest_test_options | 33 from pylib.gtest import test_options as gtest_test_options |
32 from pylib.linker import setup as linker_setup | 34 from pylib.linker import setup as linker_setup |
33 from pylib.host_driven import setup as host_driven_setup | 35 from pylib.host_driven import setup as host_driven_setup |
34 from pylib.instrumentation import setup as instrumentation_setup | 36 from pylib.instrumentation import setup as instrumentation_setup |
35 from pylib.instrumentation import test_options as instrumentation_test_options | 37 from pylib.instrumentation import test_options as instrumentation_test_options |
36 from pylib.junit import setup as junit_setup | 38 from pylib.junit import setup as junit_setup |
37 from pylib.junit import test_dispatcher as junit_dispatcher | 39 from pylib.junit import test_dispatcher as junit_dispatcher |
38 from pylib.monkey import setup as monkey_setup | 40 from pylib.monkey import setup as monkey_setup |
39 from pylib.monkey import test_options as monkey_test_options | 41 from pylib.monkey import test_options as monkey_test_options |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 default='', | 210 default='', |
209 help='Additional arguments to pass to the test.') | 211 help='Additional arguments to pass to the test.') |
210 group.add_argument('-t', dest='timeout', type=int, default=60, | 212 group.add_argument('-t', dest='timeout', type=int, default=60, |
211 help='Timeout to wait for each test ' | 213 help='Timeout to wait for each test ' |
212 '(default: %(default)s).') | 214 '(default: %(default)s).') |
213 group.add_argument('--isolate_file_path', | 215 group.add_argument('--isolate_file_path', |
214 '--isolate-file-path', | 216 '--isolate-file-path', |
215 dest='isolate_file_path', | 217 dest='isolate_file_path', |
216 help='.isolate file path to override the default ' | 218 help='.isolate file path to override the default ' |
217 'path') | 219 'path') |
| 220 group.add_argument('--app-data-file', action='append', dest='app_data_files', |
| 221 help='A file path relative to the app data directory ' |
| 222 'that should be saved to the host.') |
| 223 group.add_argument('--app-data-file-dir', |
| 224 help='Host directory to which app data files will be' |
| 225 ' saved. Used with --app-data-file.') |
| 226 group.add_argument('--delete-stale-data', dest='delete_stale_data', |
| 227 action='store_true', |
| 228 help='Delete stale test data on the device.') |
218 | 229 |
219 filter_group = group.add_mutually_exclusive_group() | 230 filter_group = group.add_mutually_exclusive_group() |
220 filter_group.add_argument('-f', '--gtest_filter', '--gtest-filter', | 231 filter_group.add_argument('-f', '--gtest_filter', '--gtest-filter', |
221 dest='test_filter', | 232 dest='test_filter', |
222 help='googletest-style filter string.') | 233 help='googletest-style filter string.') |
223 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file', | 234 filter_group.add_argument('--gtest-filter-file', dest='test_filter_file', |
224 help='Path to file that contains googletest-style ' | 235 help='Path to file that contains googletest-style ' |
225 'filter strings. (Lines will be joined with ' | 236 'filter strings. (Lines will be joined with ' |
226 '":" to create a single filter string.)') | 237 '":" to create a single filter string.)') |
227 | 238 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 help='The relative filepath to a file containing ' | 339 help='The relative filepath to a file containing ' |
329 'command-line flags to set on the device') | 340 'command-line flags to set on the device') |
330 group.add_argument('--device-flags-file', default='', | 341 group.add_argument('--device-flags-file', default='', |
331 help='The relative filepath to a file containing ' | 342 help='The relative filepath to a file containing ' |
332 'command-line flags to set on the device') | 343 'command-line flags to set on the device') |
333 group.add_argument('--isolate_file_path', | 344 group.add_argument('--isolate_file_path', |
334 '--isolate-file-path', | 345 '--isolate-file-path', |
335 dest='isolate_file_path', | 346 dest='isolate_file_path', |
336 help='.isolate file path to override the default ' | 347 help='.isolate file path to override the default ' |
337 'path') | 348 'path') |
| 349 group.add_argument('--delete-stale-data', dest='delete_stale_data', |
| 350 action='store_true', |
| 351 help='Delete stale test data on the device.') |
338 | 352 |
339 AddCommonOptions(parser) | 353 AddCommonOptions(parser) |
340 AddDeviceOptions(parser) | 354 AddDeviceOptions(parser) |
341 AddRemoteDeviceOptions(parser) | 355 AddRemoteDeviceOptions(parser) |
342 | 356 |
343 | 357 |
344 def ProcessInstrumentationOptions(args): | 358 def ProcessInstrumentationOptions(args): |
345 """Processes options/arguments and populate |options| with defaults. | 359 """Processes options/arguments and populate |options| with defaults. |
346 | 360 |
347 Args: | 361 Args: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 args.screenshot_failures, | 395 args.screenshot_failures, |
382 args.wait_for_debugger, | 396 args.wait_for_debugger, |
383 args.coverage_dir, | 397 args.coverage_dir, |
384 args.test_apk, | 398 args.test_apk, |
385 args.test_apk_path, | 399 args.test_apk_path, |
386 args.test_apk_jar_path, | 400 args.test_apk_jar_path, |
387 args.test_runner, | 401 args.test_runner, |
388 args.test_support_apk_path, | 402 args.test_support_apk_path, |
389 args.device_flags, | 403 args.device_flags, |
390 args.isolate_file_path, | 404 args.isolate_file_path, |
391 args.set_asserts | 405 args.set_asserts, |
| 406 args.delete_stale_data |
392 ) | 407 ) |
393 | 408 |
394 | 409 |
395 def AddUIAutomatorTestOptions(parser): | 410 def AddUIAutomatorTestOptions(parser): |
396 """Adds UI Automator test options to |parser|.""" | 411 """Adds UI Automator test options to |parser|.""" |
397 | 412 |
398 group = parser.add_argument_group('UIAutomator Test Options') | 413 group = parser.add_argument_group('UIAutomator Test Options') |
399 AddJavaTestOptions(group) | 414 AddJavaTestOptions(group) |
400 group.add_argument( | 415 group.add_argument( |
401 '--package', required=True, choices=constants.PACKAGE_INFO.keys(), | 416 '--package', required=True, choices=constants.PACKAGE_INFO.keys(), |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 group.add_argument( | 599 group.add_argument( |
585 '--no-timeout', action='store_true', | 600 '--no-timeout', action='store_true', |
586 help=('Do not impose a timeout. Each perf step is responsible for ' | 601 help=('Do not impose a timeout. Each perf step is responsible for ' |
587 'implementing the timeout logic.')) | 602 'implementing the timeout logic.')) |
588 group.add_argument( | 603 group.add_argument( |
589 '-f', '--test-filter', | 604 '-f', '--test-filter', |
590 help=('Test filter (will match against the names listed in --steps).')) | 605 help=('Test filter (will match against the names listed in --steps).')) |
591 group.add_argument( | 606 group.add_argument( |
592 '--dry-run', action='store_true', | 607 '--dry-run', action='store_true', |
593 help='Just print the steps without executing.') | 608 help='Just print the steps without executing.') |
| 609 # Uses 0.1 degrees C because that's what Android does. |
| 610 group.add_argument( |
| 611 '--max-battery-temp', type=int, |
| 612 help='Only start tests when the battery is at or below the given ' |
| 613 'temperature (0.1 C)') |
594 group.add_argument('single_step_command', nargs='*', action=SingleStepAction, | 614 group.add_argument('single_step_command', nargs='*', action=SingleStepAction, |
595 help='If --single-step is specified, the command to run.') | 615 help='If --single-step is specified, the command to run.') |
596 AddCommonOptions(parser) | 616 AddCommonOptions(parser) |
597 AddDeviceOptions(parser) | 617 AddDeviceOptions(parser) |
598 | 618 |
599 | 619 |
600 def ProcessPerfTestOptions(args): | 620 def ProcessPerfTestOptions(args): |
601 """Processes all perf test options. | 621 """Processes all perf test options. |
602 | 622 |
603 Args: | 623 Args: |
604 args: argparse.Namespace object. | 624 args: argparse.Namespace object. |
605 | 625 |
606 Returns: | 626 Returns: |
607 A PerfOptions named tuple which contains all options relevant to | 627 A PerfOptions named tuple which contains all options relevant to |
608 perf tests. | 628 perf tests. |
609 """ | 629 """ |
610 # TODO(jbudorick): Move single_step handling down into the perf tests. | 630 # TODO(jbudorick): Move single_step handling down into the perf tests. |
611 if args.single_step: | 631 if args.single_step: |
612 args.single_step = ' '.join(args.single_step_command) | 632 args.single_step = ' '.join(args.single_step_command) |
613 # TODO(jbudorick): Get rid of PerfOptions. | 633 # TODO(jbudorick): Get rid of PerfOptions. |
614 return perf_test_options.PerfOptions( | 634 return perf_test_options.PerfOptions( |
615 args.steps, args.flaky_steps, args.output_json_list, | 635 args.steps, args.flaky_steps, args.output_json_list, |
616 args.print_step, args.no_timeout, args.test_filter, | 636 args.print_step, args.no_timeout, args.test_filter, |
617 args.dry_run, args.single_step, args.collect_chartjson_data, | 637 args.dry_run, args.single_step, args.collect_chartjson_data, |
618 args.output_chartjson_data) | 638 args.output_chartjson_data, args.max_battery_temp) |
619 | 639 |
620 | 640 |
621 def AddPythonTestOptions(parser): | 641 def AddPythonTestOptions(parser): |
622 group = parser.add_argument_group('Python Test Options') | 642 group = parser.add_argument_group('Python Test Options') |
623 group.add_argument( | 643 group.add_argument( |
624 '-s', '--suite', dest='suite_name', metavar='SUITE_NAME', | 644 '-s', '--suite', dest='suite_name', metavar='SUITE_NAME', |
625 choices=constants.PYTHON_UNIT_TEST_SUITES.keys(), | 645 choices=constants.PYTHON_UNIT_TEST_SUITES.keys(), |
626 help='Name of the test suite to run.') | 646 help='Name of the test suite to run.') |
627 AddCommonOptions(parser) | 647 AddCommonOptions(parser) |
628 | 648 |
629 | 649 |
630 def _RunGTests(args, devices): | 650 def _RunGTests(args, devices): |
631 """Subcommand of RunTestsCommands which runs gtests.""" | 651 """Subcommand of RunTestsCommands which runs gtests.""" |
632 exit_code = 0 | 652 exit_code = 0 |
633 for suite_name in args.suite_name: | 653 for suite_name in args.suite_name: |
634 # TODO(jbudorick): Either deprecate multi-suite or move its handling down | 654 # TODO(jbudorick): Either deprecate multi-suite or move its handling down |
635 # into the gtest code. | 655 # into the gtest code. |
636 gtest_options = gtest_test_options.GTestOptions( | 656 gtest_options = gtest_test_options.GTestOptions( |
637 args.tool, | 657 args.tool, |
638 args.test_filter, | 658 args.test_filter, |
639 args.run_disabled, | 659 args.run_disabled, |
640 args.test_arguments, | 660 args.test_arguments, |
641 args.timeout, | 661 args.timeout, |
642 args.isolate_file_path, | 662 args.isolate_file_path, |
643 suite_name) | 663 suite_name, |
| 664 args.app_data_files, |
| 665 args.app_data_file_dir, |
| 666 args.delete_stale_data) |
644 runner_factory, tests = gtest_setup.Setup(gtest_options, devices) | 667 runner_factory, tests = gtest_setup.Setup(gtest_options, devices) |
645 | 668 |
646 results, test_exit_code = test_dispatcher.RunTests( | 669 results, test_exit_code = test_dispatcher.RunTests( |
647 tests, runner_factory, devices, shard=True, test_timeout=None, | 670 tests, runner_factory, devices, shard=True, test_timeout=None, |
648 num_retries=args.num_retries) | 671 num_retries=args.num_retries) |
649 | 672 |
650 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE: | 673 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE: |
651 exit_code = test_exit_code | 674 exit_code = test_exit_code |
652 | 675 |
653 report_results.LogFull( | 676 report_results.LogFull( |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 if command in constants.LOCAL_MACHINE_TESTS: | 927 if command in constants.LOCAL_MACHINE_TESTS: |
905 devices = [] | 928 devices = [] |
906 else: | 929 else: |
907 devices = _GetAttachedDevices(args.test_device) | 930 devices = _GetAttachedDevices(args.test_device) |
908 | 931 |
909 forwarder.Forwarder.RemoveHostLog() | 932 forwarder.Forwarder.RemoveHostLog() |
910 if not ports.ResetTestServerPortAllocation(): | 933 if not ports.ResetTestServerPortAllocation(): |
911 raise Exception('Failed to reset test server port.') | 934 raise Exception('Failed to reset test server port.') |
912 | 935 |
913 if command == 'gtest': | 936 if command == 'gtest': |
| 937 if args.suite_name[0] in gtest_test_instance.BROWSER_TEST_SUITES: |
| 938 return RunTestsInPlatformMode(args, parser) |
914 return _RunGTests(args, devices) | 939 return _RunGTests(args, devices) |
915 elif command == 'linker': | 940 elif command == 'linker': |
916 return _RunLinkerTests(args, devices) | 941 return _RunLinkerTests(args, devices) |
917 elif command == 'instrumentation': | 942 elif command == 'instrumentation': |
918 return _RunInstrumentationTests(args, devices) | 943 return _RunInstrumentationTests(args, devices) |
919 elif command == 'uiautomator': | 944 elif command == 'uiautomator': |
920 return _RunUIAutomatorTests(args, devices) | 945 return _RunUIAutomatorTests(args, devices) |
921 elif command == 'junit': | 946 elif command == 'junit': |
922 return _RunJUnitTests(args) | 947 return _RunJUnitTests(args) |
923 elif command == 'monkey': | 948 elif command == 'monkey': |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 if e.is_infra_error: | 1052 if e.is_infra_error: |
1028 return constants.INFRA_EXIT_CODE | 1053 return constants.INFRA_EXIT_CODE |
1029 return constants.ERROR_EXIT_CODE | 1054 return constants.ERROR_EXIT_CODE |
1030 except: # pylint: disable=W0702 | 1055 except: # pylint: disable=W0702 |
1031 logging.exception('Unrecognized error occurred.') | 1056 logging.exception('Unrecognized error occurred.') |
1032 return constants.ERROR_EXIT_CODE | 1057 return constants.ERROR_EXIT_CODE |
1033 | 1058 |
1034 | 1059 |
1035 if __name__ == '__main__': | 1060 if __name__ == '__main__': |
1036 sys.exit(main()) | 1061 sys.exit(main()) |
OLD | NEW |