1#!/usr/bin/python
2
3"""Run page cycler tests using Android instrumentation.
4
5  First, you need to get an SD card or sdcard image that has page cycler tests.
6
7  Usage:
8    Run a single page cycler test:
9      run_page_cycler.py "file:///sdcard/webkit/page_cycler/moz/start.html\?auto=1\&iterations=10"
10"""
11
12import logging
13import optparse
14import os
15import subprocess
16import sys
17import time
18
19
20
21def main(options, args):
22  """Run the tests. Will call sys.exit when complete.
23
24  """
25
26  # Set up logging format.
27  log_level = logging.INFO
28  if options.verbose:
29    log_level = logging.DEBUG
30  logging.basicConfig(level=log_level,
31                      format='%(message)s')
32
33  # Include all tests if none are specified.
34  if not args:
35    print "need a URL, e.g. file:///sdcard/webkit/page_cycler/moz/start.html\?auto=1\&iterations=10"
36    print "  or remote:android-browser-test:80/page_cycler/"
37    sys.exit(1)
38  else:
39    path = ' '.join(args);
40
41  if path[:7] == "remote:":
42    remote_path = path[7:]
43  else:
44    remote_path = None
45
46  adb_cmd = "adb ";
47  if options.adb_options:
48    adb_cmd += options.adb_options
49
50  logging.info("Running the test ...")
51
52  # Count crashed tests.
53  crashed_tests = []
54
55  timeout_ms = '0'
56  if options.time_out_ms:
57    timeout_ms = options.time_out_ms
58
59  # Run test until it's done
60
61  run_load_test_cmd_prefix = adb_cmd + " shell am instrument"
62  run_load_test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
63
64  # Call LoadTestsAutoTest::runTest.
65  run_load_test_cmd = run_load_test_cmd_prefix + " -e class com.android.dumprendertree.LoadTestsAutoTest#runPageCyclerTest -e timeout " + timeout_ms
66
67  if remote_path:
68    if options.suite:
69      run_load_test_cmd += " -e suite %s -e forward %s " % (options.suite,
70                                                            remote_path)
71    else:
72      print "for network mode, need to specify --suite as well."
73      sys.exit(1)
74    if options.iteration:
75      run_load_test_cmd += " -e iteration %s" % options.iteration
76  else:
77    run_load_test_cmd += " -e path \"%s\" " % path
78
79
80  if options.drawtime:
81    run_load_test_cmd += " -e drawtime true "
82
83  if options.save_image:
84    run_load_test_cmd += " -e saveimage \"%s\"" % options.save_image
85
86  run_load_test_cmd += run_load_test_cmd_postfix
87
88  (adb_output, adb_error) = subprocess.Popen(run_load_test_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
89  fail_flag = False
90  for line in adb_output.splitlines():
91    line = line.strip()
92    if line.find('INSTRUMENTATION_CODE') == 0:
93      if not line[22:] == '-1':
94        fail_flag = True
95        break
96    if (line.find('INSTRUMENTATION_FAILED') != -1 or
97        line.find('Process crashed.') != -1):
98      fail_flag = True
99      break
100  if fail_flag:
101    logging.error("Error happened : " + adb_output)
102    sys.exit(1)
103
104  logging.info(adb_output);
105  logging.info(adb_error);
106  logging.info("Done\n");
107
108  # Pull results from /sdcard/load_test_result.txt
109  results_dir = options.results_directory
110  if not os.path.exists(results_dir):
111    os.makedirs(results_dir)
112  if not os.path.isdir(results_dir):
113    logging.error("Cannot create results dir: " + results_dir)
114    sys.exit(1)
115
116  result_file = "/sdcard/load_test_result.txt"
117  shell_cmd_str = adb_cmd + " pull " + result_file + " " + results_dir
118  (adb_output, err) = subprocess.Popen(
119      shell_cmd_str, shell=True,
120      stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
121  if not os.path.isfile(os.path.join(results_dir, "load_test_result.txt")):
122    logging.error("Failed to pull result file.")
123    logging.error("adb stdout:")
124    logging.error(adb_output)
125    logging.error("adb stderr:")
126    logging.error(err)
127  logging.info("Results are stored under: " + results_dir + "/load_test_result.txt\n")
128
129if '__main__' == __name__:
130  option_parser = optparse.OptionParser()
131  option_parser.add_option("-t", "--time-out-ms",
132                           default=None,
133                           help="set the timeout for each test")
134  option_parser.add_option("-v", "--verbose", action="store_true",
135                           default=False,
136                           help="include debug-level logging")
137  option_parser.add_option("-a", "--adb-options",
138                           default=None,
139                           help="pass options to adb, such as -d -e, etc");
140  option_parser.add_option("-r", "--results-directory",
141                           default="layout-test-results",
142                           help="directory which results are stored.")
143
144  option_parser.add_option("-d", "--drawtime", action="store_true",
145                           default=False,
146                           help="log draw time for each page rendered.")
147
148  option_parser.add_option("-s", "--save-image",
149                           default=None,
150                           help="stores rendered page to a location on device.")
151
152  option_parser.add_option("-u", "--suite",
153                           default=None,
154                           help="(for network mode) specify the suite to"
155                           " run by name")
156
157  option_parser.add_option("-i", "--iteration",
158                           default="5",
159                           help="(for network mode) specify how many iterations"
160                           " to run")
161
162  options, args = option_parser.parse_args();
163  main(options, args)
164