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 7import logging 8import random 9 10from pylib import constants 11from pylib.base import base_test_result 12from pylib.base import base_test_runner 13from pylib.device import intent 14 15class 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.device.RunShellCommand(' '.join(cmd), timeout=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.device.StartActivity( 55 intent.Intent(package=self._package, activity=self._activity, 56 action='android.intent.action.MAIN'), 57 blocking=True, force_stop=True) 58 59 # Chrome crashes are not always caught by Monkey test runner. 60 # Verify Chrome has the same PID before and after the test. 61 before_pids = self.device.GetPids(self._package) 62 63 # Run the test. 64 output = '' 65 if before_pids: 66 output = '\n'.join(self._LaunchMonkeyTest()) 67 after_pids = self.device.GetPids(self._package) 68 69 crashed = True 70 if not self._package in before_pids: 71 logging.error('Failed to start the process.') 72 elif not self._package in after_pids: 73 logging.error('Process %s has died.', before_pids[self._package]) 74 elif before_pids[self._package] != after_pids[self._package]: 75 logging.error('Detected process restart %s -> %s', 76 before_pids[self._package], after_pids[self._package]) 77 else: 78 crashed = False 79 80 results = base_test_result.TestRunResults() 81 success_pattern = 'Events injected: %d' % self._options.event_count 82 if success_pattern in output and not crashed: 83 result = base_test_result.BaseTestResult( 84 test_name, base_test_result.ResultType.PASS, log=output) 85 else: 86 result = base_test_result.BaseTestResult( 87 test_name, base_test_result.ResultType.FAIL, log=output) 88 if 'chrome' in self._options.package: 89 logging.warning('Starting MinidumpUploadService...') 90 try: 91 self.device.old_interface.StartCrashUploadService(self._package) 92 except AssertionError as e: 93 logging.error('Failed to start MinidumpUploadService: %s', e) 94 results.AddResult(result) 95 return results, False 96