1 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """Runs a monkey test on a single device.""" 6 7 import logging 8 import random 9 10 from pylib import constants 11 from pylib.base import base_test_result 12 from pylib.base import base_test_runner 13 14 15 class TestRunner(base_test_runner.BaseTestRunner): 16 """A TestRunner instance runs a monkey test on a single device.""" 17 18 def __init__(self, test_options, device, _): 19 super(TestRunner, self).__init__(device, None) 20 self._options = test_options 21 self._package = constants.PACKAGE_INFO[self._options.package].package 22 self._activity = constants.PACKAGE_INFO[self._options.package].activity 23 24 def _LaunchMonkeyTest(self): 25 """Runs monkey test for a given package. 26 27 Returns: 28 Output from the monkey command on the device. 29 """ 30 31 timeout_ms = self._options.event_count * self._options.throttle * 1.5 32 33 cmd = ['monkey', 34 '-p %s' % self._package, 35 ' '.join(['-c %s' % c for c in self._options.category]), 36 '--throttle %d' % self._options.throttle, 37 '-s %d' % (self._options.seed or random.randint(1, 100)), 38 '-v ' * self._options.verbose_count, 39 '--monitor-native-crashes', 40 '--kill-process-after-error', 41 self._options.extra_args, 42 '%d' % self._options.event_count] 43 return self.adb.RunShellCommand(' '.join(cmd), timeout_time=timeout_ms) 44 45 def RunTest(self, test_name): 46 """Run a Monkey test on the device. 47 48 Args: 49 test_name: String to use for logging the test result. 50 51 Returns: 52 A tuple of (TestRunResults, retry). 53 """ 54 self.adb.StartActivity(self._package, 55 self._activity, 56 wait_for_completion=True, 57 action='android.intent.action.MAIN', 58 force_stop=True) 59 60 # Chrome crashes are not always caught by Monkey test runner. 61 # Verify Chrome has the same PID before and after the test. 62 before_pids = self.adb.ExtractPid(self._package) 63 64 # Run the test. 65 output = '' 66 if before_pids: 67 output = '\n'.join(self._LaunchMonkeyTest()) 68 after_pids = self.adb.ExtractPid(self._package) 69 70 crashed = True 71 if not before_pids: 72 logging.error('Failed to start the process.') 73 elif not after_pids: 74 logging.error('Process %s has died.', before_pids[0]) 75 elif before_pids[0] != after_pids[0]: 76 logging.error('Detected process restart %s -> %s', 77 before_pids[0], after_pids[0]) 78 else: 79 crashed = False 80 81 results = base_test_result.TestRunResults() 82 success_pattern = 'Events injected: %d' % self._options.event_count 83 if success_pattern in output and not crashed: 84 result = base_test_result.BaseTestResult( 85 test_name, base_test_result.ResultType.PASS, log=output) 86 else: 87 result = base_test_result.BaseTestResult( 88 test_name, base_test_result.ResultType.FAIL, log=output) 89 if 'chrome' in self._options.package: 90 logging.warning('Starting MinidumpUploadService...') 91 try: 92 self.adb.StartCrashUploadService(self._package) 93 except AssertionError as e: 94 logging.error('Failed to start MinidumpUploadService: %s', e) 95 results.AddResult(result) 96 return results, False 97