def _display_emulator_binaries(self):
        emulator_binaries = dict()

        emulator_dir = clean_path(
            add_ending_slash(str(GlobalConfig.SDK_DIR)) + "emulator/")
        try:
            for the_file in list_files_in_dir(emulator_dir):
                file_path = os.path.join(emulator_dir, the_file)
                if os.path.isfile(file_path) and "emulator" in file_path:
                    binary_name = re.findall("emulator\/(emulator*.+)",
                                             file_path)

                    if binary_name:
                        emulator_binaries[str(binary_name[0])] = file_path
        finally:
            if len(emulator_binaries) == 0:
                message = "Unable to find emulator binary files in direction '{}' of Android SDK."
                message = message.format(str(emulator_dir))
                raise LauncherFlowInterruptedException(self.TAG, message)

            else:
                Printer.system_message(
                    self.TAG,
                    "Emulator related binary files found in Android SDK:")
                for path in emulator_binaries.values():
                    Printer.system_message(
                        self.TAG, "  * " + Color.GREEN + path + Color.BLUE)

        return emulator_binaries
예제 #2
0
    def _init_phase():
        Printer.phase("INIT")
        session_logger.log_session_start_time()

        Printer.step("Launcher started working!")
        Version.info()
        Version.python_check()
예제 #3
0
    def _pre_test_clean_up_phase(self):
        Printer.phase("PRE-TESTING CLEAN UP")

        if GlobalConfig.SHOULD_RECORD_TESTS:
            Printer.step(
                "Preparing directory for recordings storage on test devices")
            self.clean_up_manager.prepare_device_directories()
예제 #4
0
    def run(self):
        Printer.console_highlighted(self.TAG, "Executing shell command: ", self.launch_tests_cmd)
        with subprocess.Popen(self.launch_tests_cmd, shell=True, stdout=subprocess.PIPE, bufsize=1,
                              universal_newlines=True, encoding="utf-8", errors="ignore") as p:
            self.test_process = p

            is_using_post_api27_flow = None
            reading_stack_in_progress = False
            current_log = None
            stack = None

            for line in p.stdout:
                line_cleaned = line.encode("utf-8", "ignore").decode("utf-8")

                if self.TEST_NAME in line_cleaned and is_using_post_api27_flow is None:
                    is_using_post_api27_flow = False
                elif self.TEST_PACKAGE in line_cleaned and is_using_post_api27_flow is None:
                    is_using_post_api27_flow = True
                elif is_using_post_api27_flow is None:
                    continue

                if is_using_post_api27_flow:
                    current_log, stack, reading_stack_in_progress = self._post_api27_logging_flow(
                        line_cleaned, current_log, stack, reading_stack_in_progress)
                else:
                    current_log, stack, reading_stack_in_progress = self._pre_api27_logging_flow(
                        line_cleaned, current_log, stack, reading_stack_in_progress)
예제 #5
0
    def _wait_for_adb_statuses_change_to(self, status, monitored_devices):
        Printer.system_message(
            self.TAG,
            "Waiting until (" + " ".join("'" + device.adb_name + "'"
                                         for device in monitored_devices) +
            ") devices status will change to '" + status + "'.")

        timeout = GlobalConfig.AVD_ADB_BOOT_TIMEOUT
        start_time = last_scan_ended = time.time() * 1000
        while True:
            current_time = time.time() * 1000

            if current_time - last_scan_ended >= GlobalConfig.ADB_SCAN_INTERVAL or start_time == last_scan_ended:
                Printer.system_message(self.TAG, "Scanning...")

                self.device_store.update_model_statuses()
                Printer.system_message(self.TAG, "  * Current wait status:")
                for device in monitored_devices:
                    Printer.system_message(
                        self.TAG, "    " + device.adb_name + " " +
                        Color.GREEN + "('" + device.status + "')")

                if all(device.status == status
                       for device in monitored_devices):
                    break

                last_scan_ended = time.time() * 1000

            if current_time - start_time >= timeout:
                message = "Devices took longer than {} seconds to launch (ADB launch). Timeout quit."
                message = message.format(str(timeout))
                raise LauncherFlowInterruptedException(self.TAG, message)

        Printer.system_message(self.TAG, "ADB wait finished with success!")
예제 #6
0
 def display_picked_apk_info(self):
     self.apk_store.display_candidates()
     if self.apk_store.usable_apk_candidate is not None:
         Printer.system_message(
             self.TAG,
             "Picked .*apk with highest version code:\n" + Color.GREEN +
             str(self.apk_store.usable_apk_candidate) + Color.BLUE + ".")
    def _find_latest_build_tools(self):
        build_tools = list_files_in_dir(
            clean_path(add_ending_slash(GlobalConfig.SDK_DIR) + "build-tools"))
        build_tools = [
            build_tool for build_tool in build_tools
            if build_tool[0].isdigit()
        ]
        build_tools_folder_with_highest_ver = None
        Printer.system_message(
            self.TAG,
            "Available Android SDK Build-Tools versions: " + str(build_tools))
        for build_tools_folder in build_tools:
            if build_tools_folder_with_highest_ver is None:
                build_tools_folder_with_highest_ver = build_tools_folder
                continue

            ver = int(re.sub("[^0-9]", "", build_tools_folder))
            highest_ver = int(
                re.sub("[^0-9]", "", build_tools_folder_with_highest_ver))

            if ver > highest_ver:
                build_tools_folder_with_highest_ver = build_tools_folder
        if build_tools_folder_with_highest_ver is None:
            message = "Android SDK Build-Tools not found. Launcher will quit."
            raise LauncherFlowInterruptedException(self.TAG, message)

        else:
            Printer.system_message(
                self.TAG,
                "Android SDK Build-Tools with latest version were selected: " +
                Color.GREEN + str(build_tools_folder_with_highest_ver) +
                Color.BLUE + ".")
        return build_tools_folder_with_highest_ver
예제 #8
0
    def prepare_session_devices(self, avd_set, avd_schemas):
        avd_ports = PortManager.get_open_ports(avd_set)
        for avd in avd_set.avd_list:
            instances_of_schema = avd.instances
            for i in range(instances_of_schema):
                avd_schema = copy.deepcopy(avd_schemas[avd.avd_name])
                avd_schema.avd_name = avd_schema.avd_name + "-" + str(i)
                port = avd_ports.pop(0)

                log_file = FileUtils.clean_path(
                    GlobalConfig.OUTPUT_AVD_LOG_DIR + avd_schema.avd_name +
                    ".txt")
                FileUtils.create_file(GlobalConfig.OUTPUT_AVD_LOG_DIR,
                                      avd_schema.avd_name, "txt")
                Printer.system_message(
                    self.TAG, "Created file " + Color.GREEN + log_file +
                    Color.BLUE + ".")

                session_device = SessionVirtualDevice(
                    avd_schema, port, log_file, self.avdmanager_controller,
                    self.emulator_controller, self.adb_controller,
                    self.adb_package_manager_controller,
                    self.adb_settings_controller)
                self.session_devices.append(session_device)
                Printer.system_message(
                    self.TAG,
                    "Android Virtual Device model was created according to schema "
                    + Color.GREEN + avd_schema.avd_name + Color.BLUE +
                    ". Instance number: " + str(i) + ". Assigned to port: " +
                    str(port) + ".")
예제 #9
0
    def _testing_phase(self):
        Printer.phase("TESTING")
        session_logger.log_total_test_start_time()

        Printer.step("Starting tests.")
        self.test_manager.run_tests(self.test_set, self.test_list)

        session_logger.log_total_test_end_time()
예제 #10
0
    def _flakiness_check_phase(self):
        if GlobalConfig.SHOULD_RERUN_FAILED_TESTS:
            Printer.phase("FLAKINESS CHECK")
            session_logger.log_total_rerun_start_time()

            Printer.step("Re-running failed tests.")
            self.test_manager.rerun_failed_tests()

            session_logger.log_total_rerun_end_time()
def _load_launch_plan(launch_manifest, launch_plan_name):
    if launch_manifest.contains_plan(launch_plan_name):
        Printer.system_message(TAG, "Launch plan " + Color.GREEN + launch_plan_name + Color.BLUE
                               + " was found in LaunchManifest.")
        return launch_manifest.get_plan(launch_plan_name)
    else:
        message = "Invalid launch plan with name '{}' does not exist in LaunchManifest!"
        message = message.format(launch_plan_name)
        raise LauncherFlowInterruptedException(TAG, message)
예제 #12
0
def _load_avd_set_name():
    avd_set_name = ArgLoader.get_arg_loaded_by(ArgLoader.AVD_SET_PREFIX)

    if avd_set_name is None:
        Printer.system_message(TAG, "No AVD set selected. ""Currently available real devices will be used in test "
                                    "session.")
    else:
        Printer.system_message(TAG, "Selected avd set: " + Color.GREEN + avd_set_name + Color.BLUE + ".")
    return avd_set_name
예제 #13
0
    def _apk_installation_phase(self):
        Printer.phase("APK INSTALLATION")
        session_logger.log_total_apk_install_start_time()

        Printer.step("Installing .*apk on devices included in test session.")
        apk = self.apk_manager.get_existing_apk(self.test_set)
        self.apk_manager.install_apk_on_devices(apk)

        session_logger.log_total_apk_install_end_time()
 def _assert_bin_directory_exists(self):
     if os.path.isfile(self.adb_bin):
         Printer.system_message(
             self.TAG, "ADB binary file found at " + Color.GREEN +
             self.adb_bin + Color.BLUE + ".")
     else:
         message = "Unable to find ADB binary at '{}'."
         message = message.format(self.adb_bin)
         raise LauncherFlowInterruptedException(self.TAG, message)
def _load_launch_plan_name():
    launch_plan_name = ArgLoader.get_arg_loaded_by(ArgLoader.LAUNCH_PLAN_PREFIX)

    if launch_plan_name is None:
        message = "No launch plan selected. Launcher will quit."
        raise LauncherFlowInterruptedException(TAG, message)
    else:
        Printer.system_message(TAG, "Selected launch plan: " + Color.GREEN + launch_plan_name + Color.BLUE + ".")
    return launch_plan_name
예제 #16
0
 def _create_apk_dir_if_not_exists(self):
     if FileUtils.dir_exists(GlobalConfig.APK_DIR):
         Printer.system_message(
             self.TAG, "Directory " + Color.GREEN + GlobalConfig.APK_DIR +
             Color.BLUE + " was found.")
     else:
         Printer.system_message(
             self.TAG, "Directory " + Color.GREEN + GlobalConfig.APK_DIR +
             Color.BLUE + " not found. Creating...")
         FileUtils.create_dir(GlobalConfig.APK_DIR)
예제 #17
0
def _load_path_set_name():
    path_set_name = ArgLoader.get_arg_loaded_by(ArgLoader.PATH_SET_PREFIX)
    if path_set_name is None:
        message = "No path set was selected. Launcher will quit."
        raise LauncherFlowInterruptedException(TAG, message)
    else:
        Printer.system_message(
            TAG, "Selected path set: " + Color.GREEN + path_set_name +
            Color.BLUE + ".")
    return path_set_name
예제 #18
0
def _load_path_set(path_manifest, path_set_name):
    if path_manifest.contains_set(path_set_name):
        Printer.system_message(
            TAG, "Path set " + Color.GREEN + path_set_name + Color.BLUE +
            " was found in PathManifest.")
        return path_manifest.get_set(path_set_name)
    else:
        message = "Invalid path set with name '{}' does not exist in PathManifest!"
        message = message.format(path_set_name)
        raise LauncherFlowInterruptedException(TAG, message)
예제 #19
0
def python_check():
    if sys.version_info >= MIN_PYTHON_VER:
        Printer.system_message(
            "", "Minimum Python version requirement met! Your version: " +
            Color.GREEN + str(sys.version_info) + Color.BLUE + ".")

    else:
        message = ("Invalid Python version. Please use at least Python " +
                   str(MIN_PYTHON_VER[0]) + "." + str(MIN_PYTHON_VER[1]) + ".")
        raise LauncherFlowInterruptedException("", message)
예제 #20
0
def _load_test_set_name():
    test_set_name = ArgLoader.get_arg_loaded_by(ArgLoader.TEST_SET_PREFIX)
    if test_set_name is None:
        message = "No test set inserted. Launcher will quit."
        raise LauncherFlowInterruptedException(TAG, message)
    else:
        Printer.system_message(
            TAG, "Selected test set: " + Color.GREEN + test_set_name +
            Color.BLUE + ".")
    return test_set_name
예제 #21
0
 def remove_device_from_session(self, device):
     if device in self.outside_session_virtual_devices:
         self.outside_session_virtual_devices.remove(device)
     elif device in self.outside_session_devices:
         self.outside_session_devices.remove(device)
     elif device in self.session_devices:
         self.session_devices.remove(device)
     Printer.system_message(
         self.TAG, "Device with name " + Color.GREEN + device.adb_name +
         Color.BLUE + " was removed from session.")
예제 #22
0
def print_test_summary():
    Printer.system_message(TAG, "Test details:")
    Printer.system_message(TAG, "  * Total number of test cases: " + Color.GREEN +
                           str(session_log.test_summary.test_number) + Color.BLUE + ".")
    Printer.system_message(TAG, "  * Tests passed: " + Color.GREEN + str(session_log.test_summary.test_passed)
                           + Color.BLUE + ".")
    Printer.system_message(TAG, "  * Tests failed: " + Color.GREEN + str(session_log.test_summary.test_failed)
                           + Color.BLUE + ".")
    if session_log.test_summary.health_rate is not None:
        Printer.system_message(TAG, "  * Health rate: " + Color.GREEN
                               + "{0:.2f}%".format(session_log.test_summary.health_rate * 100) + Color.BLUE + ".")
def _load_launch_plan_manifest():
    launch_manifest_dir = make_path_absolute(ArgLoader.get_manifest_dir(ArgLoader.LAUNCH_MANIFEST_DIR_KEY))

    if launch_manifest_dir is None:
        message = ("LaunchManifest file directory was not found. Check if config_files_dir.json exists in root " 
                   "of project. Otherwise check if it's linking to existing file.")
        raise LauncherFlowInterruptedException(TAG, message)
    else:
        launch_manifest = LaunchManifest(launch_manifest_dir)
        Printer.system_message(TAG, "Created LaunchManifest from file: " + Color.GREEN + launch_manifest_dir
                               + Color.BLUE + ".")
    return launch_manifest
예제 #24
0
def _load_avd_manifest():
    avd_manifest_dir = make_path_absolute(ArgLoader.get_manifest_dir(ArgLoader.AVD_MANIFEST_DIR_KEY))

    if avd_manifest_dir is None:
        message = ("AvdManifest file directory was not found. Check if config_files_dir.json exists in root of"
                   + "project. Otherwise check if it's linking to existing file.")
        raise LauncherFlowInterruptedException(TAG, message)
    else:
        avd_manifest = AvdManifest(avd_manifest_dir)
        Printer.system_message(TAG, "Created AvdManifest from file: " + Color.GREEN + avd_manifest_dir + Color.BLUE
                               + ".")
    return avd_manifest
예제 #25
0
    def set_instrumentation_runner_according_to(self, apk):
        Printer.system_message(
            self.TAG,
            "Scanning test .*apk file for Instrumentation Runner data.")

        resources = self.aapt_controller.list_resources(apk.test_apk_path)
        target_package = ""
        instrumentation_runner_name = ""

        inside_instrumentation_section = False
        inside_manifest_section = False
        for line in resources.splitlines():
            if "E: instrumentation" in line:
                inside_instrumentation_section = True
                continue

            if "E: manifest" in line:
                inside_manifest_section = True
                continue

            if inside_instrumentation_section and "E: " in line:
                inside_instrumentation_section = False

            if inside_manifest_section and "E: " in line:
                inside_manifest_section = False

            if inside_instrumentation_section:
                if "A: android:name" in line:
                    regex_result = re.findall("=\"(.+?)\"", line)
                    if regex_result:
                        instrumentation_runner_name = str(regex_result[0])

            if inside_manifest_section:
                if "A: package" in line:
                    regex_result = re.findall("=\"(.+?)\"", line)
                    if regex_result:
                        target_package = str(regex_result[0])

        if target_package == "":
            message = "Unable to find package of tested application in test .*apk file. Tests won't start without it."
            raise LauncherFlowInterruptedException(self.TAG, message)

        if instrumentation_runner_name == "":
            message = (
                "Unable to find Instrumentation Runner name of tested application in test .*apk file."
                " Tests won't start without it.")
            raise LauncherFlowInterruptedException(self.TAG, message)

        GlobalConfig.INSTRUMENTATION_RUNNER = target_package + "/" + instrumentation_runner_name
        Printer.system_message(
            self.TAG, "Instrumentation Runner found: " + Color.GREEN +
            GlobalConfig.INSTRUMENTATION_RUNNER + Color.BLUE + ".")
예제 #26
0
def _load_avd_schema(avd_manifest, avd_set, avd_set_name):
    avd_schema_dict = avd_manifest.avd_schema_dict

    for avd in avd_set.avd_list:
        if avd_manifest.contains_schema(avd.avd_name):
            Printer.system_message(TAG, "AVD schema " + Color.GREEN + avd.avd_name + Color.BLUE
                                   + " was found in AvdManifest.")
        else:
            message = "Set '{}' requests usage of AVD schema with name '{}' which doesn't exists in AVD schema list."
            message = message.format(avd_set_name, avd.avd_name)
            raise LauncherFlowInterruptedException(TAG, message)

    return avd_schema_dict
예제 #27
0
    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)
        test_cmd_templates = self._prepare_launch_test_cmds_for_run(
            test_packages, devices, test_set.shard)

        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 + ".")

        self._run_tests(devices, test_cmd_templates)
예제 #28
0
    def build_apk(self, test_set):
        Printer.system_message(
            self.TAG, "Building application and test .*apk from scratch.")

        session_logger.log_app_apk_build_start_time()
        self.gradle_controller.build_application_apk(test_set)
        session_logger.log_app_apk_build_end_time()

        session_logger.log_test_apk_build_start_time()
        self.gradle_controller.build_test_apk(test_set)
        session_logger.log_test_apk_build_end_time()

        return self.get_existing_apk(test_set)
 def _check_if_gradle_binary_was_found(self):
     self.project_root_found = GlobalConfig.PROJECT_ROOT_DIR != "" and os.path.isdir(
         GlobalConfig.PROJECT_ROOT_DIR)
     self.gradlew_found = os.path.isfile(self.gradle_bin)
     if self.project_root_found:
         Printer.system_message(
             self.TAG, "Project root dir " + Color.GREEN +
             GlobalConfig.PROJECT_ROOT_DIR + Color.BLUE +
             " was found! Building new .*apk is possible.")
         if self.gradlew_found:
             Printer.system_message(
                 self.TAG, "gradlew binary found at " + Color.GREEN +
                 str(self.gradle_bin) + Color.BLUE + ".")
예제 #30
0
def _load_test_set(test_manifest, test_set_name):
    if test_manifest.contains_set(test_set_name):
        Printer.system_message(
            TAG, "Test set " + Color.GREEN + test_set_name + Color.BLUE +
            " was found in TestManifest.")

        test_set = test_manifest.get_set(test_set_name)
        Printer.system_message(TAG,
                               "Test set contains following package names: ")
        for package_name in test_set.set_package_names:
            Printer.system_message(
                TAG, "  * " + Color.GREEN + package_name + Color.BLUE)

        found_all_packages = True
        errors = ""
        for package_name in test_set.set_package_names:
            if not test_manifest.contains_package(package_name):
                found_all_packages = False
                errors += "\n              - Test package '" + package_name + "' was not found in TestManifest!"

        if found_all_packages:
            Printer.system_message(
                TAG, "All test packages from set " + Color.GREEN +
                test_set_name + Color.BLUE + " were found in TestManifest.")
        else:
            raise LauncherFlowInterruptedException(TAG, errors)
    else:
        message = "Test set '{}' not found in TestManifest. Launcher will quit."
        message = message.format(test_set_name)
        raise LauncherFlowInterruptedException(TAG, message)

    return test_set