def run(self): try: self._init_phase() self._load_config_phase() self._object_init_phase() self._pre_device_preparation_clean_up_phase() self._device_preparation_phase() self._device_launch_phase() self._apk_preparation_phase() self._apk_installation_phase() self._pre_test_clean_up_phase() self._testing_phase() except LauncherFlowInterruptedException as e: Printer.error(e.caller_tag, str(e)) quit() finally: self._finalization_phase()
def run(self): try: self._init_phase() self._load_config_phase() self._object_init_phase() self._pre_device_preparation_clean_up_phase() self._device_preparation_phase() self._device_launch_phase() self._apk_preparation_phase() self._apk_installation_phase() self._pre_test_clean_up_phase() self._testing_phase() self._flakiness_check_phase() except Exception as e: if isinstance(e, LauncherFlowInterruptedException): Printer.error(e.caller_tag, str(e)) quit() else: raise e finally: self._finalization_phase()
def _load_launch_plan_to_global_settings(launch_plan): avd_set = ArgLoader.get_arg_loaded_by(ArgLoader.AVD_SET_PREFIX) is_avd_session_requested = avd_set is not None and avd_set != ArgLoader.AVD_SET_DEFAULT Printer.system_message(TAG, "General:") general_settings = launch_plan.general if is_avd_session_requested: GlobalConfig.SHOULD_USE_ONLY_DEVICES_SPAWNED_IN_SESSION = True else: GlobalConfig.SHOULD_USE_ONLY_DEVICES_SPAWNED_IN_SESSION = False GlobalConfig.ADB_CALL_BUFFER_SIZE = general_settings.adb_call_buffer_size if GlobalConfig.ADB_CALL_BUFFER_SIZE > 0: Printer.system_message( TAG, " * ADB call buffer size set to: " + Color.GREEN + str(GlobalConfig.ADB_CALL_BUFFER_SIZE) + " slot(s)" + Color.BLUE + ".") else: message = "ADB_CALL_BUFFER_SIZE cannot be smaller than 1. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) GlobalConfig.ADB_CALL_BUFFER_DELAY_BETWEEN_CMD = general_settings.adb_call_buffer_delay_between_cmd if GlobalConfig.ADB_CALL_BUFFER_DELAY_BETWEEN_CMD >= 0: if GlobalConfig.ADB_CALL_BUFFER_DELAY_BETWEEN_CMD == 0: Printer.system_message( TAG, " * ADB call buffer is disabled. ADB_CALL_BUFFER_DELAY_BETWEEN_CMD" " param set to: " + +Color.GREEN + "0 second(s)" + +Color.BLUE + ".") else: Printer.system_message( TAG, " * ADB call buffer will clear slots after " + Color.GREEN + str(GlobalConfig.ADB_CALL_BUFFER_DELAY_BETWEEN_CMD / 1000) + " second(s)" + Color.BLUE + " from ADB call.") else: message = "ADB_CALL_BUFFER_DELAY_BETWEEN_CMD cannot be negative! Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) if is_avd_session_requested: Printer.system_message(TAG, "Device preparation phase settings:") device_prep_settings = launch_plan.device_preparation_phase GlobalConfig.SHOULD_RECREATE_EXISTING_AVD = device_prep_settings.avd_should_recreate_existing if GlobalConfig.SHOULD_RECREATE_EXISTING_AVD: Printer.system_message( TAG, " * If requested AVD already exists - it will be" + Color.GREEN + " recreated from scratch" + Color.BLUE + ".") else: Printer.system_message( TAG, " * If requested AVD already exists - it will be" + Color.GREEN + " reused" + Color.BLUE + ".") Printer.system_message(TAG, "Device launching phase settings:") device_launch_settings = launch_plan.device_launching_phase GlobalConfig.IGNORED_DEVICE_LIST = device_launch_settings.device_android_id_to_ignore Printer.system_message( TAG, " * Devices with following Android-IDs will be ignored: " + Color.GREEN + str(GlobalConfig.IGNORED_DEVICE_LIST) + Color.BLUE + ".") if is_avd_session_requested: GlobalConfig.SHOULD_LAUNCH_AVD_SEQUENTIALLY = device_launch_settings.avd_launch_sequentially if GlobalConfig.SHOULD_LAUNCH_AVD_SEQUENTIALLY: Printer.system_message( TAG, " * AVD will be launched " + Color.GREEN + "one by one" + Color.BLUE + ". Wait for start will be performed for each AVD separately and it will take more" " time.") else: Printer.system_message( TAG, " * AVD will be launched " + Color.GREEN + "all at once" + Color.BLUE + ".") Printer.error( TAG, "Warning: when launching AVD simultaneously ADB is unaware of the amount of memory" " that specific AVD will use. If there is not enough memory in the system and you launch" " too many AVD at the same time your PC might turn off due to lack of RAM memory." ) GlobalConfig.ADB_SCAN_INTERVAL = device_launch_settings.avd_status_scan_interval_millis if GlobalConfig.ADB_SCAN_INTERVAL is "": message = " * ADB_SCAN_INTERVAL not specified in LaunchManifest. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) else: Printer.system_message( TAG, " * ADB will be scanned with interval of " + Color.GREEN + str(GlobalConfig.ADB_SCAN_INTERVAL / 1000) + " second(s)" + Color.BLUE + ".") GlobalConfig.AVD_ADB_BOOT_TIMEOUT = device_launch_settings.avd_wait_for_adb_boot_timeout_millis if GlobalConfig.AVD_ADB_BOOT_TIMEOUT is "": message = " * AVD_ADB_BOOT_TIMEOUT not specified in LaunchManifest. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) else: Printer.system_message( TAG, " * AVD - ADB boot timeout set to " + Color.GREEN + str(GlobalConfig.AVD_ADB_BOOT_TIMEOUT / 1000) + " second(s)" + Color.BLUE + ".") GlobalConfig.AVD_SYSTEM_BOOT_TIMEOUT = device_launch_settings.avd_wait_for_system_boot_timeout_millis if GlobalConfig.AVD_SYSTEM_BOOT_TIMEOUT is "": message = " * AVD_SYSTEM_BOOT_TIMEOUT not specified in LaunchManifest. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) else: Printer.system_message( TAG, " * AVD - ADB system boot timeout set to " + Color.GREEN + str(GlobalConfig.AVD_SYSTEM_BOOT_TIMEOUT / 1000) + " second(s)" + Color.BLUE + ".") GlobalConfig.SHOULD_RESTART_ADB = device_launch_settings.device_before_launching_restart_adb if GlobalConfig.SHOULD_RESTART_ADB: Printer.system_message( TAG, " * " + Color.GREEN + "ADB will be restarted" + Color.BLUE + " before launching tests.") Printer.system_message(TAG, "Apk preparation phase settings:") apk_preparation_settings = launch_plan.apk_preparation_phase GlobalConfig.SHOULD_BUILD_NEW_APK = apk_preparation_settings.build_new_apk if GlobalConfig.SHOULD_BUILD_NEW_APK: Printer.system_message( TAG, " * Launcher will " + Color.GREEN + "build .*apk" + Color.BLUE + " for tests with commands specified in test set.") else: Printer.system_message( TAG, " * Launcher will " + Color.GREEN + "look for existing .*apk" + Color.BLUE + " look for existing .*apk for tests and try to build only if nothing was found." ) Printer.system_message(TAG, "Test run phase settings:") testing_phase = launch_plan.testing_phase GlobalConfig.SHOULD_RECORD_TESTS = testing_phase.record_tests if GlobalConfig.SHOULD_RECORD_TESTS: Printer.system_message( TAG, " * Launcher will " + Color.GREEN + "record device screens" + Color.BLUE + " during test session.") else: Printer.system_message( TAG, " * Launcher test " + Color.GREEN + "recording is turned off" + Color.BLUE + ".")
def _load_paths_to_global_settings(path_set): GlobalConfig.SDK_DIR = clean_folder_only_dir( (path_set.paths["sdk_dir"]).path_value) if GlobalConfig.SDK_DIR == "": Printer.system_message( TAG, "SDK path not set in PathManifest. Will use path set in env variable " + Color.GREEN + "ANDROID_HOME" + Color.BLUE + ".") if ANDROID_HOME_ENV is None: message = "Env variable 'ANDROID_HOME' is not set. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) else: GlobalConfig.SDK_DIR = clean_folder_only_dir( make_path_absolute(ANDROID_HOME_ENV)) Printer.system_message( TAG, "Launcher will look for SDK in dir: " + Color.GREEN + GlobalConfig.SDK_DIR + Color.BLUE + ".") GlobalConfig.AVD_DIR = clean_folder_only_dir( (path_set.paths["avd_dir"]).path_value) if GlobalConfig.AVD_DIR == "": Printer.system_message( TAG, "AVD path not set in PathManifest. " "Will use path set in env variable 'ANDROID_SDK_HOME'.") if ANDROID_SDK_HOME_ENV is None: Printer.system_message( TAG, "Env variable 'ANDROID_SDK_HOME' is not set. " "Trying to recreate default path from user root.") GlobalConfig.AVD_DIR = clean_folder_only_dir( make_path_absolute(HOME)) + ".android" Printer.system_message( TAG, "Launcher will look for AVD images in dir: " + Color.GREEN + GlobalConfig.AVD_DIR + Color.BLUE + ".") GlobalConfig.PROJECT_ROOT_DIR = clean_folder_only_dir( make_path_absolute((path_set.paths["project_root_dir"]).path_value)) if GlobalConfig.PROJECT_ROOT_DIR == "": Printer.system_message( TAG, "Project root was not specified. This field is not obligatory.") Printer.error( TAG, "Warning: Without project root directory launcher will quit if no " ".*apk files will be found in directory loaded from 'apk_dir' field of PathManifest." ) else: Printer.system_message( TAG, "Android project root dir set to: " + Color.GREEN + GlobalConfig.PROJECT_ROOT_DIR + Color.BLUE + ".") GlobalConfig.APK_DIR = clean_folder_only_dir( make_path_absolute((path_set.paths["apk_dir"]).path_value)) if GlobalConfig.APK_DIR == "": message = "Directory with .*apk files was not specified. Launcher will quit." raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Launcher will look for .*apk files in dir: " + Color.GREEN + GlobalConfig.APK_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_DIR = clean_folder_only_dir( (path_set.paths["output_dir"]).path_value) if GlobalConfig.OUTPUT_DIR == "": Printer.system_message( TAG, "Output path not set in PathManifest. Default value will be used.") GlobalConfig.OUTPUT_DIR = OUTPUT_DIR_DEFAULT if not os.path.isabs(GlobalConfig.OUTPUT_DIR): message = "Path " + GlobalConfig.OUTPUT_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Launcher will generate log from tests in dir: " + Color.GREEN + GlobalConfig.OUTPUT_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_SUMMARY_LOG_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_SUMMARY_LOG_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_SUMMARY_LOG_DIR): message = "Path " + GlobalConfig.OUTPUT_SUMMARY_LOG_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Summary log will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_SUMMARY_LOG_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_AVD_LOG_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_AVD_LOG_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_AVD_LOG_DIR): message = "Path " + GlobalConfig.OUTPUT_AVD_LOG_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Logs from AVD will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_AVD_LOG_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_TEST_LOG_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_TEST_LOG_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_TEST_LOG_DIR): message = "Path " + GlobalConfig.OUTPUT_TEST_LOG_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Logs from tests will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_TEST_LOG_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_TEST_LOGCAT_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_TEST_LOGCAT_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_TEST_LOGCAT_DIR): message = "Path " + GlobalConfig.OUTPUT_TEST_LOGCAT_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Logcat logs from tests will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_TEST_LOGCAT_DIR + Color.BLUE + ".") GlobalConfig.DEVICE_VIDEO_STORAGE_DIR = clean_folder_only_dir( DEVICE_VIDEO_STORAGE_FOLDER_DEFAULT) Printer.system_message( TAG, "Firstly recordings will be saved in root directory of test device storage in " + Color.GREEN + GlobalConfig.DEVICE_VIDEO_STORAGE_DIR + Color.BLUE + " folder.") GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_TEST_VIDEO_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR): message = "Path " + GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Secondly recordings from tests will be pulled from each device to dir: " + Color.GREEN + GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_STYLES_FOLDER_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_HTML_STYLES_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_STYLES_FOLDER_DIR): message = "Path " + GlobalConfig.OUTPUT_STYLES_FOLDER_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Styles for all html logs will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_STYLES_FOLDER_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_LOGCAT_HTML_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR + OUTPUT_TEST_LOGCAT_HTML_FOLDER_DEFAULT) if not os.path.isabs(GlobalConfig.OUTPUT_LOGCAT_HTML_DIR): message = "Path " + GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Html logs presenting logcats from devices will be stored in dir: " + Color.GREEN + GlobalConfig.OUTPUT_LOGCAT_HTML_DIR + Color.BLUE + ".") GlobalConfig.OUTPUT_INDEX_HTML_DIR = clean_folder_only_dir( GlobalConfig.OUTPUT_DIR) + OUTPUT_HTML_INDEX_FILE_NAME if not os.path.isabs(GlobalConfig.OUTPUT_INDEX_HTML_DIR): message = "Path " + GlobalConfig.OUTPUT_TEST_RECORDINGS_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "All html logs containing results from tests, logcats and videos can be accessed from " + Color.GREEN + GlobalConfig.OUTPUT_INDEX_HTML_DIR + Color.BLUE + " file generated after " + "session ends.") GlobalConfig.LOG_GENERATOR_DIR = clean_folder_only_dir( LOG_GENERATOR_DIR_DEFAULT) if not os.path.isabs(GlobalConfig.LOG_GENERATOR_DIR): message = "Path " + GlobalConfig.LOG_GENERATOR_DIR + " needs to be absolute!" raise LauncherFlowInterruptedException(TAG, message) Printer.system_message( TAG, "Logs will be generated with usage of " + Color.GREEN + "LogGenerator.py" + Color.BLUE + " file stored in dir: " + Color.GREEN + GlobalConfig.LOG_GENERATOR_DIR + Color.BLUE + ".")
def get_open_ports(avd_set): _check_port_rules(avd_set) ports_to_use = avd_set.avd_port_rules.ports_to_use if len(ports_to_use) > 0: message = "Requested ports:" for port in ports_to_use: message += (" '" + str(port) + "'") message += "." message(TAG, message) ports_to_ignore = avd_set.avd_port_rules.ports_to_ignore if len(ports_to_ignore) > 0: message = "Ignoring ports:" for port in ports_to_ignore: message += (" '" + str(port) + "'") message += "." Printer.system_message(TAG, message) should_assign_missing_ports = avd_set.avd_port_rules.assign_missing_ports if should_assign_missing_ports: Printer.system_message( TAG, "Not requested ports will be automatically assigned.") else: Printer.system_message( TAG, "Port auto assignment is turned off. Only specified ports will be used." ) avd_instances = 0 for avd in avd_set.avd_list: avd_instances += avd.instances range_min = avd_set.avd_port_rules.search_range_min range_max = avd_set.avd_port_rules.search_range_max Printer.system_message( TAG, "Checking for " + str(avd_instances) + " open ports in range <" + str(range_min) + ", " + str(range_max) + ">.") available_ports = list() for port in ports_to_use: try: ShellHelper.execute_shell(GeneralCommand.CHECK_PORT.format(port), False, False) port_open = False except: port_open = True if port_open: available_ports.append(port) else: message = "Port {} was requested but is currently used." message = message.format(str(port)) raise LauncherFlowInterruptedException(TAG, message) if should_assign_missing_ports: temp_port = range_min for i in range(avd_instances - len(available_ports)): while temp_port < range_max and len( available_ports) != avd_instances: try: ShellHelper.execute_shell( GeneralCommand.CHECK_PORT.format(temp_port), False, False) port_open = False except: port_open = True if port_open: if temp_port not in available_ports and temp_port not in ports_to_ignore: available_ports.append(temp_port) else: Printer.error( TAG, "Port " + str(temp_port) + " is currently used and will be omitted.") temp_port += 2 if len(available_ports) != avd_instances: message = "There are only {} open ports available in range <{}, {}>. Requested amount: {}." message = message.format(str(len(available_ports)), str(range_min), str(range_max), str(avd_instances)) raise LauncherFlowInterruptedException(TAG, message) return available_ports