OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 """Runs the Monkey tests on one or more devices.""" | |
7 import logging | |
8 import optparse | |
9 import random | |
10 import sys | |
11 | |
12 from pylib.base import base_test_result | |
13 from pylib.base import test_dispatcher | |
14 from pylib.host_driven import test_case | |
15 from pylib.host_driven import test_runner | |
16 from pylib.utils import report_results | |
17 from pylib.utils import test_options_parser | |
18 | |
19 | |
20 class MonkeyTest(test_case.HostDrivenTestCase): | |
21 def __init__(self, test_name, package_name, activity_name, category, seed, | |
22 throttle, event_count, verbosity, extra_args): | |
23 """Create a MonkeyTest object. | |
24 | |
25 Args: | |
26 test_name: Name of the method to run for this test object. | |
27 package_name: Allowed package. | |
28 activity_name: Name of the activity to start. | |
29 category: A list of allowed categories. | |
30 seed: Seed value for pseduo-random generator. Same seed value | |
31 generates the same sequence of events. Seed is randomized by default. | |
32 throttle: Delay between events (ms). | |
33 event_count: Number of events to generate. | |
34 verbosity: Verbosity level [0-3]. | |
35 extra_args: A string of other args to pass to the command verbatim. | |
36 """ | |
37 super(MonkeyTest, self).__init__(test_name) | |
38 self.package_name = package_name | |
39 self.activity_name = activity_name | |
40 self.category = category | |
41 self.seed = seed or random.randint(1, 100) | |
42 self.throttle = throttle | |
43 self.event_count = event_count | |
44 self.verbosity = verbosity | |
45 self.extra_args = extra_args | |
46 | |
47 def testMonkey(self): | |
48 # Launch and wait for Chrome to launch. | |
49 self.adb.StartActivity(self.package_name, | |
50 self.activity_name, | |
51 wait_for_completion=True, | |
52 action='android.intent.action.MAIN', | |
53 force_stop=True) | |
54 | |
55 # Chrome crashes are not always caught by Monkey test runner. | |
56 # Verify Chrome has the same PID before and after the test. | |
57 before_pids = self.adb.ExtractPid(self.package_name) | |
58 | |
59 # Run the test. | |
60 output = '' | |
61 if before_pids: | |
62 output = '\n'.join(self._LaunchMonkeyTest()) | |
63 after_pids = self.adb.ExtractPid(self.package_name) | |
64 | |
65 crashed = (not before_pids or not after_pids | |
66 or after_pids[0] != before_pids[0]) | |
67 | |
68 results = base_test_result.TestRunResults() | |
69 if 'Monkey finished' in output and not crashed: | |
70 result = base_test_result.BaseTestResult( | |
71 self.tagged_name, base_test_result.ResultType.PASS, log=output) | |
72 else: | |
73 result = base_test_result.BaseTestResult( | |
74 self.tagged_name, base_test_result.ResultType.FAIL, log=output) | |
75 results.AddResult(result) | |
76 return results | |
77 | |
78 def _LaunchMonkeyTest(self): | |
79 """Runs monkey test for a given package. | |
80 | |
81 Returns: | |
82 Output from the monkey command on the device. | |
83 """ | |
84 | |
85 timeout_ms = self.event_count * self.throttle * 1.5 | |
86 | |
87 cmd = ['monkey', | |
88 '-p %s' % self.package_name, | |
89 ' '.join(['-c %s' % c for c in self.category]), | |
90 '--throttle %d' % self.throttle, | |
91 '-s %d' % self.seed, | |
92 '-v ' * self.verbosity, | |
93 '--monitor-native-crashes', | |
94 '--kill-process-after-error', | |
95 self.extra_args, | |
96 '%d' % self.event_count] | |
97 return self.adb.RunShellCommand(' '.join(cmd), timeout_time=timeout_ms) | |
98 | |
99 | |
100 def RunMonkeyTests(options): | |
101 """Runs the Monkey tests, replicating it if there multiple devices.""" | |
102 logger = logging.getLogger() | |
103 logger.setLevel(logging.DEBUG) | |
104 | |
105 # Actually run the tests. | |
106 logging.debug('Running monkey tests.') | |
107 available_tests = [ | |
108 MonkeyTest('testMonkey', options.package_name, options.activity_name, | |
109 category=options.category, seed=options.seed, | |
110 throttle=options.throttle, event_count=options.event_count, | |
111 verbosity=options.verbosity, extra_args=options.extra_args)] | |
112 | |
113 def TestRunnerFactory(device, shard_index): | |
114 return test_runner.HostDrivenTestRunner( | |
115 device, shard_index, '', options.build_type, False, False) | |
116 | |
117 results, exit_code = test_dispatcher.RunTests( | |
118 available_tests, TestRunnerFactory, False, None, shard=False, | |
119 build_type=options.build_type, num_retries=0) | |
120 | |
121 report_results.LogFull( | |
122 results=results, | |
123 test_type='Monkey', | |
124 test_package='Monkey', | |
125 build_type=options.build_type) | |
126 | |
127 return exit_code | |
128 | |
129 | |
130 def main(): | |
131 desc = 'Run the Monkey tests on 1 or more devices.' | |
132 parser = optparse.OptionParser(description=desc) | |
133 test_options_parser.AddBuildTypeOption(parser) | |
134 parser.add_option('--package-name', help='Allowed package.') | |
135 parser.add_option('--activity-name', | |
136 default='com.google.android.apps.chrome.Main', | |
137 help='Name of the activity to start [default: %default].') | |
138 parser.add_option('--category', default='', | |
139 help='A list of allowed categories [default: %default].') | |
140 parser.add_option('--throttle', default=100, type='int', | |
141 help='Delay between events (ms) [default: %default]. ') | |
142 parser.add_option('--seed', type='int', | |
143 help=('Seed value for pseudo-random generator. Same seed ' | |
144 'value generates the same sequence of events. Seed ' | |
145 'is randomized by default.')) | |
146 parser.add_option('--event-count', default=10000, type='int', | |
147 help='Number of events to generate [default: %default].') | |
148 parser.add_option('--verbosity', default=1, type='int', | |
149 help='Verbosity level [0-3] [default: %default].') | |
150 parser.add_option('--extra-args', default='', | |
151 help=('String of other args to pass to the command verbatim' | |
152 ' [default: "%default"].')) | |
153 (options, args) = parser.parse_args() | |
154 | |
155 if args: | |
156 parser.print_help(sys.stderr) | |
157 parser.error('Unknown arguments: %s' % args) | |
158 | |
159 if not options.package_name: | |
160 parser.print_help(sys.stderr) | |
161 parser.error('Missing package name') | |
162 | |
163 if options.category: | |
164 options.category = options.category.split(',') | |
165 | |
166 RunMonkeyTests(options) | |
167 | |
168 | |
169 if __name__ == '__main__': | |
170 main() | |
OLD | NEW |