예제 #1
0
def _ExecuteOneShellCommandWithTimeout(cmd,
                                       timeout,
                                       callback_on_timeout=None,
                                       *args):
    """Executes a command with timeout.

    If the process times out, this function terminates it and continues
    waiting.

    Args:
        proc: Popen object, the process to wait for.
        timeout: float, timeout in seconds.
        callback_on_timeout: callable, callback function for the case
                             when the command times out.
        args: arguments for the callback_on_timeout.

    Returns:
        tuple(string, string, int) which are stdout, stderr and return code.
    """
    # On Windows, subprocess.Popen(shell=True) starts two processes, cmd.exe
    # and the command. The Popen object represents the cmd.exe process, so
    # calling Popen.kill() does not terminate the command.
    # This function uses process group to ensure command termination.
    proc = utils.start_standing_subprocess(cmd)
    result = []

    def WaitForProcess():
        out, err = proc.communicate()
        result.append((out, err, proc.returncode))

    wait_thread = threading.Thread(target=WaitForProcess)
    wait_thread.daemon = True
    wait_thread.start()
    try:
        wait_thread.join(timeout)
    finally:
        if proc.poll() is None:
            utils.kill_process_group(proc)
        if callback_on_timeout is not None:
            if ((utils.is_on_windows()
                 and proc.returncode == EXIT_CODE_TIMEOUT_ON_WINDOWS)
                    or proc.returncode == EXIT_CODE_TIMEOUT_ON_LINUX):
                callback_on_timeout(*args)
    wait_thread.join()

    if len(result) != 1:
        logging.error("Unexpected command result: %s", result)
        return "", "", proc.returncode
    return result[0]
 def startAdbLogcat(self):
     """Starts a standing adb logcat collection in separate subprocesses and
     save the logcat in a file.
     """
     if self.isAdbLogcatOn:
         raise AndroidDeviceError(("Android device %s already has an adb "
                                   "logcat thread going on. Cannot start "
                                   "another one.") % self.serial)
     f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
     utils.create_dir(self.log_path)
     logcat_file_path = os.path.join(self.log_path, f_name)
     try:
         extra_params = self.adb_logcat_param
     except AttributeError:
         extra_params = "-b all"
     cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
         self.serial, extra_params, logcat_file_path)
     self.adb_logcat_process = utils.start_standing_subprocess(cmd)
     self.adb_logcat_file_path = logcat_file_path
예제 #3
0
    def startVtsAgent(self):
        """Start HAL agent on the AndroidDevice.

        This function starts the target side native agent and is persisted
        throughout the test run.
        """
        self.log.info("Starting VTS agent")
        if self.vts_agent_process:
            raise AndroidDeviceError("HAL agent is already running on %s." %
                                     self.serial)

        event = tfi.Begin("start vts agent", tfi.categories.FRAMEWORK_SETUP)

        self._StopLLKD()

        event_cleanup = tfi.Begin("start vts agent -- cleanup",
                                  tfi.categories.FRAMEWORK_SETUP)
        cleanup_commands = [
            "rm -f /data/local/tmp/vts_driver_*",
            "rm -f /data/local/tmp/vts_agent_callback*"
        ]

        kill_command = "pgrep 'vts_*' | xargs kill"
        cleanup_commands.append(kill_command)
        try:
            self.adb.shell("\"" + " ; ".join(cleanup_commands) + "\"")
        except adb.AdbError as e:
            self.log.warning(
                "A command to setup the env to start the VTS Agent failed %s",
                e)
        event_cleanup.End()

        log_severity = getattr(self, keys.ConfigKeys.KEY_LOG_SEVERITY, "INFO")
        bits = ['64', '32'] if self.is64Bit else ['32']
        file_names = ['vts_hal_agent', 'vts_hal_driver', 'vts_shell_driver']
        for bitness in bits:
            vts_agent_log_path = os.path.join(
                self.log_path, 'vts_agent_%s_%s.log' % (bitness, self.serial))

            chmod_cmd = ' '.join(
                map(
                    lambda file_name:
                    'chmod 755 {path}/{bit}/{file_name}{bit};'.format(
                        path=DEFAULT_AGENT_BASE_DIR,
                        bit=bitness,
                        file_name=file_name), file_names))

            cmd = (
                'adb -s {s} shell "{chmod} LD_LIBRARY_PATH={path}/{bitness} '
                '{path}/{bitness}/vts_hal_agent{bitness} '
                '--hal_driver_path_32={path}/32/vts_hal_driver32 '
                '--hal_driver_path_64={path}/64/vts_hal_driver64 '
                '--spec_dir={path}/spec '
                '--shell_driver_path_32={path}/32/vts_shell_driver32 '
                '--shell_driver_path_64={path}/64/vts_shell_driver64 '
                '-l {severity}" >> {log} 2>&1').format(
                    s=self.serial,
                    chmod=chmod_cmd,
                    bitness=bitness,
                    path=DEFAULT_AGENT_BASE_DIR,
                    log=vts_agent_log_path,
                    severity=log_severity)
            try:
                self.vts_agent_process = utils.start_standing_subprocess(
                    cmd, check_health_delay=1)
                break
            except utils.VTSUtilsError as e:
                logging.exception(e)
                with open(vts_agent_log_path, 'r') as log_file:
                    logging.error("VTS agent output:\n")
                    logging.error(log_file.read())
                # one common cause is that 64-bit executable is not supported
                # in low API level devices.
                if bitness == '32':
                    msg = "unrecognized bitness"
                    event.Remove(msg)
                    logging.error(msg)
                    raise
                else:
                    logging.error('retrying using a 32-bit binary.')
        event.End()
    def startVtsAgent(self):
        """Start HAL agent on the AndroidDevice.

        This function starts the target side native agent and is persisted
        throughout the test run.
        """
        self.log.info("Starting VTS agent")
        if self.vts_agent_process:
            raise AndroidDeviceError("HAL agent is already running on %s." %
                                     self.serial)

        cleanup_commands = [
            "rm -f /data/local/tmp/vts_driver_*",
            "rm -f /data/local/tmp/vts_agent_callback*"
        ]
        kill_commands = ["killall vts_hal_agent32", "killall vts_hal_agent64",
                         "killall fuzzer32", "killall fuzzer64",
                         "killall vts_shell_driver32",
                         "killall vts_shell_driver64"]
        cleanup_commands.extend(kill_commands)
        chmod_commands = [
            "chmod 755 %s/32/vts_hal_agent32" % DEFAULT_AGENT_BASE_DIR,
            "chmod 755 %s/64/vts_hal_agent64" % DEFAULT_AGENT_BASE_DIR,
            "chmod 755 %s/32/fuzzer32" % DEFAULT_AGENT_BASE_DIR,
            "chmod 755 %s/64/fuzzer64" % DEFAULT_AGENT_BASE_DIR,
            "chmod 755 %s/32/vts_shell_driver32" % DEFAULT_AGENT_BASE_DIR,
            "chmod 755 %s/64/vts_shell_driver64" % DEFAULT_AGENT_BASE_DIR
        ]
        cleanup_commands.extend(chmod_commands)
        for cmd in cleanup_commands:
            try:
                self.adb.shell(cmd)
            except adb.AdbError as e:
                self.log.warning(
                    "A command to setup the env to start the VTS Agent failed %s",
                    e)

        bits = ['64', '32'] if self.is64Bit else ['32']
        for bitness in bits:
            vts_agent_log_path = os.path.join(self.log_path,
                     "vts_agent_" + bitness + ".log")
            cmd = (
                'adb -s {s} shell LD_LIBRARY_PATH={path}/{bitness} '
                '{path}/{bitness}/vts_hal_agent{bitness}'
                ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
                ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log} 2>&1'
            ).format(s=self.serial,
                     bitness=bitness,
                     path=DEFAULT_AGENT_BASE_DIR,
                     log=vts_agent_log_path)
            try:
                self.vts_agent_process = utils.start_standing_subprocess(
                    cmd, check_health_delay=1)
                break
            except utils.VTSUtilsError as e:
                logging.exception(e)
                with open(vts_agent_log_path, 'r') as log_file:
                    logging.error("VTS agent output:\n")
                    logging.error(log_file.read())
                # one common cause is that 64-bit executable is not supported
                # in low API level devices.
                if bitness == '32':
                    raise
                else:
                    logging.error('retrying using a 32-bit binary.')