summaryrefslogtreecommitdiffstats
path: root/build/android/run_monkey_test.py
blob: ab759156d1b190adf4479ccaa53a1389797073f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Runs the Monkey tests on one or more devices."""
import logging
import optparse
import time

from pylib import android_commands
from pylib import python_test_base
from pylib import python_test_caller
from pylib import python_test_sharder
from pylib import test_options_parser
from pylib import test_result


class MonkeyTest(python_test_base.PythonTestBase):
  def __init__(self, test_name, options):
    self.options = options
    super(MonkeyTest, self).__init__(test_name)

  def testMonkey(self):
    start_ms = int(time.time()) * 1000

    # Launch and wait for Chrome to launch.
    self.adb.StartActivity(self.options['package_name'],
                           self.options.pop('activity_name'),
                           wait_for_completion=True,
                           action='android.intent.action.MAIN')

    # Chrome crashes are not always caught by Monkey test runner.
    # Verify Chrome has the same PID before and after the test.
    before_pids = self.adb.ExtractPid(self.options['package_name'])

    # Run the test.
    output = ''
    duration_ms = 0
    if before_pids:
      output = '\n'.join(self.adb.RunMonkey(**self.options))
      duration_ms = int(time.time()) * 1000 - start_ms
      after_pids = self.adb.ExtractPid(self.options['package_name'])

    crashed = (not before_pids or not after_pids
               or after_pids[0] != before_pids[0])
    result = test_result.SingleTestResult(self.qualified_name, start_ms,
                                          duration_ms, log=output)
    results = test_result.TestResults()

    if 'Monkey finished' in output and not crashed:
      results.ok = [result]
    else:
      results.crashed = [result]

    return results


def DispatchPythonTests(options):
  """Dispatches the Monkey tests, sharding it if there multiple devices."""
  logger = logging.getLogger()
  logger.setLevel(logging.DEBUG)

  build_type = options.pop('build_type')
  available_tests = [MonkeyTest('testMonkey', options)]
  attached_devices = android_commands.GetAttachedDevices()
  if not attached_devices:
    raise Exception('You have no devices attached or visible!')

  # Actually run the tests.
  logging.debug('Running monkey tests.')
  available_tests *= len(attached_devices)
  sharder = python_test_sharder.PythonTestSharder(
      attached_devices, 1, available_tests)
  result = sharder.RunShardedTests()
  result.LogFull('Monkey', 'Monkey', build_type)
  result.PrintAnnotation()


def main():
  desc = 'Run the Monkey tests on 1 or more devices.'
  parser = optparse.OptionParser(description=desc)
  test_options_parser.AddBuildTypeOption(parser)
  parser.add_option('--package-name',
                    help='Allowed package.')
  parser.add_option('--activity-name',
                    default='com.google.android.apps.chrome.Main',
                    help='Name of the activity to start [default: %default].')
  parser.add_option('--category',
                    help='A list of allowed categories [default: ""].')
  parser.add_option('--throttle', default=100, type='int',
                    help='Delay between events (ms) [default: %default]. ')
  parser.add_option('--seed', type='int',
                    help='Seed value for pseduo-random generator. Same seed'
                         ' value generates the same sequence of events. Seed is'
                         ' randomized by default.')
  parser.add_option('--event-count', default=10000, type='int',
                    help='Number of events to generate [default: %default].')
  parser.add_option('--verbosity', default=1, type='int',
                    help='Verbosity level [0-3] [default: %default].')
  parser.add_option('--extra-args', default='',
                    help='String of other args to pass to the command verbatim'
                         ' [default: "%default"].')
  (options, args) = parser.parse_args()

  if args:
    parser.error('Unknown arguments: %s' % args)

  if not options.package_name:
    parser.error('Missing package name')

  if options.category:
    options.category = options.category.split(',')

  DispatchPythonTests(vars(options))


if __name__ == '__main__':
  main()