run_reliability_tests.py revision 2ab6f1fe0b17d281ea215f8ca412a5e1992011cc
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
174010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
204010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuTEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt"
212ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang ZhuTEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt"
224010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuHTTP_URL_FILE = "urllist_http"
234010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuHTTPS_URL_FILE = "urllist_https"
244010ac35b1e49d659d7a32cc191302b8e2d8758aGuang ZhuNUM_URLS = 25
254010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
264010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
274010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhudef DumpRenderTreeFinished(adb_cmd):
284010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """Check if DumpRenderTree finished running.
294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  Args:
314010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_cmd: adb command string
324010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
334010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  Returns:
344010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    True if DumpRenderTree has finished, False otherwise
354010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """
364010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
374010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # pull test status file and look for "#DONE"
384010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
394010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_output = subprocess.Popen(shell_cmd_str,
404010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                shell=True, stdout=subprocess.PIPE,
414010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stderr=subprocess.PIPE).communicate()[0]
424010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  return adb_output.strip() == "#DONE"
434010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
444010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
4565455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhudef RemoveDeviceFile(adb_cmd, file_name):
4665455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  shell_cmd_str = adb_cmd + " shell rm " + file_name
4765455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  subprocess.Popen(shell_cmd_str,
4865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu                   shell=True, stdout=subprocess.PIPE,
4965455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu                   stderr=subprocess.PIPE).communicate()
504010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
514010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
5217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhudef Bugreport(url, bugreport_dir, adb_cmd):
5317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  """Pull a bugreport from the device."""
5417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  bugreport_filename = "%s/reliability_bugreport_%d.txt" % (bugreport_dir,
5517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                                                            int(time.time()))
5617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
5717f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  # prepend the report with url
5817f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle = open(bugreport_filename, "w")
5917f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle.writelines("Bugreport for crash in url - %s\n\n" % url)
6017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  handle.close()
6117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
6217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  cmd = "%s bugreport >> %s" % (adb_cmd, bugreport_filename)
6317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  os.system(cmd)
6417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
6517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
662ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhudef ProcessPageLoadTime(raw_log):
672ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  """Processes the raw page load time logged by test app."""
682ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle = open(raw_log, "r")
692ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  load_times = {}
702ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
712ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  for line in log_handle:
722ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    line = line.strip()
732ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    pair = line.split("|")
742ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    if len(pair) != 2:
752ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      logging.info("Line has more than one '|': " + line)
762ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      continue
772ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    if pair[0] not in load_times:
782ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      load_times[pair[0]] = [0, 0]
792ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    try:
802ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      pair[1] = int(pair[1])
812ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    except ValueError:
822ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      logging.info("Lins has non-numeric load time: " + line)
832ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu      continue
842ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    load_times[pair[0]][0] += pair[1]
852ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    load_times[pair[0]][1] += 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():
922ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    log_handle.write("%s|%f\n" % (url, float(times[0]) / times[1]))
932ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  log_handle.close()
942ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
952ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
964010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhudef main(options, args):
974010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  """Send the url list to device and start testing, restart if crashed."""
984010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
994010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Set up logging format.
1004010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  log_level = logging.INFO
1014010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.verbose:
1024010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    log_level = logging.DEBUG
1034010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.basicConfig(level=log_level,
1044010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                      format="%(message)s")
1054010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1064010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Include all tests if none are specified.
1074010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not args:
10865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing URL list file"
10965455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    sys.exit(1)
1104010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1114010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    path = args[0]
1124010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1134010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not options.crash_file:
11465455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing crash file name, use --crash-file to specify"
1154010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1164010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1174010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    crashed_file = options.crash_file
1184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if not options.timeout_file:
12065455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu    print "Missing timeout file, use --timeout-file to specify"
1214010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1224010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
1234010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    timedout_file = options.timeout_file
1244010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1253e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  if not options.delay:
1263e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu    manual_delay = 0
1273e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  else:
1283e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu    manual_delay = options.delay
1293e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu
13017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not options.bugreport:
13117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    bugreport_dir = "."
13217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  else:
13317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    bugreport_dir = options.bugreport
13417f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not os.path.exists(bugreport_dir):
13517f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    os.makedirs(bugreport_dir)
13617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  if not os.path.isdir(bugreport_dir):
13717f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    logging.error("Cannot create results dir: " + bugreport_dir)
13817f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    sys.exit(1)
13917f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu
1404010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_cmd = "adb "
1414010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.adb_options:
1424010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_cmd += options.adb_options + " "
1434010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1444010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # push url list to device
1454010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = adb_cmd + " push \"" + path + "\" \"" + TEST_LIST_FILE + "\""
1464010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  proc = subprocess.Popen(test_cmd, shell=True,
1474010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                          stdout=subprocess.PIPE,
1484010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                          stderr=subprocess.PIPE)
1494010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  (adb_output, adb_error) = proc.communicate()
1504010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if proc.returncode != 0:
1514010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("failed to push url list to device.")
1524010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error(adb_output)
1534010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error(adb_error)
1544010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
1554010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
15665455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  # clean up previous results
15765455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  RemoveDeviceFile(adb_cmd, TEST_STATUS_FILE)
15865455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu  RemoveDeviceFile(adb_cmd, TEST_TIMEOUT_FILE)
15965455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu
1604010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info("Running the test ...")
1614010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1624010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Count crashed tests.
1634010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  crashed_tests = []
1644010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1654010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if options.time_out_ms:
1664010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    timeout_ms = options.time_out_ms
1674010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1684010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Run test until it's done
1694010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd_prefix = adb_cmd + " shell am instrument"
1704010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
1714010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1724010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  # Call ReliabilityTestsAutoTest#startReliabilityTests
1734010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = (test_cmd_prefix + " -e class "
17465455a1a46e3bec020befd27ff5ad6bfdab61a7dGuang Zhu              "com.android.dumprendertree.ReliabilityTest#"
1752ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu              "runReliabilityTest -e timeout %s -e delay %s" %
1762ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu              (str(timeout_ms), str(manual_delay)))
1772ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1782ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  if options.logtime:
1792ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    test_cmd += " -e logtime true"
1802ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
1812ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  test_cmd += test_cmd_postfix
1824010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1834010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  adb_output = subprocess.Popen(test_cmd, shell=True,
1844010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stdout=subprocess.PIPE,
1854010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                stderr=subprocess.PIPE).communicate()[0]
1864010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  while not DumpRenderTreeFinished(adb_cmd):
1874010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("DumpRenderTree exited before all URLs are visited.")
1884010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
1894010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    crashed_test = subprocess.Popen(shell_cmd_str, shell=True,
1904010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                    stdout=subprocess.PIPE).communicate()[0]
1914010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info(crashed_test + " CRASHED")
1924010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    crashed_tests.append(crashed_test)
19317f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu    Bugreport(crashed_test, bugreport_dir, adb_cmd)
1944010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("Resuming reliability test runner...")
1954010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1964010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    adb_output = subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
1974010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                                  stderr=subprocess.PIPE).communicate()[0]
1984010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
1994010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if (adb_output.find("INSTRUMENTATION_FAILED") != -1 or
2004010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu      adb_output.find("Process crashed.") != -1):
2014010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.error("Error happened : " + adb_output)
2024010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    sys.exit(1)
2034010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2044010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info(adb_output)
2054010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  logging.info("Done\n")
2064010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2074010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  if crashed_tests:
2084010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle = open(crashed_file, "w")
2094010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle.writelines("\n".join(crashed_tests))
2104010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("Crashed URL list stored in: " + crashed_file)
2114010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    file_handle.close()
2124010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  else:
2134010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu    logging.info("No crash found.")
2144010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2152ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  # get timeout file from sdcard
2164010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  test_cmd = (adb_cmd + "pull \"" + TEST_TIMEOUT_FILE + "\" \""
2174010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu              + timedout_file +  "\"")
2184010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
2194010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                   stderr=subprocess.PIPE).communicate()
2204010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2212ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  if options.logtime:
2222ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    # get logged page load times from sdcard
2232ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    test_cmd = (adb_cmd + "pull \"" + TEST_LOAD_TIME_FILE + "\" \""
2242ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                + options.logtime +  "\"")
2252ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
2262ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                     stderr=subprocess.PIPE).communicate()
2272ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu    ProcessPageLoadTime(options.logtime)
2282ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu
2294010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu
2304010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhuif "__main__" == __name__:
2314010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  option_parser = optparse.OptionParser()
2323e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-t", "--time-out-ms",
2334010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=60000,
2344010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="set the timeout for each test")
2353e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-v", "--verbose", action="store_true",
2364010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=False,
2374010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="include debug-level logging")
2383e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-a", "--adb-options",
2394010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default=None,
2404010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="pass options to adb, such as -d -e, etc")
2413e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-c", "--crash-file",
2424010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default="reliability_crashed_sites.txt",
2434010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           help="the list of sites that cause browser to crash")
2443e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-f", "--timeout-file",
2454010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu                           default="reliability_timedout_sites.txt",
24617f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           help="the list of sites that timedout during test")
2473e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu  option_parser.add_option("-d", "--delay",
2483e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu                           default=0,
2493e8950c0c73f9c1574ce3388c754009edf6bc930Guang Zhu                           help="add a manual delay between pages (in ms)")
25017f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu  option_parser.add_option("-b", "--bugreport",
25117f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           default=".",
25217f8fa6b24da34724b4497622f374b27f3041e1cGuang Zhu                           help="the directory to store bugreport for crashes")
2532ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu  option_parser.add_option("-l", "--logtime",
2542ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                           default=None,
2552ab6f1fe0b17d281ea215f8ca412a5e1992011ccGuang Zhu                           help="Logs page load time for each url to the file")
2564010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  opts, arguments = option_parser.parse_args()
2574010ac35b1e49d659d7a32cc191302b8e2d8758aGuang Zhu  main(opts, arguments)
258