• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Utility script to launch browser-tests on the Chromoting bot."""
5
6import argparse
7import time
8
9from chromoting_test_utilities import CleanupUserProfileDir
10from chromoting_test_utilities import GetJidFromHostLog
11from chromoting_test_utilities import GetJidListFromTestResults
12from chromoting_test_utilities import InitialiseTestMachineForLinux
13from chromoting_test_utilities import MAX_RETRIES
14from chromoting_test_utilities import PrintHostLogContents
15from chromoting_test_utilities import PROD_DIR_ID
16from chromoting_test_utilities import RunCommandInSubProcess
17from chromoting_test_utilities import TestCaseSetup
18from chromoting_test_utilities import TestMachineCleanup
19
20SUCCESS_INDICATOR = 'SUCCESS: all tests passed.'
21BROWSER_NOT_STARTED_ERROR = (
22    'Still waiting for the following processes to finish')
23TIME_OUT_INDICATOR = '(TIMED OUT)'
24
25
26def LaunchBTCommand(args, command):
27  """Launches the specified browser-test command.
28
29    Retry if the execution failed because a browser-instance was not launched or
30    because the JID used did not match the host-JID.
31  Args:
32    args: Command line args, used for test-case startup tasks.
33    command: Browser-test command line.
34
35  Returns:
36    host_log_file_names: Array of host logs created for this command, including
37         retries.
38  """
39  host_log_file_names = []
40
41  retries = 0
42  host_jid_mismatch = False
43  host_jid = None
44  while retries <= MAX_RETRIES:
45    # TestCaseSetup restarts the me2me host, and sets up user-profile dir.
46    # It returns the file-name of the me2me host log.
47    # If we are attempting to run this test because of a JID-mismatch, don't
48    # restart host.
49    if host_jid_mismatch:
50      # Cleanup user-profile directory, but don't restart host.
51      CleanupUserProfileDir(args)
52    else:
53      host_log_file_names.append(TestCaseSetup(args))
54      # Parse the me2me host log to obtain the JID that the host registered.
55      host_jid = GetJidFromHostLog(host_log_file_names[retries])
56
57    results = RunCommandInSubProcess(command)
58
59    # Get the JID used by this test to connect a remote-host, if any.
60    jids_used = GetJidListFromTestResults(results)
61
62    # Check for JID mismatch before checking for test success, so that we may
63    # record instances where a test passed despite a JID mismatch.
64    if jids_used and host_jid.rstrip() not in jids_used:
65      host_jid_mismatch = True
66      print('Host JID mismatch. JID in host log = %s.' % host_jid.rstrip())
67      print('Host JIDs used by test:')
68      for jid in jids_used:
69        print(jid)
70
71    if host_jid_mismatch:
72      # The JID for the remote-host did not match the JID that was used for this
73      # execution of the test. This happens because of a replication delay in
74      # updating all instances of the Chromoting Directory Server. To
75      # work-around this, sleep for 30s, which, based off a recent (08/2015)
76      # query for average replication delay for Chromoting, should be sufficient
77      # for the current JID value to have fully propagated.
78      retries += 1
79      time.sleep(30)
80      continue
81    if jids_used:
82      print('JID used by test matched me2me host JID: %s' % host_jid)
83    else:
84      # There wasn't a mismatch and no JIDs were returned. If no JIDs were
85      # returned, that means the test didn't use any JIDs, so there is nothing
86      # further for us to do.
87      pass
88
89    if SUCCESS_INDICATOR in results:
90      break
91
92    # Sometimes, during execution of browser-tests, a browser instance is
93    # not started and the test times out. See http://crbug/480025.
94    # To work around it, check if this execution failed owing to that
95    # problem and retry.
96    # There are 2 things to look for in the results:
97    # A line saying "Still waiting for the following processes to finish",
98    # and, because sometimes that line gets logged even if the test
99    # eventually passes, we'll also look for "(TIMED OUT)", before retrying.
100    if BROWSER_NOT_STARTED_ERROR in results and TIME_OUT_INDICATOR in results:
101      print('Browser-instance not started (http://crbug/480025). Retrying.')
102    else:
103      print('Test failed for unknown reason. Retrying.')
104
105    retries += 1
106
107  # Check that the test passed.
108  test_failure = False
109  failing_tests = ''
110  if SUCCESS_INDICATOR not in results:
111    test_failure = True
112    # Add this command-line to list of tests that failed.
113    failing_tests = command
114
115  return host_log_file_names, test_failure, failing_tests
116
117
118def run_tests(args):
119
120  InitialiseTestMachineForLinux(args.cfg_file)
121
122  host_log_files = []
123  have_test_failure = False
124  all_failing_tests = ''
125  with open(args.commands_file) as f:
126    for line in f:
127      # Replace the PROD_DIR value in the command-line with
128      # the passed in value.
129      line = line.replace(PROD_DIR_ID, args.prod_dir)
130      # Launch specified command line for test.
131      log_files, test_failure, failing_tests = LaunchBTCommand(args, line)
132      host_log_files.extend(log_files)
133      have_test_failure = have_test_failure or test_failure
134      all_failing_tests += failing_tests
135
136  # All tests completed. Include host-logs in the test results.
137  PrintHostLogContents(host_log_files)
138
139  return host_log_files, have_test_failure, all_failing_tests
140
141
142def main():
143  parser = argparse.ArgumentParser()
144  parser.add_argument('-f',
145                      '--commands_file',
146                      help='path to file listing commands to be launched.')
147  parser.add_argument('-p',
148                      '--prod_dir',
149                      help='path to folder having product and test binaries.')
150  parser.add_argument('-c', '--cfg_file', help='path to test host config file.')
151  parser.add_argument('--me2me_manifest_file',
152                      help='path to me2me host manifest file.')
153  parser.add_argument('--it2me_manifest_file',
154                      help='path to it2me host manifest file.')
155  parser.add_argument(
156      '-u',
157      '--user_profile_dir',
158      help='path to user-profile-dir, used by connect-to-host tests.')
159  command_line_args = parser.parse_args()
160  host_logs = ''
161  try:
162    host_logs, had_test_failure, failing_tests = run_tests(command_line_args)
163    if had_test_failure:
164      print('++++++++++AT LEAST 1 TEST FAILED++++++++++')
165      print(failing_tests.rstrip('\n'))
166      print('++++++++++++++++++++++++++++++++++++++++++')
167      raise Exception('At least one test failed.')
168  finally:
169    # Stop host and cleanup user-profile-dir.
170    TestMachineCleanup(command_line_args.user_profile_dir, host_logs)
171
172
173if __name__ == '__main__':
174  main()
175