Esempio n. 1
0
def adb_shell(device,
              command,
              timeout=None,
              check_exit_code=False,
              as_root=False):  # NOQA
    _check_env()
    if as_root:
        command = 'echo "{}" | su'.format(escape_double_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 $?'".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('\n', 2)
            except ValueError:
                exit_code, _ = raw_output.rsplit('\n', 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
Esempio n. 2
0
def adb_shell(device, command, timeout=None, check_exit_code=False, as_root=False):  # NOQA
    _check_env()
    if as_root:
        command = 'echo "{}" | su'.format(escape_double_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 $?'".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('\n', 2)
            except ValueError:
                exit_code, _ = raw_output.rsplit('\n', 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
Esempio n. 3
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)
Esempio n. 4
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)
Esempio n. 5
0
    def execute(self, state, args):
        name = identifier(args.plugin)
        rst_output = None

        if name == caseless_string('settings'):
            rst_output = get_rst_for_global_config()
            rst_output += get_rst_for_envars()
            plugin_name = name.lower()
            kind = 'global:'
        else:
            try:
                plugin = pluginloader.get_plugin_class(name)
            except NotFoundError:
                plugin = None
            if plugin:
                rst_output = get_rst_from_plugin(plugin)
                plugin_name = plugin.name
                kind = '{}:'.format(plugin.kind)
            else:
                target = get_target_description(name)
                if target:
                    rst_output = get_rst_from_target(target)
                    plugin_name = target.name
                    kind = 'target:'

        if not rst_output:
            raise NotFoundError(
                'Could not find plugin or alias "{}"'.format(name))

        if which('pandoc'):
            p = Popen(['pandoc', '-f', 'rst', '-t', 'man'],
                      stdin=PIPE,
                      stdout=PIPE,
                      stderr=PIPE)
            if sys.version_info[0] == 3:
                output, _ = p.communicate(rst_output.encode(
                    sys.stdin.encoding))
                output = output.decode(sys.stdout.encoding)
            else:
                output, _ = p.communicate(rst_output)

            # Make sure to double escape back slashes
            output = output.replace('\\', '\\\\\\')

            # Correctly format the title and page number of the man page
            title, body = output.split('\n', 1)
            title = '.TH {}{} 7'.format(kind, plugin_name)
            output = '\n'.join([title, body])

            call('echo "{}" | man -l -'.format(escape_double_quotes(output)),
                 shell=True)
        else:
            print(rst_output)  # pylint: disable=superfluous-parens
Esempio n. 6
0
    def execute(self, state, args):
        name = identifier(args.plugin)
        rst_output = None

        if name == caseless_string('settings'):
            rst_output = get_rst_for_global_config()
            rst_output += get_rst_for_envars()
            plugin_name = name.lower()
            kind = 'global:'
        else:
            try:
                plugin = pluginloader.get_plugin_class(name)
            except NotFoundError:
                plugin = None
            if plugin:
                rst_output = get_rst_from_plugin(plugin)
                plugin_name = plugin.name
                kind = '{}:'.format(plugin.kind)
            else:
                target = get_target_description(name)
                if target:
                    rst_output = get_rst_from_target(target)
                    plugin_name = target.name
                    kind = 'target:'

        if not rst_output:
            raise NotFoundError('Could not find plugin or alias "{}"'.format(name))

        if which('pandoc'):
            p = Popen(['pandoc', '-f', 'rst', '-t', 'man'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
            if sys.version_info[0] == 3:
                output, _ = p.communicate(rst_output.encode(sys.stdin.encoding))
                output = output.decode(sys.stdout.encoding)
            else:
                output, _ = p.communicate(rst_output)

            # Make sure to double escape back slashes
            output = output.replace('\\', '\\\\\\')

            # Correctly format the title and page number of the man page
            title, body = output.split('\n', 1)
            title = '.TH {}{} 7'.format(kind, plugin_name)
            output = '\n'.join([title, body])

            call('echo "{}" | man -l -'.format(escape_double_quotes(output)), shell=True)
        else:
            print(rst_output)  # pylint: disable=superfluous-parens
Esempio n. 7
0
 def kick_off(self, command, as_root=False):
     command = 'sh -c "{}" 1>/dev/null 2>/dev/null &'.format(escape_double_quotes(command))
     return self.conn.execute(command, as_root=as_root)
Esempio n. 8
0
    def _gem5_shell(self, command, as_root=False, timeout=None, check_exit_code=True, sync=True):  # pylint: disable=R0912
        """
        Execute a command in the gem5 shell

        This wraps the telnet connection to gem5 and processes the raw output.

        This method waits for the shell to return, and then will try and
        separate the output from the command from the command itself. If this
        fails, warn, but continue with the potentially wrong output.

        The exit code is also checked by default, and non-zero exit codes will
        raise a TargetError.
        """
        if sync:
            self._sync_gem5_shell()

        gem5_logger.debug("gem5_shell command: {}".format(command))

        if as_root:
            command = 'echo "{}" | su'.format(escape_double_quotes(command))

        # Send the actual command
        self.conn.send("{}\n".format(command))

        # Wait for the response. We just sit here and wait for the prompt to
        # appear, as gem5 might take a long time to provide the output. This
        # avoids timeout issues.
        command_index = -1
        while command_index == -1:
            if self.conn.prompt():
                output = re.sub(r' \r([^\n])', r'\1', self.conn.before)
                output = re.sub(r'[\b]', r'', output)
                # Deal with line wrapping
                output = re.sub(r'[\r].+?<', r'', output)
                command_index = output.find(command)

                # If we have -1, then we cannot match the command, but the
                # prompt has returned. Hence, we have a bit of an issue. We
                # warn, and return the whole output.
                if command_index == -1:
                    gem5_logger.warn("gem5_shell: Unable to match command in "
                                     "command output. Expect parsing errors!")
                    command_index = 0

        output = output[command_index + len(command):].strip()

        # If the gem5 system echoes the executed command, we need to remove that too!
        if self.strip_echoed_commands:
            command_index = output.find(command)
            if command_index != -1:
                output = output[command_index + len(command):].strip()

        gem5_logger.debug("gem5_shell output: {}".format(output))

        # We get a second prompt. Hence, we need to eat one to make sure that we
        # stay in sync. If we do not do this, we risk getting out of sync for
        # slower simulations.
        self.conn.expect([self.conn.UNIQUE_PROMPT, self.conn.PROMPT], timeout=self.default_timeout)

        if check_exit_code:
            exit_code_text = self._gem5_shell('echo $?', as_root=as_root,
                                             timeout=timeout, check_exit_code=False,
                                             sync=False)
            try:
                exit_code = int(exit_code_text.split()[0])
                if exit_code:
                    message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
                    raise TargetError(message.format(exit_code, command, output))
            except (ValueError, IndexError):
                gem5_logger.warning('Could not get exit code for "{}",\ngot: "{}"'.format(command, exit_code_text))

        return output
Esempio n. 9
0
 def pull(self, source, dest, timeout=30):
     source = '"{}"@"{}":"{}"'.format(escape_double_quotes(self.username),
                                      escape_spaces(escape_double_quotes(self.host)),
                                      escape_spaces(escape_double_quotes(source)))
     return self._scp(source, dest, timeout)
Esempio n. 10
0
    def _gem5_shell(self, command, as_root=False, timeout=None, check_exit_code=True, sync=True):  # pylint: disable=R0912
        """
        Execute a command in the gem5 shell

        This wraps the telnet connection to gem5 and processes the raw output.

        This method waits for the shell to return, and then will try and
        separate the output from the command from the command itself. If this
        fails, warn, but continue with the potentially wrong output.

        The exit code is also checked by default, and non-zero exit codes will
        raise a TargetError.
        """
        if sync:
            self._sync_gem5_shell()

        gem5_logger.debug("gem5_shell command: {}".format(command))

        if as_root:
            command = 'echo "{}" | su'.format(escape_double_quotes(command))

        # Send the actual command
        self.conn.send("{}\n".format(command))

        # Wait for the response. We just sit here and wait for the prompt to
        # appear, as gem5 might take a long time to provide the output. This
        # avoids timeout issues.
        command_index = -1
        while command_index == -1:
            if self.conn.prompt():
                output = re.sub(r' \r([^\n])', r'\1', self.conn.before)
                output = re.sub(r'[\b]', r'', output)
                # Deal with line wrapping
                output = re.sub(r'[\r].+?<', r'', output)
                command_index = output.find(command)

                # If we have -1, then we cannot match the command, but the
                # prompt has returned. Hence, we have a bit of an issue. We
                # warn, and return the whole output.
                if command_index == -1:
                    gem5_logger.warn("gem5_shell: Unable to match command in "
                                     "command output. Expect parsing errors!")
                    command_index = 0

        output = output[command_index + len(command):].strip()

        # It is possible that gem5 will echo the command. Therefore, we need to
        # remove that too!
        command_index = output.find(command)
        if command_index != -1:
            output = output[command_index + len(command):].strip()

        gem5_logger.debug("gem5_shell output: {}".format(output))

        # We get a second prompt. Hence, we need to eat one to make sure that we
        # stay in sync. If we do not do this, we risk getting out of sync for
        # slower simulations.
        self.conn.expect([self.conn.UNIQUE_PROMPT, self.conn.PROMPT], timeout=self.default_timeout)

        if check_exit_code:
            exit_code_text = self._gem5_shell('echo $?', as_root=as_root,
                                             timeout=timeout, check_exit_code=False,
                                             sync=False)
            try:
                exit_code = int(exit_code_text.split()[0])
                if exit_code:
                    message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
                    raise TargetError(message.format(exit_code, command, output))
            except (ValueError, IndexError):
                gem5_logger.warning('Could not get exit code for "{}",\ngot: "{}"'.format(command, exit_code_text))

        return output