def _run_tests(self, devices, test_cmd_templates, is_rerunning=False): device_commands_dict = self._prepare_device_control_cmds(devices) threads_finished = False logcat_threads_num = len(devices) recording_threads_num = len( devices) if GlobalConfig.SHOULD_RECORD_TESTS else 0 test_threads_num = len(test_cmd_templates) logcat_threads = list() test_threads = list() test_log_saving_threads = list() logcat_saving_threads = list() test_recording_saving_threads = list() try: while not threads_finished: if len(logcat_threads) != logcat_threads_num: for device in devices: logcat_thread = TestLogCatMonitorThread( device, device_commands_dict.get(device), GlobalConfig.SHOULD_RECORD_TESTS) logcat_threads.append(logcat_thread) logcat_thread.start() if len(test_recording_saving_threads) != recording_threads_num: for device in devices: test_recording_saving_thread = TestRecordingSavingThread( device) test_recording_saving_threads.append( test_recording_saving_thread) test_recording_saving_thread.start() if len(test_threads) != test_threads_num and all( t.logcat_process is not None for t in logcat_threads): for device in devices: if not any(t.device.adb_name == device.adb_name and t.is_alive() for t in test_threads) \ and len(test_cmd_templates) > 0: launch_cmd_template = test_cmd_templates.pop(0) launch_cmd = launch_cmd_template.replace( self.DEVICE_NAME_PLACEHOLDER, device.adb_name) instance = "packages" if not is_rerunning else "tests" Printer.system_message( self.TAG, str(len(test_cmd_templates)) + " {} to run left...".format(instance)) self.adb_package_manager_controller.clear_package_cache( device.adb_name, GlobalConfig.APP_PACKAGE) test_thread = TestThread(launch_cmd, device) test_threads.append(test_thread) test_thread.start() for test_thread in test_threads: if len(test_thread.logs) > 0: current_test_logs = copy.deepcopy(test_thread.logs) self.test_store.store_test_status(current_test_logs) for test_log in current_test_logs: contain_count = self.test_store.test_contain_count( test_log.test_name) if contain_count > 1: test_log.rerun_count += contain_count - 1 if is_rerunning: session_logger.update_flaky_candidate(test_log) else: if test_log.test_status == "success": session_logger.increment_passed_tests() if test_log.test_status == "failure": session_logger.increment_failed_tests() test_log_saving_thread = TestSummarySavingThread( test_thread.device, current_test_logs) test_log_saving_threads.append(test_log_saving_thread) test_log_saving_thread.start() test_thread.logs.clear() for logcat_thread in logcat_threads: if len(logcat_thread.logs) > 0: current_logcats = copy.deepcopy(logcat_thread.logs) self.test_store.store_test_logcat(current_logcats) for test_logcat in current_logcats: contain_count = self.test_store.test_logcat_contain_count( test_logcat.test_name) if contain_count > 1: test_logcat.rerun_count += contain_count - 1 logcat_saving_thread = TestLogcatSavingThread( logcat_thread.device, current_logcats) logcat_saving_threads.append(logcat_saving_thread) logcat_saving_thread.start() logcat_thread.logs.clear() if len(logcat_thread.recordings) > 0: device = logcat_thread.device current_recordings = copy.deepcopy( logcat_thread.recordings) for recording_saving_thread in test_recording_saving_threads: if recording_saving_thread.device.adb_name == device.adb_name: pull_cmd_list = list() clear_cmd_list = list() for recording_name in current_recordings: recording_dir = FileUtils.add_ending_slash( FileUtils.clean_path( GlobalConfig. DEVICE_VIDEO_STORAGE_DIR) ) + recording_name pull_cmd_list.append( self._prepare_pull_recording_cmd( device, recording_dir)) clear_cmd_list.append( self._prepare_remove_recording_cmd( device, recording_dir)) recording_saving_thread.add_recordings( current_recordings) recording_saving_thread.add_pull_recording_cmds( pull_cmd_list) recording_saving_thread.add_clear_recordings_cmd( clear_cmd_list) logcat_thread.recordings.clear() if len(test_threads) == test_threads_num \ and all(not t.is_alive() for t in test_threads) \ and all(t.is_finished() for t in test_log_saving_threads) \ and all(t.is_finished() for t in logcat_saving_threads): for test_thread in test_threads: test_thread.kill_processes() test_thread.join() for logcat_thread in logcat_threads: logcat_thread.kill_processes() logcat_thread.join() for test_log_saving_thread in test_log_saving_threads: test_log_saving_thread.join() for logcat_saving_thread in logcat_saving_threads: logcat_saving_thread.join() test_threads.clear() logcat_threads.clear() test_log_saving_threads.clear() logcat_saving_threads.clear() if len(test_recording_saving_threads) > 0 and len( logcat_threads) == 0: if all( len(t.recordings) == 0 for t in test_recording_saving_threads): for recording_thread in test_recording_saving_threads: recording_thread.kill_processes() recording_thread.join() test_recording_saving_threads.clear() threads_finished = len(logcat_threads) == 0 and len( test_threads) == 0 and len( test_log_saving_threads) == 0 and len( logcat_saving_threads) == 0 and len( test_recording_saving_threads) == 0 and len( test_cmd_templates) == 0 except Exception as e: message = "Error has occurred during test session: \n" + str(e) raise LauncherFlowInterruptedException(self.TAG, message) finally: if len(test_threads) > 0: for test_thread in test_threads: test_thread.kill_processes() test_thread.join() if len(logcat_threads) > 0: for logcat_thread in logcat_threads: logcat_thread.kill_processes() logcat_thread.join() if len(test_log_saving_threads) > 0: for test_log_saving_thread in test_log_saving_threads: test_log_saving_thread.join() if len(logcat_saving_threads) > 0: for logcat_saving_thread in logcat_saving_threads: logcat_saving_thread.join() if len(test_recording_saving_threads) > 0: for recording_thread in test_recording_saving_threads: recording_thread.kill_processes() recording_thread.join() test_threads.clear() logcat_threads.clear() test_log_saving_threads.clear() logcat_saving_threads.clear() test_recording_saving_threads.clear()
def run_tests(self, test_set, test_list): devices = self.device_store.get_devices() test_packages = self.test_store.get_packages(test_set, test_list) launch_variant_string = "TESTS SPLIT INTO SHARDS" if test_set.shard else "EACH TEST ON EACH DEVICE" Printer.system_message( self.TAG, "According to test set settings, tests will be run with following variant: " + Color.GREEN + launch_variant_string + Color.BLUE + ".") device_commands_dict = self._prepare_device_control_cmds(devices) test_cmd_templates = self._prepare_launch_test_cmds_for_run( test_packages, devices, test_set.shard) threads_finished = False logcat_threads_num = len(devices) recording_threads_num = len( devices) if GlobalConfig.SHOULD_RECORD_TESTS else 0 test_threads_num = len(test_cmd_templates) logcat_threads = list() test_threads = list() test_log_saving_threads = list() logcat_saving_threads = list() test_recording_saving_threads = list() try: while not threads_finished: if len(logcat_threads) != logcat_threads_num: for device in devices: logcat_thread = TestLogCatMonitorThread( device, device_commands_dict.get(device), GlobalConfig.SHOULD_RECORD_TESTS) logcat_threads.append(logcat_thread) logcat_thread.start() if len(test_recording_saving_threads) != recording_threads_num: for device in devices: test_recording_saving_thread = TestRecordingSavingThread( device) test_recording_saving_threads.append( test_recording_saving_thread) test_recording_saving_thread.start() if len(test_threads) != test_threads_num and all( t.logcat_process is not None for t in logcat_threads): for device in devices: if not any(t.device.adb_name == device.adb_name and t.is_alive() for t in test_threads) \ and len(test_cmd_templates) > 0: launch_cmd_template = test_cmd_templates.pop(0) launch_cmd = launch_cmd_template.replace( self.DEVICE_NAME_PLACEHOLDER, device.adb_name) Printer.system_message( self.TAG, str(len(test_cmd_templates)) + " packages to run left...") self.adb_package_manager_controller.clear_package_cache( device.adb_name, GlobalConfig.APP_PACKAGE) test_thread = TestThread(launch_cmd, device) test_threads.append(test_thread) test_thread.start() for test_thread in test_threads: if len(test_thread.logs) > 0: current_test_logs = copy.deepcopy(test_thread.logs) for log in current_test_logs: if log.test_status == "success": session_logger.increment_passed_tests() if log.test_status == "failure": session_logger.increment_failed_tests() test_log_saving_thread = TestSummarySavingThread( test_thread.device, current_test_logs) test_log_saving_threads.append(test_log_saving_thread) test_log_saving_thread.start() test_thread.logs.clear() for logcat_thread in logcat_threads: if len(logcat_thread.logs) > 0: current_logcats = copy.deepcopy(logcat_thread.logs) logcat_saving_thread = TestLogcatSavingThread( logcat_thread.device, current_logcats) logcat_saving_threads.append(logcat_saving_thread) logcat_saving_thread.start() logcat_thread.logs.clear() if len(logcat_thread.recordings) > 0: device = logcat_thread.device current_recordings = copy.deepcopy( logcat_thread.recordings) for recording_saving_thread in test_recording_saving_threads: if recording_saving_thread.device.adb_name == device.adb_name: pull_cmd_list = list() clear_cmd_list = list() for recording_name in current_recordings: recording_dir = FileUtils.add_ending_slash( FileUtils.clean_path( GlobalConfig. DEVICE_VIDEO_STORAGE_DIR) ) + recording_name pull_cmd_list.append( self._prepare_pull_recording_cmd( device, recording_dir)) clear_cmd_list.append( self._prepare_remove_recording_cmd( device, recording_dir)) recording_saving_thread.add_recordings( current_recordings) recording_saving_thread.add_pull_recording_cmds( pull_cmd_list) recording_saving_thread.add_clear_recordings_cmd( clear_cmd_list) logcat_thread.recordings.clear() if len(test_threads) == test_threads_num \ and all(not t.is_alive() for t in test_threads) \ and all(t.is_finished() for t in test_log_saving_threads) \ and all(t.is_finished() for t in logcat_saving_threads): for test_thread in test_threads: test_thread.kill_processes() test_thread.join() for logcat_thread in logcat_threads: logcat_thread.kill_processes() logcat_thread.join() for test_log_saving_thread in test_log_saving_threads: test_log_saving_thread.join() for logcat_saving_thread in logcat_saving_threads: logcat_saving_thread.join() test_threads.clear() logcat_threads.clear() test_log_saving_threads.clear() logcat_saving_threads.clear() if len(test_recording_saving_threads) > 0 and len( logcat_threads) == 0: if all( len(t.recordings) == 0 for t in test_recording_saving_threads): for recording_thread in test_recording_saving_threads: recording_thread.kill_processes() recording_thread.join() test_recording_saving_threads.clear() threads_finished = len(logcat_threads) == 0 and len( test_threads) == 0 and len( test_log_saving_threads) == 0 and len( logcat_saving_threads) == 0 and len( test_recording_saving_threads) == 0 and len( test_cmd_templates) == 0 except Exception as e: message = "Error has occurred during test session: \n" + str(e) raise LauncherFlowInterruptedException(self.TAG, message) finally: if len(test_threads) > 0: for test_thread in test_threads: test_thread.kill_processes() test_thread.join() if len(logcat_threads) > 0: for logcat_thread in logcat_threads: logcat_thread.kill_processes() logcat_thread.join() if len(test_log_saving_threads) > 0: for test_log_saving_thread in test_log_saving_threads: test_log_saving_thread.join() if len(logcat_saving_threads) > 0: for logcat_saving_thread in logcat_saving_threads: logcat_saving_thread.join() if len(test_recording_saving_threads) > 0: for recording_thread in test_recording_saving_threads: recording_thread.kill_processes() recording_thread.join() test_threads.clear() logcat_threads.clear() test_log_saving_threads.clear() logcat_saving_threads.clear() test_recording_saving_threads.clear()