| # Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Utility script to launch browser-tests on the Chromoting bot.""" | |
| import argparse | |
| import time | |
| from chromoting_test_utilities import CleanupUserProfileDir | |
| from chromoting_test_utilities import GetJidFromHostLog | |
| from chromoting_test_utilities import GetJidListFromTestResults | |
| from chromoting_test_utilities import InitialiseTestMachineForLinux | |
| from chromoting_test_utilities import MAX_RETRIES | |
| from chromoting_test_utilities import PrintHostLogContents | |
| from chromoting_test_utilities import PROD_DIR_ID | |
| from chromoting_test_utilities import RunCommandInSubProcess | |
| from chromoting_test_utilities import TestCaseSetup | |
| from chromoting_test_utilities import TestMachineCleanup | |
| SUCCESS_INDICATOR = 'SUCCESS: all tests passed.' | |
| TEST_FAILURE = False | |
| FAILING_TESTS = '' | |
| BROWSER_NOT_STARTED_ERROR = ( | |
| 'Still waiting for the following processes to finish') | |
| TIME_OUT_INDICATOR = '(TIMED OUT)' | |
| def LaunchBTCommand(args, command): | |
| """Launches the specified browser-test command. | |
| Retry if the execution failed because a browser-instance was not launched or | |
| because the JID used did not match the host-JID. | |
| Args: | |
| args: Command line args, used for test-case startup tasks. | |
| command: Browser-test command line. | |
| Returns: | |
| host_log_file_names: Array of host logs created for this command, including | |
| retries. | |
| """ | |
| global TEST_FAILURE, FAILING_TESTS | |
| host_log_file_names = [] | |
| retries = 0 | |
| host_jid_mismatch = False | |
| host_jid = None | |
| while retries <= MAX_RETRIES: | |
| # TestCaseSetup restarts the me2me host, and sets up user-profile dir. | |
| # It returns the file-name of the me2me host log. | |
| # If we are attempting to run this test because of a JID-mismatch, don't | |
| # restart host. | |
| if host_jid_mismatch: | |
| # Cleanup user-profile directory, but don't restart host. | |
| CleanupUserProfileDir(args) | |
| else: | |
| host_log_file_names.append(TestCaseSetup(args)) | |
| # Parse the me2me host log to obtain the JID that the host registered. | |
| host_jid = GetJidFromHostLog(host_log_file_names[retries]) | |
| results = RunCommandInSubProcess(command) | |
| # Get the JID used by this test to connect a remote-host, if any. | |
| jids_used = GetJidListFromTestResults(results) | |
| # Check for JID mismatch before checking for test success, so that we may | |
| # record instances where a test passed despite a JID mismatch. | |
| if jids_used and host_jid.rstrip() not in jids_used: | |
| host_jid_mismatch = True | |
| print 'Host JID mismatch. JID in host log = %s.' % host_jid.rstrip() | |
| print 'Host JIDs used by test:' | |
| for jid in jids_used: | |
| print jid | |
| if host_jid_mismatch: | |
| # The JID for the remote-host did not match the JID that was used for this | |
| # execution of the test. This happens because of a replication delay in | |
| # updating all instances of the Chromoting Directory Server. To | |
| # work-around this, sleep for 30s, which, based off a recent (08/2015) | |
| # query for average replication delay for Chromoting, should be sufficient | |
| # for the current JID value to have fully propagated. | |
| retries += 1 | |
| time.sleep(30) | |
| continue | |
| elif jids_used: | |
| print 'JID used by test matched me2me host JID: %s' % host_jid | |
| else: | |
| # There wasn't a mismatch and no JIDs were returned. If no JIDs were | |
| # returned, that means the test didn't use any JIDs, so there is nothing | |
| # further for us to do. | |
| pass | |
| if SUCCESS_INDICATOR in results: | |
| break | |
| # Sometimes, during execution of browser-tests, a browser instance is | |
| # not started and the test times out. See http://crbug/480025. | |
| # To work around it, check if this execution failed owing to that | |
| # problem and retry. | |
| # There are 2 things to look for in the results: | |
| # A line saying "Still waiting for the following processes to finish", | |
| # and, because sometimes that line gets logged even if the test | |
| # eventually passes, we'll also look for "(TIMED OUT)", before retrying. | |
| if BROWSER_NOT_STARTED_ERROR in results and TIME_OUT_INDICATOR in results: | |
| print 'Browser-instance not started (http://crbug/480025). Retrying.' | |
| else: | |
| print 'Test failed for unknown reason. Retrying.' | |
| retries += 1 | |
| # Check that the test passed. | |
| if SUCCESS_INDICATOR not in results: | |
| TEST_FAILURE = True | |
| # Add this command-line to list of tests that failed. | |
| FAILING_TESTS += command | |
| return host_log_file_names | |
| def main(args): | |
| InitialiseTestMachineForLinux(args.cfg_file) | |
| host_log_files = [] | |
| with open(args.commands_file) as f: | |
| for line in f: | |
| # Replace the PROD_DIR value in the command-line with | |
| # the passed in value. | |
| line = line.replace(PROD_DIR_ID, args.prod_dir) | |
| # Launch specified command line for test. | |
| host_log_files.extend(LaunchBTCommand(args, line)) | |
| # All tests completed. Include host-logs in the test results. | |
| PrintHostLogContents(host_log_files) | |
| return host_log_files | |
| if __name__ == '__main__': | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('-f', '--commands_file', | |
| help='path to file listing commands to be launched.') | |
| parser.add_argument('-p', '--prod_dir', | |
| help='path to folder having product and test binaries.') | |
| parser.add_argument('-c', '--cfg_file', | |
| help='path to test host config file.') | |
| parser.add_argument('--me2me_manifest_file', | |
| help='path to me2me host manifest file.') | |
| parser.add_argument('--it2me_manifest_file', | |
| help='path to it2me host manifest file.') | |
| parser.add_argument( | |
| '-u', '--user_profile_dir', | |
| help='path to user-profile-dir, used by connect-to-host tests.') | |
| command_line_args = parser.parse_args() | |
| host_logs = '' | |
| try: | |
| host_logs = main(command_line_args) | |
| if TEST_FAILURE: | |
| print '++++++++++AT LEAST 1 TEST FAILED++++++++++' | |
| print FAILING_TESTS.rstrip('\n') | |
| print '++++++++++++++++++++++++++++++++++++++++++' | |
| raise Exception('At least one test failed.') | |
| finally: | |
| # Stop host and cleanup user-profile-dir. | |
| TestMachineCleanup(command_line_args.user_profile_dir, host_logs) |