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 collections | 9 import collections |
10 import logging | 10 import logging |
11 import optparse | 11 import optparse |
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 android_commands | 19 from pylib import android_commands |
20 from pylib import constants | 20 from pylib import constants |
21 from pylib import forwarder | 21 from pylib import forwarder |
22 from pylib import ports | 22 from pylib import ports |
23 from pylib.base import base_test_result | 23 from pylib.base import base_test_result |
| 24 from pylib.base import environment_factory |
24 from pylib.base import test_dispatcher | 25 from pylib.base import test_dispatcher |
| 26 from pylib.base import test_instance_factory |
| 27 from pylib.base import test_run_factory |
25 from pylib.gtest import gtest_config | 28 from pylib.gtest import gtest_config |
26 from pylib.gtest import setup as gtest_setup | 29 from pylib.gtest import setup as gtest_setup |
27 from pylib.gtest import test_options as gtest_test_options | 30 from pylib.gtest import test_options as gtest_test_options |
28 from pylib.linker import setup as linker_setup | 31 from pylib.linker import setup as linker_setup |
29 from pylib.host_driven import setup as host_driven_setup | 32 from pylib.host_driven import setup as host_driven_setup |
30 from pylib.instrumentation import setup as instrumentation_setup | 33 from pylib.instrumentation import setup as instrumentation_setup |
31 from pylib.instrumentation import test_options as instrumentation_test_options | 34 from pylib.instrumentation import test_options as instrumentation_test_options |
32 from pylib.junit import setup as junit_setup | 35 from pylib.junit import setup as junit_setup |
33 from pylib.junit import test_dispatcher as junit_dispatcher | 36 from pylib.junit import test_dispatcher as junit_dispatcher |
34 from pylib.monkey import setup as monkey_setup | 37 from pylib.monkey import setup as monkey_setup |
35 from pylib.monkey import test_options as monkey_test_options | 38 from pylib.monkey import test_options as monkey_test_options |
36 from pylib.perf import setup as perf_setup | 39 from pylib.perf import setup as perf_setup |
37 from pylib.perf import test_options as perf_test_options | 40 from pylib.perf import test_options as perf_test_options |
38 from pylib.perf import test_runner as perf_test_runner | 41 from pylib.perf import test_runner as perf_test_runner |
39 from pylib.uiautomator import setup as uiautomator_setup | 42 from pylib.uiautomator import setup as uiautomator_setup |
40 from pylib.uiautomator import test_options as uiautomator_test_options | 43 from pylib.uiautomator import test_options as uiautomator_test_options |
41 from pylib.utils import apk_helper | 44 from pylib.utils import apk_helper |
42 from pylib.utils import command_option_parser | 45 from pylib.utils import command_option_parser |
43 from pylib.utils import report_results | 46 from pylib.utils import report_results |
44 from pylib.utils import reraiser_thread | 47 from pylib.utils import reraiser_thread |
45 from pylib.utils import run_tests_helper | 48 from pylib.utils import run_tests_helper |
46 | 49 |
47 | 50 |
48 HOST_TESTS = ['junit', 'python'] | |
49 | |
50 | |
51 def AddCommonOptions(option_parser): | 51 def AddCommonOptions(option_parser): |
52 """Adds all common options to |option_parser|.""" | 52 """Adds all common options to |option_parser|.""" |
53 | 53 |
54 group = optparse.OptionGroup(option_parser, 'Common Options') | 54 group = optparse.OptionGroup(option_parser, 'Common Options') |
55 default_build_type = os.environ.get('BUILDTYPE', 'Debug') | 55 default_build_type = os.environ.get('BUILDTYPE', 'Debug') |
56 group.add_option('--debug', action='store_const', const='Debug', | 56 group.add_option('--debug', action='store_const', const='Debug', |
57 dest='build_type', default=default_build_type, | 57 dest='build_type', default=default_build_type, |
58 help=('If set, run test suites under out/Debug. ' | 58 help=('If set, run test suites under out/Debug. ' |
59 'Default is env var BUILDTYPE or Debug.')) | 59 'Default is env var BUILDTYPE or Debug.')) |
60 group.add_option('--release', action='store_const', | 60 group.add_option('--release', action='store_const', |
(...skipping 10 matching lines...) Expand all Loading... |
71 group.add_option('-v', | 71 group.add_option('-v', |
72 '--verbose', | 72 '--verbose', |
73 dest='verbose_count', | 73 dest='verbose_count', |
74 default=0, | 74 default=0, |
75 action='count', | 75 action='count', |
76 help='Verbose level (multiple times for more)') | 76 help='Verbose level (multiple times for more)') |
77 group.add_option('--flakiness-dashboard-server', | 77 group.add_option('--flakiness-dashboard-server', |
78 dest='flakiness_dashboard_server', | 78 dest='flakiness_dashboard_server', |
79 help=('Address of the server that is hosting the ' | 79 help=('Address of the server that is hosting the ' |
80 'Chrome for Android flakiness dashboard.')) | 80 'Chrome for Android flakiness dashboard.')) |
| 81 group.add_option('--enable-platform-mode', action='store_true', |
| 82 help=('Run the test scripts in platform mode, which ' |
| 83 'conceptually separates the test runner from the ' |
| 84 '"device" (local or remote, real or emulated) on ' |
| 85 'which the tests are running. [experimental]')) |
| 86 group.add_option('-e', '--environment', default='local', |
| 87 help=('Test environment to run in. Must be one of: %s' % |
| 88 ', '.join(constants.VALID_ENVIRONMENTS))) |
81 option_parser.add_option_group(group) | 89 option_parser.add_option_group(group) |
82 | 90 |
83 | 91 |
84 def ProcessCommonOptions(options): | 92 def ProcessCommonOptions(options, error_func): |
85 """Processes and handles all common options.""" | 93 """Processes and handles all common options.""" |
86 run_tests_helper.SetLogLevel(options.verbose_count) | 94 run_tests_helper.SetLogLevel(options.verbose_count) |
87 constants.SetBuildType(options.build_type) | 95 constants.SetBuildType(options.build_type) |
88 if options.build_directory: | 96 if options.build_directory: |
89 constants.SetBuildDirectory(options.build_directory) | 97 constants.SetBuildDirectory(options.build_directory) |
| 98 if options.environment not in constants.VALID_ENVIRONMENTS: |
| 99 error_func('--environment must be one of: %s' % |
| 100 ', '.join(constants.VALID_ENVIRONMENTS)) |
90 | 101 |
91 | 102 |
92 def AddDeviceOptions(option_parser): | 103 def AddDeviceOptions(option_parser): |
93 group = optparse.OptionGroup(option_parser, 'Device Options') | 104 group = optparse.OptionGroup(option_parser, 'Device Options') |
94 group.add_option('-c', dest='cleanup_test_files', | 105 group.add_option('-c', dest='cleanup_test_files', |
95 help='Cleanup test files on the device after run', | 106 help='Cleanup test files on the device after run', |
96 action='store_true') | 107 action='store_true') |
97 group.add_option('--tool', | 108 group.add_option('--tool', |
98 dest='tool', | 109 dest='tool', |
99 help=('Run the test under a tool ' | 110 help=('Run the test under a tool ' |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 # Check for extra arguments | 836 # Check for extra arguments |
826 if len(args) > 2 and command != 'perf': | 837 if len(args) > 2 and command != 'perf': |
827 option_parser.error('Unrecognized arguments: %s' % (' '.join(args[2:]))) | 838 option_parser.error('Unrecognized arguments: %s' % (' '.join(args[2:]))) |
828 return constants.ERROR_EXIT_CODE | 839 return constants.ERROR_EXIT_CODE |
829 if command == 'perf': | 840 if command == 'perf': |
830 if ((options.single_step and len(args) <= 2) or | 841 if ((options.single_step and len(args) <= 2) or |
831 (not options.single_step and len(args) > 2)): | 842 (not options.single_step and len(args) > 2)): |
832 option_parser.error('Unrecognized arguments: %s' % (' '.join(args))) | 843 option_parser.error('Unrecognized arguments: %s' % (' '.join(args))) |
833 return constants.ERROR_EXIT_CODE | 844 return constants.ERROR_EXIT_CODE |
834 | 845 |
835 ProcessCommonOptions(options) | 846 ProcessCommonOptions(options, option_parser.error) |
836 | 847 |
837 if command in HOST_TESTS: | 848 if options.enable_platform_mode: |
| 849 return RunTestsInPlatformMode(command, options, option_parser) |
| 850 |
| 851 if command in constants.LOCAL_MACHINE_TESTS: |
838 devices = [] | 852 devices = [] |
839 else: | 853 else: |
840 devices = _GetAttachedDevices(options.test_device) | 854 devices = _GetAttachedDevices(options.test_device) |
841 | 855 |
842 forwarder.Forwarder.RemoveHostLog() | 856 forwarder.Forwarder.RemoveHostLog() |
843 if not ports.ResetTestServerPortAllocation(): | 857 if not ports.ResetTestServerPortAllocation(): |
844 raise Exception('Failed to reset test server port.') | 858 raise Exception('Failed to reset test server port.') |
845 | 859 |
846 if command == 'gtest': | 860 if command == 'gtest': |
847 return _RunGTests(options, devices) | 861 return _RunGTests(options, devices) |
848 elif command == 'linker': | 862 elif command == 'linker': |
849 return _RunLinkerTests(options, devices) | 863 return _RunLinkerTests(options, devices) |
850 elif command == 'instrumentation': | 864 elif command == 'instrumentation': |
851 return _RunInstrumentationTests(options, option_parser.error, devices) | 865 return _RunInstrumentationTests(options, option_parser.error, devices) |
852 elif command == 'uiautomator': | 866 elif command == 'uiautomator': |
853 return _RunUIAutomatorTests(options, option_parser.error, devices) | 867 return _RunUIAutomatorTests(options, option_parser.error, devices) |
854 elif command == 'junit': | 868 elif command == 'junit': |
855 return _RunJUnitTests(options, option_parser.error) | 869 return _RunJUnitTests(options, option_parser.error) |
856 elif command == 'monkey': | 870 elif command == 'monkey': |
857 return _RunMonkeyTests(options, option_parser.error, devices) | 871 return _RunMonkeyTests(options, option_parser.error, devices) |
858 elif command == 'perf': | 872 elif command == 'perf': |
859 return _RunPerfTests(options, args, option_parser.error) | 873 return _RunPerfTests(options, args, option_parser.error) |
860 elif command == 'python': | 874 elif command == 'python': |
861 return _RunPythonTests(options, option_parser.error) | 875 return _RunPythonTests(options, option_parser.error) |
862 else: | 876 else: |
863 raise Exception('Unknown test type.') | 877 raise Exception('Unknown test type.') |
864 | 878 |
865 | 879 |
| 880 _SUPPORTED_IN_PLATFORM_MODE = [ |
| 881 # TODO(jbudorick): Add support for more test types. |
| 882 'gtest', |
| 883 ] |
| 884 |
| 885 |
| 886 def RunTestsInPlatformMode(command, options, option_parser): |
| 887 |
| 888 if command not in _SUPPORTED_IN_PLATFORM_MODE: |
| 889 option_parser.error('%s is not yet supported in platform mode' % command) |
| 890 |
| 891 with environment_factory.CreateEnvironment( |
| 892 command, options, option_parser.error) as env: |
| 893 with test_instance_factory.CreateTestInstance( |
| 894 command, options, option_parser.error) as test: |
| 895 with test_run_factory.CreateTestRun( |
| 896 options, env, test, option_parser.error) as test_run: |
| 897 results = test_run.RunTests() |
| 898 |
| 899 report_results.LogFull( |
| 900 results=results, |
| 901 test_type=test.TestType(), |
| 902 test_package=test_run.TestPackage(), |
| 903 annotation=options.annotations, |
| 904 flakiness_server=options.flakiness_dashboard_server) |
| 905 |
| 906 return results |
| 907 |
| 908 |
866 def HelpCommand(command, _options, args, option_parser): | 909 def HelpCommand(command, _options, args, option_parser): |
867 """Display help for a certain command, or overall help. | 910 """Display help for a certain command, or overall help. |
868 | 911 |
869 Args: | 912 Args: |
870 command: String indicating the command that was received to trigger | 913 command: String indicating the command that was received to trigger |
871 this function. | 914 this function. |
872 options: optparse options dictionary. unused. | 915 options: optparse options dictionary. unused. |
873 args: List of extra args from optparse. | 916 args: List of extra args from optparse. |
874 option_parser: optparse.OptionParser object. | 917 option_parser: optparse.OptionParser object. |
875 | 918 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 | 979 |
937 def main(): | 980 def main(): |
938 signal.signal(signal.SIGUSR1, DumpThreadStacks) | 981 signal.signal(signal.SIGUSR1, DumpThreadStacks) |
939 option_parser = command_option_parser.CommandOptionParser( | 982 option_parser = command_option_parser.CommandOptionParser( |
940 commands_dict=VALID_COMMANDS) | 983 commands_dict=VALID_COMMANDS) |
941 return command_option_parser.ParseAndExecute(option_parser) | 984 return command_option_parser.ParseAndExecute(option_parser) |
942 | 985 |
943 | 986 |
944 if __name__ == '__main__': | 987 if __name__ == '__main__': |
945 sys.exit(main()) | 988 sys.exit(main()) |
OLD | NEW |