예제 #1
0
  def Run(self, test, device, flags=None, **kwargs):
    extras = dict(self._extras)

    with device_temp_file.DeviceTempFile(device.adb) as command_line_file:
      device.WriteFile(command_line_file.name, '_ %s' % flags if flags else '_')
      extras[_EXTRA_COMMAND_LINE_FILE] = command_line_file.name

      with device_temp_file.DeviceTempFile(device.adb) as test_list_file:
        if test:
          device.WriteFile(test_list_file.name, '\n'.join(test))
          extras[_EXTRA_TEST_LIST] = test_list_file.name

        return device.StartInstrumentation(
            self._component, extras=extras, raw=False, **kwargs)
예제 #2
0
파일: md5sum.py 프로젝트: TobbyT/mojo-apps
def CalculateDeviceMd5Sums(paths, device):
  """Calculates the MD5 sum value for all items in |paths|.

  Args:
    paths: A list of device paths to md5sum.
  Returns:
    A list of named tuples with 'hash' and 'path' attributes.
  """
  if isinstance(paths, basestring):
    paths = [paths]

  if not device.FileExists(MD5SUM_DEVICE_BIN_PATH):
    device.adb.Push(
        os.path.join(constants.GetOutDirectory(), 'md5sum_dist'),
        MD5SUM_DEVICE_LIB_PATH)

  out = []
  with tempfile.NamedTemporaryFile() as md5sum_script_file:
    with device_temp_file.DeviceTempFile(device) as md5sum_device_script_file:
      md5sum_script = (
          MD5SUM_DEVICE_SCRIPT_FORMAT.format(
              path=p, md5sum_lib=MD5SUM_DEVICE_LIB_PATH,
              md5sum_bin=MD5SUM_DEVICE_BIN_PATH)
          for p in paths)
      md5sum_script_file.write('; '.join(md5sum_script))
      md5sum_script_file.flush()
      device.adb.Push(md5sum_script_file.name, md5sum_device_script_file.name)
      out = device.RunShellCommand(['sh', md5sum_device_script_file.name])

  return [HashAndPath(*l.split(None, 1)) for l in out]
예제 #3
0
    def RunWithFlags(self, device, flags, **kwargs):
        cmd = [
            self._test_run.GetTool(device).GetTestWrapper(),
            self._exe_device_path,
            flags,
        ]
        cwd = constants.TEST_EXECUTABLE_DIR

        env = {
            'LD_LIBRARY_PATH':
            '%s/%s_deps' %
            (constants.TEST_EXECUTABLE_DIR, self._exe_file_name),
        }
        try:
            gcov_strip_depth = os.environ['NATIVE_COVERAGE_DEPTH_STRIP']
            external = device.GetExternalStoragePath()
            env['GCOV_PREFIX'] = '%s/gcov' % external
            env['GCOV_PREFIX_STRIP'] = gcov_strip_depth
        except (device_errors.CommandFailedError, KeyError):
            pass

        # TODO(jbudorick): Switch to just RunShellCommand once perezju@'s CL
        # for long shell commands lands.
        with device_temp_file.DeviceTempFile(device.adb) as script_file:
            script_contents = ' '.join(cmd)
            logging.info('script contents: %r' % script_contents)
            device.WriteFile(script_file.name, script_contents)
            output = device.RunShellCommand(['sh', script_file.name],
                                            cwd=cwd,
                                            env=env,
                                            **kwargs)
        return output
예제 #4
0
    def TakeScreenshot(self, host_path=None, timeout=None, retries=None):
        """Takes a screenshot of the device.

    Args:
      host_path: A string containing the path on the host to save the
                 screenshot to. If None, a file name in the current
                 directory will be generated.
      timeout: timeout in seconds
      retries: number of retries

    Returns:
      The name of the file on the host to which the screenshot was saved.

    Raises:
      CommandFailedError on failure.
      CommandTimeoutError on timeout.
      DeviceUnreachableError on missing device.
    """
        if not host_path:
            host_path = os.path.abspath('screenshot-%s.png' % _GetTimeStamp())
        with device_temp_file.DeviceTempFile(self.adb,
                                             suffix='.png') as device_tmp:
            self.RunShellCommand(
                ['/system/bin/screencap', '-p', device_tmp.name],
                check_return=True)
            self.PullFile(device_tmp.name, host_path)
        return host_path
예제 #5
0
def CalculateDeviceMd5Sums(paths, device):
    """Calculates the MD5 sum value for all items in |paths|.

  Args:
    paths: A list of device paths to md5sum.
  Returns:
    A dict mapping paths to their respective md5sum checksums.
  """
    if isinstance(paths, basestring):
        paths = [paths]

    if not device.FileExists(MD5SUM_DEVICE_BIN_PATH):
        md5sum_dist_path = os.path.join(constants.GetOutDirectory(),
                                        'md5sum_dist')
        if not os.path.exists(md5sum_dist_path):
            raise IOError('File not built: %s' % md5sum_dist_path)
        device.adb.Push(md5sum_dist_path, MD5SUM_DEVICE_LIB_PATH)

    out = []

    with tempfile.NamedTemporaryFile() as md5sum_script_file:
        with device_temp_file.DeviceTempFile(
                device.adb) as md5sum_device_script_file:
            md5sum_script = (MD5SUM_DEVICE_SCRIPT_FORMAT.format(
                path=p,
                md5sum_lib=MD5SUM_DEVICE_LIB_PATH,
                md5sum_bin=MD5SUM_DEVICE_BIN_PATH) for p in paths)
            md5sum_script_file.write('; '.join(md5sum_script))
            md5sum_script_file.flush()
            device.adb.Push(md5sum_script_file.name,
                            md5sum_device_script_file.name)
            out = device.RunShellCommand(
                ['sh', md5sum_device_script_file.name])

    return _ParseMd5SumOutput(out)
예제 #6
0
  def RunWithFlags(self, device, flags, **kwargs):
    with device_temp_file.DeviceTempFile(device.adb) as command_line_file:
      device.WriteFile(command_line_file.name, '_ %s' % flags)

      return device.StartInstrumentation(
          self._component,
          extras={_EXTRA_COMMAND_LINE_FILE: command_line_file.name},
          raw=False,
          **kwargs)
예제 #7
0
 def testTempFileNameAlreadyExists(self):
   with self.assertCalls(
       self.mockShellCall('test -d /data/local/tmp'),
       self.mockExistsTest(True),
       self.mockExistsTest(True),
       self.mockExistsTest(True),
       self.mockExistsTest(False),
       self.mockShellCall('touch '),
       self.mockShellCall('rm -f ')):
     with device_temp_file.DeviceTempFile(self.adb) as tmpfile:
       logging.debug('Temp file name: %s' % tmpfile.name)
예제 #8
0
 def testTempFileLifecycle(self):
   with self.assertCalls(
       self.mockShellCall('test -d /data/local/tmp'),
       self.mockExistsTest(False),
       self.mockShellCall('touch ')):
     tempFileContextManager = device_temp_file.DeviceTempFile(self.adb)
   with mock.patch.object(self.adb, 'Shell'):
     with tempFileContextManager as tmpfile:
       logging.debug('Temp file name: %s' % tmpfile.name)
       self.assertEquals(0, self.adb.Shell.call_count)
     self.assertEquals(1, self.adb.Shell.call_count)
     args, _ = self.adb.Shell.call_args
     self.assertTrue(args[0].startswith('rm -f '))
예제 #9
0
    def RunWithFlags(self, device, flags, **kwargs):
        with device_temp_file.DeviceTempFile(device.adb) as command_line_file:
            device.WriteFile(command_line_file.name, '_ %s' % flags)

            extras = {
                _EXTRA_COMMAND_LINE_FILE: command_line_file.name,
            }
            if self._enable_test_server_spawner:
                extras[_EXTRA_ENABLE_TEST_SERVER_SPAWNER] = '1'

            return device.StartInstrumentation(self._component,
                                               extras=extras,
                                               raw=False,
                                               **kwargs)
예제 #10
0
    def WriteFile(self,
                  device_path,
                  contents,
                  as_root=False,
                  force_push=False,
                  timeout=None,
                  retries=None):
        """Writes |contents| to a file on the device.

    Args:
      device_path: A string containing the absolute path to the file to write
          on the device.
      contents: A string containing the data to write to the device.
      as_root: A boolean indicating whether the write should be executed with
          root privileges (if available).
      force_push: A boolean indicating whether to force the operation to be
          performed by pushing a file to the device. The default is, when the
          contents are short, to pass the contents using a shell script instead.
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      CommandFailedError if the file could not be written on the device.
      CommandTimeoutError on timeout.
      DeviceUnreachableError on missing device.
    """
        if len(contents) < 512 and not force_push:
            cmd = 'echo -n %s > %s' % (cmd_helper.SingleQuote(contents),
                                       cmd_helper.SingleQuote(device_path))
            self.RunShellCommand(cmd, as_root=as_root, check_return=True)
        else:
            with tempfile.NamedTemporaryFile() as host_temp:
                host_temp.write(contents)
                host_temp.flush()
                if as_root and self.NeedsSU():
                    with device_temp_file.DeviceTempFile(
                            self.adb) as device_temp:
                        self.adb.Push(host_temp.name, device_temp.name)
                        # Here we need 'cp' rather than 'mv' because the temp and
                        # destination files might be on different file systems (e.g.
                        # on internal storage and an external sd card)
                        self.RunShellCommand(
                            ['cp', device_temp.name, device_path],
                            as_root=True,
                            check_return=True)
                else:
                    self.adb.Push(host_temp.name, device_path)
예제 #11
0
    def __init__(self, device, perf_binary, categories):
        self._device = device
        self._output_file = device_temp_file.DeviceTempFile(
            self._device.adb, prefix='perf_output')
        self._log_file = tempfile.TemporaryFile()

        # TODO(jbudorick) Look at providing a way to unhandroll this once the
        #                 adb rewrite has fully landed.
        device_param = (['-s', str(self._device)] if str(self._device) else [])
        cmd = ['adb'] + device_param + \
              ['shell', perf_binary, 'record',
               '--output', self._output_file.name] + _PERF_OPTIONS
        if categories:
            cmd += ['--event', ','.join(categories)]
        self._perf_control = perf_control.PerfControl(self._device)
        self._perf_control.SetPerfProfilingMode()
        self._perf_process = subprocess.Popen(cmd,
                                              stdout=self._log_file,
                                              stderr=subprocess.STDOUT)
 def GetPsOutput(self, columns, pid=None):
     assert columns == ['pid', 'name'] or columns == ['pid'], \
         'Only know how to return pid and name. Requested: ' + columns
     command = 'ps'
     if pid:
         command += ' -p %d' % pid
     with device_temp_file.DeviceTempFile(self._device.adb) as ps_out:
         command += ' > %s' % ps_out.name
         self._device.RunShellCommand(command)
         # Get rid of trailing new line and header.
         ps = self._device.ReadFile(ps_out.name).split('\n')[1:-1]
     output = []
     for line in ps:
         data = line.split()
         curr_pid = data[1]
         curr_name = data[-1]
         if columns == ['pid', 'name']:
             output.append([curr_pid, curr_name])
         else:
             output.append([curr_pid])
     return output
예제 #13
0
  def WriteFile(self, device_path, contents, as_root=False, force_push=False,
                timeout=None, retries=None):
    """Writes |contents| to a file on the device.

    Args:
      device_path: A string containing the absolute path to the file to write
          on the device.
      contents: A string containing the data to write to the device.
      as_root: A boolean indicating whether the write should be executed with
          root privileges (if available).
      force_push: A boolean indicating whether to force the operation to be
          performed by pushing a file to the device. The default is, when the
          contents are short, to pass the contents using a shell script instead.
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      CommandFailedError if the file could not be written on the device.
      CommandTimeoutError on timeout.
      DeviceUnreachableError on missing device.
    """
    if not force_push and len(contents) < self._MAX_ADB_COMMAND_LENGTH:
      # If the contents are small, for efficieny we write the contents with
      # a shell command rather than pushing a file.
      cmd = 'echo -n %s > %s' % (cmd_helper.SingleQuote(contents),
                                 cmd_helper.SingleQuote(device_path))
      self.RunShellCommand(cmd, as_root=as_root, check_return=True)
    elif as_root and self.NeedsSU():
      # Adb does not allow to "push with su", so we first push to a temp file
      # on a safe location, and then copy it to the desired location with su.
      with device_temp_file.DeviceTempFile(self.adb) as device_temp:
        self._WriteFileWithPush(device_temp.name, contents)
        # Here we need 'cp' rather than 'mv' because the temp and
        # destination files might be on different file systems (e.g.
        # on internal storage and an external sd card).
        self.RunShellCommand(['cp', device_temp.name, device_path],
                             as_root=True, check_return=True)
    else:
      # If root is not needed, we can push directly to the desired location.
      self._WriteFileWithPush(device_path, contents)
예제 #14
0
  def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
                      as_root=False, single_line=False,
                      timeout=None, retries=None):
    """Run an ADB shell command.

    The command to run |cmd| should be a sequence of program arguments or else
    a single string.

    When |cmd| is a sequence, it is assumed to contain the name of the command
    to run followed by its arguments. In this case, arguments are passed to the
    command exactly as given, without any further processing by the shell. This
    allows to easily pass arguments containing spaces or special characters
    without having to worry about getting quoting right. Whenever possible, it
    is recomended to pass |cmd| as a sequence.

    When |cmd| is given as a string, it will be interpreted and run by the
    shell on the device.

    This behaviour is consistent with that of command runners in cmd_helper as
    well as Python's own subprocess.Popen.

    TODO(perezju) Change the default of |check_return| to True when callers
      have switched to the new behaviour.

    Args:
      cmd: A string with the full command to run on the device, or a sequence
        containing the command and its arguments.
      check_return: A boolean indicating whether or not the return code should
        be checked.
      cwd: The device directory in which the command should be run.
      env: The environment variables with which the command should be run.
      as_root: A boolean indicating whether the shell command should be run
        with root privileges.
      single_line: A boolean indicating if only a single line of output is
        expected.
      timeout: timeout in seconds
      retries: number of retries

    Returns:
      If single_line is False, the output of the command as a list of lines,
      otherwise, a string with the unique line of output emmited by the command
      (with the optional newline at the end stripped).

    Raises:
      AdbCommandFailedError if check_return is True and the exit code of
        the command run on the device is non-zero.
      CommandFailedError if single_line is True but the output contains two or
        more lines.
      CommandTimeoutError on timeout.
      DeviceUnreachableError on missing device.
    """
    def env_quote(key, value):
      if not DeviceUtils._VALID_SHELL_VARIABLE.match(key):
        raise KeyError('Invalid shell variable name %r' % key)
      # using double quotes here to allow interpolation of shell variables
      return '%s=%s' % (key, cmd_helper.DoubleQuote(value))

    def do_run(cmd):
      try:
        return self.adb.Shell(cmd)
      except device_errors.AdbCommandFailedError as exc:
        if check_return:
          raise
        else:
          return exc.output

    if not isinstance(cmd, basestring):
      cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd)
    if env:
      env = ' '.join(env_quote(k, v) for k, v in env.iteritems())
      cmd = '%s %s' % (env, cmd)
    if cwd:
      cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd)
    if as_root and self.NeedsSU():
      # "su -c sh -c" allows using shell features in |cmd|
      cmd = 'su -c sh -c %s' % cmd_helper.SingleQuote(cmd)
    if timeout is None:
      timeout = self._default_timeout

    if len(cmd) < self._MAX_ADB_COMMAND_LENGTH:
      output = do_run(cmd)
    else:
      with device_temp_file.DeviceTempFile(self.adb, suffix='.sh') as script:
        self._WriteFileWithPush(script.name, cmd)
        logging.info('Large shell command will be run from file: %s ...',
                     cmd[:100])
        output = do_run('sh %s' % script.name_quoted)

    output = output.splitlines()
    if single_line:
      if not output:
        return ''
      elif len(output) == 1:
        return output[0]
      else:
        msg = 'one line of output was expected, but got: %s'
        raise device_errors.CommandFailedError(msg % output, str(self))
    else:
      return output