14010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu#!/usr/bin/python2.4
24010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
34010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu"""Run reliability tests using Android instrumentation.
44010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
54010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  A test file consists of list web sites to test is needed as a parameter
64010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
74010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  Usage:
84010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    run_reliability_tests.py path/to/url/list
94010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu"""
104010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
114010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuimport logging
124010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuimport optparse
1317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhuimport os
144010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuimport subprocess
154010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuimport sys
1617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhuimport time
170528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhufrom Numeric import *
184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
204010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
214010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt"
222ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang ZhuTEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt"
234010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuHTTP_URL_FILE = "urllist_http"
244010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuHTTPS_URL_FILE = "urllist_https"
254010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuNUM_URLS = 25
264010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
274010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
284010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhudef DumpRenderTreeFinished(adb_cmd):
294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """Check if DumpRenderTree finished running.
304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
314010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  Args:
324010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_cmd: adb command string
334010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
344010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  Returns:
354010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    True if DumpRenderTree has finished, False otherwise
364010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """
374010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
384010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # pull test status file and look for "#DONE"
394010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
404010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_output = subprocess.Popen(shell_cmd_str,
414010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                shell=True, stdout=subprocess.PIPE,
424010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stderr=subprocess.PIPE).communicate()[0]
434010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  return adb_output.strip() == "#DONE"
444010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
454010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
4665455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhudef RemoveDeviceFile(adb_cmd, file_name):
4765455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  shell_cmd_str = adb_cmd + " shell rm " + file_name
4865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  subprocess.Popen(shell_cmd_str,
4965455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu                   shell=True, stdout=subprocess.PIPE,
5065455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu                   stderr=subprocess.PIPE).communicate()
514010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
524010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
5317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhudef Bugreport(url, bugreport_dir, adb_cmd):
5417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  """Pull a bugreport from the device."""
5517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  bugreport_filename = "%s/reliability_bugreport_%d.txt" % (bugreport_dir,
5617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                                                            int(time.time()))
5717f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
5817f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  # prepend the report with url
5917f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle = open(bugreport_filename, "w")
6017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle.writelines("Bugreport for crash in url - %s\n\n" % url)
6117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle.close()
6217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
6317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  cmd = "%s bugreport >> %s" % (adb_cmd, bugreport_filename)
6417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  os.system(cmd)
6517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
6617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
672ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhudef ProcessPageLoadTime(raw_log):
682ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  """Processes the raw page load time logged by test app."""
692ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle = open(raw_log, "r")
702ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  load_times = {}
712ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
722ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  for line in log_handle:
732ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    line = line.strip()
742ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    pair = line.split("|")
752ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    if len(pair) != 2:
762ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      logging.info("Line has more than one '|': " + line)
772ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      continue
782ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    if pair[0] not in load_times:
790528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu      load_times[pair[0]] = []
802ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    try:
812ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      pair[1] = int(pair[1])
822ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    except ValueError:
832ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      logging.info("Lins has non-numeric load time: " + line)
842ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      continue
850528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    load_times[pair[0]].append(pair[1])
862ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
872ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle.close()
882ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
892ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  # rewrite the average time to file
902ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle = open(raw_log, "w")
912ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  for url, times in load_times.iteritems():
920528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    # calculate std
930528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    arr = array(times)
940528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    avg = average(arr)
950528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    d = arr - avg
960528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    std = sqrt(sum(d * d) / len(arr))
970528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    output = ("%-70s%-10d%-10d%-12.2f%-12.2f%s\n" %
980528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu              (url, min(arr), max(arr), avg, std,
990528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu               array2string(arr)))
1000528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu    log_handle.write(output)
1012ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle.close()
1022ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1032ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1044010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhudef main(options, args):
1054010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """Send the url list to device and start testing, restart if crashed."""
1064010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1074010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Set up logging format.
1084010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  log_level = logging.INFO
1094010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.verbose:
1104010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    log_level = logging.DEBUG
1114010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.basicConfig(level=log_level,
1124010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                      format="%(message)s")
1134010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1144010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Include all tests if none are specified.
1154010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not args:
11665455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing URL list file"
11765455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    sys.exit(1)
1184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    path = args[0]
1204010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1214010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not options.crash_file:
12265455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing crash file name, use --crash-file to specify"
1234010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1244010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1254010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    crashed_file = options.crash_file
1264010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1274010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not options.timeout_file:
12865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing timeout file, use --timeout-file to specify"
1294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1314010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    timedout_file = options.timeout_file
1324010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1333e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  if not options.delay:
1343e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu    manual_delay = 0
1353e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  else:
1363e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu    manual_delay = options.delay
1373e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu
13817f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not options.bugreport:
13917f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    bugreport_dir = "."
14017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  else:
14117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    bugreport_dir = options.bugreport
14217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not os.path.exists(bugreport_dir):
14317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    os.makedirs(bugreport_dir)
14417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not os.path.isdir(bugreport_dir):
14517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    logging.error("Cannot create results dir: " + bugreport_dir)
14617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    sys.exit(1)
14717f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
1484010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_cmd = "adb "
1494010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.adb_options:
1504010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_cmd += options.adb_options + " "
1514010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1524010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # push url list to device
1534010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = adb_cmd + " push \"" + path + "\" \"" + TEST_LIST_FILE + "\""
1544010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  proc = subprocess.Popen(test_cmd, shell=True,
1554010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                          stdout=subprocess.PIPE,
1564010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                          stderr=subprocess.PIPE)
1574010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  (adb_output, adb_error) = proc.communicate()
1584010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if proc.returncode != 0:
1594010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("failed to push url list to device.")
1604010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error(adb_output)
1614010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error(adb_error)
1624010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1634010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
16465455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  # clean up previous results
16565455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  RemoveDeviceFile(adb_cmd, TEST_STATUS_FILE)
16665455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  RemoveDeviceFile(adb_cmd, TEST_TIMEOUT_FILE)
1670528cd03b27298cb7f5cb7e371e29deb8e05ae6aGuang Zhu  RemoveDeviceFile(adb_cmd, TEST_LOAD_TIME_FILE)
16865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu
1694010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info("Running the test ...")
1704010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1714010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Count crashed tests.
1724010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  crashed_tests = []
1734010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1744010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.time_out_ms:
1754010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    timeout_ms = options.time_out_ms
1764010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1774010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Run test until it's done
1784010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd_prefix = adb_cmd + " shell am instrument"
1794010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
1804010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1814010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Call ReliabilityTestsAutoTest#startReliabilityTests
1824010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = (test_cmd_prefix + " -e class "
18365455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu              "com.android.dumprendertree.ReliabilityTest#"
1842ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu              "runReliabilityTest -e timeout %s -e delay %s" %
1852ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu              (str(timeout_ms), str(manual_delay)))
1862ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1872ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  if options.logtime:
1882ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    test_cmd += " -e logtime true"
1892ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1902ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  test_cmd += test_cmd_postfix
1914010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1924010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_output = subprocess.Popen(test_cmd, shell=True,
1934010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stdout=subprocess.PIPE,
1944010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stderr=subprocess.PIPE).communicate()[0]
1954010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  while not DumpRenderTreeFinished(adb_cmd):
1964010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("DumpRenderTree exited before all URLs are visited.")
1974010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
198ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu    crashed_test = ""
199ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu    while not crashed_test:
200ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu      (crashed_test, err) = subprocess.Popen(
201ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu          shell_cmd_str, shell=True, stdout=subprocess.PIPE,
202ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu          stderr=subprocess.PIPE).communicate()
203ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu      crashed_test = crashed_test.strip()
204ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu      if not crashed_test:
205ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu        logging.error('Cannot get crashed test name, device offline?')
206ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu        logging.error('stderr: ' + err)
207ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu        logging.error('retrying in 10s...')
208ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu        time.sleep(10)
209ad1e25da74517343b306f5fe72d42b2ccb59ec6eGuang Zhu
2104010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info(crashed_test + " CRASHED")
2114010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    crashed_tests.append(crashed_test)
21217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    Bugreport(crashed_test, bugreport_dir, adb_cmd)
2134010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("Resuming reliability test runner...")
2144010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2154010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_output = subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
2164010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                  stderr=subprocess.PIPE).communicate()[0]
2174010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if (adb_output.find("INSTRUMENTATION_FAILED") != -1 or
2194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu      adb_output.find("Process crashed.") != -1):
2204010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("Error happened : " + adb_output)
2214010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
2224010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2234010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info(adb_output)
2244010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info("Done\n")
2254010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2264010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if crashed_tests:
2274010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle = open(crashed_file, "w")
2284010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle.writelines("\n".join(crashed_tests))
2294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("Crashed URL list stored in: " + crashed_file)
2304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle.close()
2314010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
2324010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("No crash found.")
2334010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2342ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  # get timeout file from sdcard
2354010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = (adb_cmd + "pull \"" + TEST_TIMEOUT_FILE + "\" \""
2364010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu              + timedout_file +  "\"")
2374010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
2384010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                   stderr=subprocess.PIPE).communicate()
2394010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2402ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  if options.logtime:
2412ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    # get logged page load times from sdcard
2422ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    test_cmd = (adb_cmd + "pull \"" + TEST_LOAD_TIME_FILE + "\" \""
2432ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                + options.logtime +  "\"")
2442ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
2452ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                     stderr=subprocess.PIPE).communicate()
2462ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    ProcessPageLoadTime(options.logtime)
2472ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
2484010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2494010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuif "__main__" == __name__:
2504010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  option_parser = optparse.OptionParser()
2513e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-t", "--time-out-ms",
2524010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=60000,
2534010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="set the timeout for each test")
2543e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-v", "--verbose", action="store_true",
2554010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=False,
2564010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="include debug-level logging")
2573e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-a", "--adb-options",
2584010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=None,
2594010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="pass options to adb, such as -d -e, etc")
2603e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-c", "--crash-file",
2614010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default="reliability_crashed_sites.txt",
2624010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="the list of sites that cause browser to crash")
2633e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-f", "--timeout-file",
2644010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default="reliability_timedout_sites.txt",
26517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           help="the list of sites that timedout during test")
2663e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-d", "--delay",
2673e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu                           default=0,
2683e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu                           help="add a manual delay between pages (in ms)")
26917f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  option_parser.add_option("-b", "--bugreport",
27017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           default=".",
27117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           help="the directory to store bugreport for crashes")
2722ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  option_parser.add_option("-l", "--logtime",
2732ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                           default=None,
2742ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                           help="Logs page load time for each url to the file")
2754010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  opts, arguments = option_parser.parse_args()
2764010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  main(opts, arguments)
277