Пример #1
0
def adb_shell(device,
              command,
              timeout=None,
              check_exit_code=False,
              as_root=False,
              newline_separator='\r\n'):  # NOQA
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_string = ' -s {}'.format(device) if device else ''
    full_command = 'adb{} shell "{}"'.format(device_string,
                                             escape_double_quotes(command))
    logger.debug(full_command)
    if check_exit_code:
        actual_command = "adb{} shell '({}); echo \"\n$?\"'".format(
            device_string, escape_single_quotes(command))
        raw_output, error = check_output(actual_command, timeout, shell=True)
        if raw_output:
            try:
                output, exit_code, _ = raw_output.rsplit(newline_separator, 2)
            except ValueError:
                exit_code, _ = raw_output.rsplit(newline_separator, 1)
                output = ''
        else:  # raw_output is empty
            exit_code = '969696'  # just because
            output = ''

        exit_code = exit_code.strip()
        if exit_code.isdigit():
            if int(exit_code):
                message = 'Got exit code {}\nfrom: {}\nSTDOUT: {}\nSTDERR: {}'
                raise TargetError(
                    message.format(exit_code, full_command, output, error))
            elif AM_START_ERROR.findall(output):
                message = 'Could not start activity; got the following:'
                message += '\n{}'.format(AM_START_ERROR.findall(output)[0])
                raise TargetError(message)
        else:  # not all digits
            if AM_START_ERROR.findall(output):
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(
                    message.format(AM_START_ERROR.findall(output)[0]))
            else:
                message = 'adb has returned early; did not get an exit code. '\
                          'Was kill-server invoked?'
                raise TargetError(message)
    else:  # do not check exit code
        output, _ = check_output(full_command, timeout, shell=True)
    return output
Пример #2
0
 def _execute_and_wait_for_prompt(self, command, timeout=None, as_root=False, strip_colors=True, log=True):
     self.conn.prompt(0.1)  # clear an existing prompt if there is one.
     if as_root:
         command = "sudo -- sh -c '{}'".format(escape_single_quotes(command))
         if log:
             logger.debug(command)
         self.conn.sendline(command)
         if self.password:
             index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5)
             if index == 0:
                 self.conn.sendline(self.password)
     else:  # not as_root
         if log:
             logger.debug(command)
         self.conn.sendline(command)
     timed_out = self._wait_for_prompt(timeout)
     # the regex removes line breaks potential introduced when writing
     # command to shell.
     output = process_backspaces(self.conn.before)
     output = re.sub(r"\r([^\n])", r"\1", output)
     if "\r\n" in output:  # strip the echoed command
         output = output.split("\r\n", 1)[1]
     if timed_out:
         self.cancel_running_command()
         raise TimeoutError(command, output)
     if strip_colors:
         output = strip_bash_colors(output)
     return output
Пример #3
0
 def _execute_and_wait_for_prompt(self,
                                  command,
                                  timeout=None,
                                  as_root=False,
                                  strip_colors=True,
                                  log=True):
     self.conn.prompt(0.1)  # clear an existing prompt if there is one.
     if as_root:
         command = "sudo -- sh -c '{}'".format(
             escape_single_quotes(command))
         if log:
             logger.debug(command)
         self.conn.sendline(command)
         if self.password:
             index = self.conn.expect_exact([self.password_prompt, TIMEOUT],
                                            timeout=0.5)
             if index == 0:
                 self.conn.sendline(self.password)
     else:  # not as_root
         if log:
             logger.debug(command)
         self.conn.sendline(command)
     timed_out = self._wait_for_prompt(timeout)
     # the regex removes line breaks potential introduced when writing
     # command to shell.
     output = process_backspaces(self.conn.before)
     output = re.sub(r'\r([^\n])', r'\1', output)
     if '\r\n' in output:  # strip the echoed command
         output = output.split('\r\n', 1)[1]
     if timed_out:
         self.cancel_running_command()
         raise TimeoutError(command, output)
     if strip_colors:
         output = strip_bash_colors(output)
     return output
Пример #4
0
def adb_shell(device,
              command,
              timeout=None,
              check_exit_code=False,
              as_root=False,
              adb_server=None):  # NOQA
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_part = []
    if adb_server:
        device_part = ['-H', adb_server]
    device_part += ['-s', device] if device else []

    # On older combinations of ADB/Android versions, the adb host command always
    # exits with 0 if it was able to run the command on the target, even if the
    # command failed (https://code.google.com/p/android/issues/detail?id=3254).
    # Homogenise this behaviour by running the command then echoing the exit
    # code.
    adb_shell_command = '({}); echo \"\n$?\"'.format(command)
    actual_command = ['adb'] + device_part + ['shell', adb_shell_command]
    logger.debug('adb {} shell {}'.format(' '.join(device_part), command))
    raw_output, error = check_output(actual_command, timeout, shell=False)
    if raw_output:
        try:
            output, exit_code, _ = raw_output.replace('\r\n', '\n').replace(
                '\r', '\n').rsplit('\n', 2)
        except ValueError:
            exit_code, _ = raw_output.replace('\r\n', '\n').replace(
                '\r', '\n').rsplit('\n', 1)
            output = ''
    else:  # raw_output is empty
        exit_code = '969696'  # just because
        output = ''

    if check_exit_code:
        exit_code = exit_code.strip()
        re_search = AM_START_ERROR.findall('{}\n{}'.format(output, error))
        if exit_code.isdigit():
            if int(exit_code):
                message = ('Got exit code {}\nfrom target command: {}\n'
                           'STDOUT: {}\nSTDERR: {}')
                raise TargetError(
                    message.format(exit_code, command, output, error))
            elif re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
        else:  # not all digits
            if re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
            else:
                message = 'adb has returned early; did not get an exit code. '\
                          'Was kill-server invoked?\nOUTPUT:\n-----\n{}\n'\
                          '-----\nERROR:\n-----\n{}\n-----'
                raise TargetError(message.format(raw_output, error))

    return output
Пример #5
0
def adb_shell(device, command, timeout=None, check_exit_code=False,
              as_root=False, newline_separator='\r\n'):  # NOQA
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_string = ' -s {}'.format(device) if device else ''
    full_command = 'adb{} shell "{}"'.format(device_string,
                                             escape_double_quotes(command))
    logger.debug(full_command)
    if check_exit_code:
        actual_command = "adb{} shell '({}); echo \"\n$?\"'".format(device_string,
                                                                    escape_single_quotes(command))
        raw_output, error = check_output(actual_command, timeout, shell=True)
        if raw_output:
            try:
                output, exit_code, _ = raw_output.rsplit(newline_separator, 2)
            except ValueError:
                exit_code, _ = raw_output.rsplit(newline_separator, 1)
                output = ''
        else:  # raw_output is empty
            exit_code = '969696'  # just because
            output = ''

        exit_code = exit_code.strip()
        if exit_code.isdigit():
            if int(exit_code):
                message = 'Got exit code {}\nfrom: {}\nSTDOUT: {}\nSTDERR: {}'
                raise TargetError(message.format(exit_code, full_command, output, error))
            elif AM_START_ERROR.findall(output):
                message = 'Could not start activity; got the following:'
                message += '\n{}'.format(AM_START_ERROR.findall(output)[0])
                raise TargetError(message)
        else:  # not all digits
            if AM_START_ERROR.findall(output):
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(AM_START_ERROR.findall(output)[0]))
            else:
                message = 'adb has returned early; did not get an exit code. '\
                          'Was kill-server invoked?'
                raise TargetError(message)
    else:  # do not check exit code
        output, _ = check_output(full_command, timeout, shell=True)
    return output
Пример #6
0
def adb_background_shell(device, command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         as_root=False):
    """Runs the sepcified command in a subprocess, returning the the Popen object."""
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_string = ' -s {}'.format(device) if device else ''
    full_command = 'adb{} shell "{}"'.format(device_string, escape_double_quotes(command))
    logger.debug(full_command)
    return subprocess.Popen(full_command, stdout=stdout, stderr=stderr, shell=True)
Пример #7
0
def adb_background_shell(device, command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         as_root=False):
    """Runs the sepcified command in a subprocess, returning the the Popen object."""
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_string = ' -s {}'.format(device) if device else ''
    full_command = 'adb{} shell "{}"'.format(device_string, escape_double_quotes(command))
    logger.debug(full_command)
    return subprocess.Popen(full_command, stdout=stdout, stderr=stderr, shell=True)
Пример #8
0
def adb_shell(device, command, timeout=None, check_exit_code=False,
              as_root=False, adb_server=None):  # NOQA
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_part = []
    if adb_server:
        device_part = ['-H', adb_server]
    device_part += ['-s', device] if device else []

    # On older combinations of ADB/Android versions, the adb host command always
    # exits with 0 if it was able to run the command on the target, even if the
    # command failed (https://code.google.com/p/android/issues/detail?id=3254).
    # Homogenise this behaviour by running the command then echoing the exit
    # code.
    adb_shell_command = '({}); echo \"\n$?\"'.format(command)
    actual_command = ['adb'] + device_part + ['shell', adb_shell_command]
    logger.debug('adb {} shell {}'.format(' '.join(device_part), command))
    raw_output, error = check_output(actual_command, timeout, shell=False)
    if raw_output:
        try:
            output, exit_code, _ = raw_output.replace('\r\n', '\n').replace('\r', '\n').rsplit('\n', 2)
        except ValueError:
            exit_code, _ = raw_output.replace('\r\n', '\n').replace('\r', '\n').rsplit('\n', 1)
            output = ''
    else:  # raw_output is empty
        exit_code = '969696'  # just because
        output = ''

    if check_exit_code:
        exit_code = exit_code.strip()
        re_search = AM_START_ERROR.findall('{}\n{}'.format(output, error))
        if exit_code.isdigit():
            if int(exit_code):
                message = ('Got exit code {}\nfrom target command: {}\n'
                           'STDOUT: {}\nSTDERR: {}')
                raise TargetError(message.format(exit_code, command, output, error))
            elif re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
        else:  # not all digits
            if re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
            else:
                message = 'adb has returned early; did not get an exit code. '\
                          'Was kill-server invoked?\nOUTPUT:\n-----\n{}\n'\
                          '-----\nERROR:\n-----\n{}\n-----'
                raise TargetError(message.format(raw_output, error))

    return output
Пример #9
0
 def _execute_and_wait_for_prompt(self,
                                  command,
                                  timeout=None,
                                  as_root=False,
                                  strip_colors=True,
                                  log=True):
     self.conn.prompt(0.1)  # clear an existing prompt if there is one.
     if self.username == 'root':
         # As we're already root, there is no need to use sudo.
         as_root = False
     if as_root:
         command = self.sudo_cmd.format(escape_single_quotes(command))
         if log:
             logger.debug(command)
         self.conn.sendline(command)
         if self.password:
             index = self.conn.expect_exact([self.password_prompt, TIMEOUT],
                                            timeout=0.5)
             if index == 0:
                 self.conn.sendline(self.password)
     else:  # not as_root
         if log:
             logger.debug(command)
         self.conn.sendline(command)
     timed_out = self._wait_for_prompt(timeout)
     # the regex removes line breaks potential introduced when writing
     # command to shell.
     if sys.version_info[0] == 3:
         output = process_backspaces(
             self.conn.before.decode(sys.stdout.encoding, 'replace'))
     else:
         output = process_backspaces(self.conn.before)
     output = re.sub(r'\r([^\n])', r'\1', output)
     if '\r\n' in output:  # strip the echoed command
         output = output.split('\r\n', 1)[1]
     if timed_out:
         self.cancel_running_command()
         raise TimeoutError(command, output)
     if strip_colors:
         output = strip_bash_colors(output)
     return output