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.
5 """Runs a monkey test on a single device."""
10 from pylib
import constants
11 from pylib
.base
import base_test_result
12 from pylib
.base
import base_test_runner
13 from pylib
.device
import device_errors
14 from pylib
.device
import intent
16 _CHROME_PACKAGE
= constants
.PACKAGE_INFO
['chrome'].package
18 class TestRunner(base_test_runner
.BaseTestRunner
):
19 """A TestRunner instance runs a monkey test on a single device."""
21 def __init__(self
, test_options
, device
, _
):
22 super(TestRunner
, self
).__init
__(device
, None)
23 self
._options
= test_options
24 self
._package
= constants
.PACKAGE_INFO
[self
._options
.package
].package
25 self
._activity
= constants
.PACKAGE_INFO
[self
._options
.package
].activity
27 def _LaunchMonkeyTest(self
):
28 """Runs monkey test for a given package.
31 Output from the monkey command on the device.
34 timeout_ms
= self
._options
.event_count
* self
._options
.throttle
* 1.5
37 '-p %s' % self
._package
,
38 ' '.join(['-c %s' % c
for c
in self
._options
.category
]),
39 '--throttle %d' % self
._options
.throttle
,
40 '-s %d' % (self
._options
.seed
or random
.randint(1, 100)),
41 '-v ' * self
._options
.verbose_count
,
42 '--monitor-native-crashes',
43 '--kill-process-after-error',
44 self
._options
.extra_args
,
45 '%d' % self
._options
.event_count
]
46 return self
.device
.RunShellCommand(' '.join(cmd
), timeout
=timeout_ms
)
48 def RunTest(self
, test_name
):
49 """Run a Monkey test on the device.
52 test_name: String to use for logging the test result.
55 A tuple of (TestRunResults, retry).
57 self
.device
.StartActivity(
58 intent
.Intent(package
=self
._package
, activity
=self
._activity
,
59 action
='android.intent.action.MAIN'),
60 blocking
=True, force_stop
=True)
62 # Chrome crashes are not always caught by Monkey test runner.
63 # Verify Chrome has the same PID before and after the test.
64 before_pids
= self
.device
.GetPids(self
._package
)
69 output
= '\n'.join(self
._LaunchMonkeyTest
())
70 after_pids
= self
.device
.GetPids(self
._package
)
73 if not self
._package
in before_pids
:
74 logging
.error('Failed to start the process.')
75 elif not self
._package
in after_pids
:
76 logging
.error('Process %s has died.', before_pids
[self
._package
])
77 elif before_pids
[self
._package
] != after_pids
[self
._package
]:
78 logging
.error('Detected process restart %s -> %s',
79 before_pids
[self
._package
], after_pids
[self
._package
])
83 results
= base_test_result
.TestRunResults()
84 success_pattern
= 'Events injected: %d' % self
._options
.event_count
85 if success_pattern
in output
and not crashed
:
86 result
= base_test_result
.BaseTestResult(
87 test_name
, base_test_result
.ResultType
.PASS
, log
=output
)
89 result
= base_test_result
.BaseTestResult(
90 test_name
, base_test_result
.ResultType
.FAIL
, log
=output
)
91 if 'chrome' in self
._options
.package
:
92 logging
.warning('Starting MinidumpUploadService...')
93 # TODO(jbudorick): Update this after upstreaming.
94 minidump_intent
= intent
.Intent(
95 action
='%s.crash.ACTION_FIND_ALL' % _CHROME_PACKAGE
,
96 package
=self
._package
,
97 activity
='%s.crash.MinidumpUploadService' % _CHROME_PACKAGE
)
99 self
.device
.RunShellCommand(
100 ['am', 'startservice'] + minidump_intent
.am_args
,
101 as_root
=True, check_return
=True)
102 except device_errors
.CommandFailedError
:
103 logging
.exception('Failed to start MinidumpUploadService')
105 results
.AddResult(result
)
106 return results
, False