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