Exemplo n.º 1
0
    def _KillHostLocked(self):
        """Kills the forwarder process running on the host.

    Note that the global lock must be acquired before calling this method.
    """
        logger.info('Killing host_forwarder.')
        try:
            kill_cmd = [self._host_forwarder_path, '--kill-server']
            (exit_code, output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                kill_cmd, Forwarder._TIMEOUT)
            if exit_code != 0:
                logger.warning('Forwarder unable to shut down:\n%s', output)
                kill_cmd = ['pkill', '-9', 'host_forwarder']
                (exit_code,
                 output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                     kill_cmd, Forwarder._TIMEOUT)
                if exit_code == -9:
                    # pkill can exit with -9, seemingly in cases where the process it's
                    # asked to kill dies sometime during pkill running. In this case,
                    # re-running should result in pkill succeeding.
                    logging.warning(
                        'pkilling host forwarder returned -9, retrying through strace. '
                        'Output: %s', output)
                    exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                        ['strace', '-f', '-s', '256'] + kill_cmd,
                        Forwarder._TIMEOUT)
                if exit_code in (0, 1):
                    # pkill exits with a 0 if it was able to signal at least one process.
                    # pkill exits with a 1 if it wasn't able to signal a process because
                    # no matching process existed. We're ok with either.
                    return

                _, ps_output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                    ['ps', 'aux'], Forwarder._TIMEOUT)
                host_forwarder_lines = [
                    line for line in ps_output.splitlines()
                    if 'host_forwarder' in line
                ]
                if host_forwarder_lines:
                    logger.error('Remaining host_forwarder processes:\n  %s',
                                 '\n  '.join(host_forwarder_lines))
                else:
                    logger.error('No remaining host_forwarder processes?')
                _DumpHostLog()
                error_msg = textwrap.dedent("""\
            `{kill_cmd}` failed to kill host_forwarder.
              exit_code: {exit_code}
              output:
            {output}
            """)
                raise HostForwarderError(
                    error_msg.format(kill_cmd=' '.join(kill_cmd),
                                     exit_code=str(exit_code),
                                     output='\n'.join(
                                         '    %s' % l
                                         for l in output.splitlines())))
        except cmd_helper.TimeoutError as e:
            raise HostForwarderError('`%s` timed out:\n%s' %
                                     (' '.join(kill_cmd), e.output))
    def _RunSingleTest(self, test):
        self._test_instance.WriteBuildBotJson(self._output_dir)

        timeout = self._tests[test].get('timeout', self._timeout)
        cmd = self._CreateCmd(test)
        cwd = os.path.abspath(host_paths.DIR_SOURCE_ROOT)

        self._LogTest(test, cmd, timeout)

        try:
            start_time = time.time()

            with contextlib_ext.Optional(trace_event.trace(test),
                                         self._env.trace_output):
                exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                    cmd, timeout, cwd=cwd, shell=True)
            end_time = time.time()
            chart_json_output = self._test_instance.ReadChartjsonOutput(
                self._output_dir)
            if exit_code == 0:
                result_type = base_test_result.ResultType.PASS
            else:
                result_type = base_test_result.ResultType.FAIL
        except cmd_helper.TimeoutError as e:
            end_time = time.time()
            exit_code = -1
            output = e.output
            chart_json_output = ''
            result_type = base_test_result.ResultType.TIMEOUT
        return self._ProcessTestResult(test, cmd, start_time, end_time,
                                       exit_code, output, chart_json_output,
                                       result_type)
Exemplo n.º 3
0
    def _RunAdbCmd(cls,
                   args,
                   timeout=None,
                   retries=None,
                   device_serial=None,
                   check_error=True,
                   cpu_affinity=None):
        # pylint: disable=no-member
        try:
            status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                cls._BuildAdbCmd(args,
                                 device_serial,
                                 cpu_affinity=cpu_affinity),
                timeout_retry.CurrentTimeoutThreadGroup().GetRemainingTime())
        except OSError as e:
            if e.errno in (errno.ENOENT, errno.ENOEXEC):
                raise device_errors.NoAdbError(msg=str(e))
            else:
                raise

        if status != 0:
            raise device_errors.AdbCommandFailedError(args, output, status,
                                                      device_serial)
        # This catches some errors, including when the device drops offline;
        # unfortunately adb is very inconsistent with error reporting so many
        # command failures present differently.
        if check_error and output.startswith('error:'):
            raise device_errors.AdbCommandFailedError(args, output)
        return output
Exemplo n.º 4
0
    def _UnmapDevicePortLocked(device_port, device):
        """Internal method used by UnmapDevicePort().

    Note that the global lock must be acquired before calling this method.
    """
        instance = Forwarder._GetInstanceLocked(None)
        serial = str(device)
        serial_with_port = (serial, device_port)
        if serial_with_port not in instance._device_to_host_port_map:
            logger.error('Trying to unmap non-forwarded port %d', device_port)
            return

        host_port = instance._device_to_host_port_map[serial_with_port]
        del instance._device_to_host_port_map[serial_with_port]
        del instance._host_to_device_port_map[host_port]

        unmap_cmd = [
            instance._host_forwarder_path,
            '--adb=%s' % adb_wrapper.AdbWrapper.GetAdbPath(),
            '--serial-id=%s' % serial, '--unmap',
            str(device_port)
        ]
        try:
            (exit_code, output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                unmap_cmd, Forwarder._TIMEOUT)
        except cmd_helper.TimeoutError as e:
            raise HostForwarderError('`%s` timed out:\n%s' %
                                     (' '.join(unmap_cmd), e.output))
        if exit_code != 0:
            logger.error(
                '`%s` exited with %d:\n%s', ' '.join(unmap_cmd), exit_code,
                '\n'.join(output) if isinstance(output, list) else output)
Exemplo n.º 5
0
  def _RunAdbCmd(cls, args, timeout=None, retries=None, device_serial=None,
                 check_error=True, cpu_affinity=None,
                 ensure_logs_on_timeout=True):
    timeout = timeout_retry.CurrentTimeoutThreadGroup().GetRemainingTime()
    if ensure_logs_on_timeout and timeout:
      timeout = 0.95 * timeout
    try:
      status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
          cls._BuildAdbCmd(args, device_serial, cpu_affinity=cpu_affinity),
          timeout, env=cls._ADB_ENV)
    except OSError as e:
      if e.errno in (errno.ENOENT, errno.ENOEXEC):
        raise device_errors.NoAdbError(msg=str(e))
      else:
        raise

    # Best effort to catch errors from adb; unfortunately adb is very
    # inconsistent with error reporting so many command failures present
    # differently.
    if status != 0 or (check_error and output.startswith('error:')):
      not_found_m = _DEVICE_NOT_FOUND_RE.match(output)
      device_waiting_m = _WAITING_FOR_DEVICE_RE.match(output)
      if (device_waiting_m is not None
          or (not_found_m is not None and
              not_found_m.group('serial') == device_serial)):
        raise device_errors.DeviceUnreachableError(device_serial)
      else:
        raise device_errors.AdbCommandFailedError(
            args, output, status, device_serial)

    return output
Exemplo n.º 6
0
    def _RunAdbCmd(cls,
                   args,
                   timeout=None,
                   retries=None,
                   device_serial=None,
                   check_error=True,
                   cpu_affinity=None):
        # pylint: disable=no-member
        try:
            status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                cls._BuildAdbCmd(args,
                                 device_serial,
                                 cpu_affinity=cpu_affinity),
                timeout_retry.CurrentTimeoutThreadGroup().GetRemainingTime())
        except OSError as e:
            if e.errno in (errno.ENOENT, errno.ENOEXEC):
                raise device_errors.NoAdbError(msg=str(e))
            else:
                raise

        # Best effort to catch errors from adb; unfortunately adb is very
        # inconsistent with error reporting so many command failures present
        # differently.
        if status != 0 or (check_error and output.startswith('error:')):
            m = _DEVICE_NOT_FOUND_RE.match(output)
            if m is not None and m.group('serial') == device_serial:
                raise device_errors.DeviceUnreachableError(device_serial)
            else:
                raise device_errors.AdbCommandFailedError(
                    args, output, status, device_serial)

        return output
Exemplo n.º 7
0
    def _KillHostLocked(self):
        """Kills the forwarder process running on the host.

    Note that the global lock must be acquired before calling this method.
    """
        logger.info('Killing host_forwarder.')
        try:
            kill_cmd = [self._host_forwarder_path, '--kill-server']
            (exit_code, output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                kill_cmd, Forwarder._TIMEOUT)
            if exit_code != 0:
                logger.warning('Forwarder unable to shut down:\n%s', output)
                kill_cmd = ['pkill', '-9', 'host_forwarder']
                (exit_code,
                 output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                     kill_cmd, Forwarder._TIMEOUT)
                if exit_code != 0:
                    _, ps_output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                        ['ps', 'aux'], Forwarder._TIMEOUT)
                    host_forwarder_lines = [
                        line for line in ps_output.splitlines()
                        if 'host_forwarder' in line
                    ]
                    if host_forwarder_lines:
                        logger.error(
                            'Remaining host_forwarder processes:\n  %s',
                            '\n  '.join(host_forwarder_lines))
                    else:
                        logger.error('No remaining host_forwarder processes?')
                    _DumpHostLog()
                    error_msg = textwrap.dedent("""\
              `{kill_cmd}` failed to kill host_forwarder.
                exit_code: {exit_code}
              """)
                    raise HostForwarderError(
                        error_msg.format(kill_cmd=' '.join(kill_cmd),
                                         exit_code=str(exit_code)))
        except cmd_helper.TimeoutError as e:
            raise HostForwarderError('`%s` timed out:\n%s' %
                                     (' '.join(kill_cmd), e.output))
Exemplo n.º 8
0
    def _KillHostLocked(self):
        """Kills the forwarder process running on the host.

    Note that the global lock must be acquired before calling this method.
    """
        logger.info('Killing host_forwarder.')
        try:
            kill_cmd = [self._host_forwarder_path, '--kill-server']
            (exit_code, _o) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                kill_cmd, Forwarder._TIMEOUT)
            if exit_code != 0:
                kill_cmd = ['pkill', '-9', 'host_forwarder']
                (exit_code,
                 output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                     kill_cmd, Forwarder._TIMEOUT)
                if exit_code != 0:
                    raise HostForwarderError('%s exited with %d:\n%s' %
                                             (self._host_forwarder_path,
                                              exit_code, '\n'.join(output)))
        except cmd_helper.TimeoutError as e:
            raise HostForwarderError('`%s` timed out:\n%s' %
                                     (' '.join(kill_cmd), e.output))
Exemplo n.º 9
0
    def _RunAdbCmd(cls,
                   args,
                   timeout=None,
                   retries=None,
                   device_serial=None,
                   check_error=True,
                   cpu_affinity=None,
                   additional_env=None):
        if timeout:
            remaining = timeout_retry.CurrentTimeoutThreadGroup(
            ).GetRemainingTime()
            if remaining:
                # Use a slightly smaller timeout than remaining time to ensure that we
                # have time to collect output from the command.
                timeout = 0.95 * remaining
            else:
                timeout = None
        env = cls._ADB_ENV.copy()
        if additional_env:
            env.update(additional_env)
        try:
            adb_cmd = cls._BuildAdbCmd(args,
                                       device_serial,
                                       cpu_affinity=cpu_affinity)
            status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                adb_cmd, timeout, env=env)
        except OSError as e:
            if e.errno in (errno.ENOENT, errno.ENOEXEC):
                raise device_errors.NoAdbError(msg=str(e))
            else:
                raise
        except cmd_helper.TimeoutError:
            logger.error('Timeout on adb command: %r', adb_cmd)
            raise

        # Best effort to catch errors from adb; unfortunately adb is very
        # inconsistent with error reporting so many command failures present
        # differently.
        if status != 0 or (check_error and output.startswith('error:')):
            not_found_m = _DEVICE_NOT_FOUND_RE.search(output)
            device_waiting_m = _WAITING_FOR_DEVICE_RE.match(output)
            if (device_waiting_m is not None
                    or (not_found_m is not None
                        and not_found_m.group('serial') == device_serial)):
                raise device_errors.DeviceUnreachableError(device_serial)
            else:
                raise device_errors.AdbCommandFailedError(
                    args, output, status, device_serial)

        return output
Exemplo n.º 10
0
def lsusb():
    """Call lsusb and return the parsed output."""
    _, lsusb_list_output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
        ['lsusb'], timeout=10)
    devices = []
    for line in lsusb_list_output.splitlines():
        m = _LSUSB_BUS_DEVICE_RE.match(line)
        if m:
            bus_num = m.group(1)
            dev_num = m.group(2)
            try:
                devices.append(_lsusbv_on_device(bus_num, dev_num))
            except cmd_helper.TimeoutError:
                # Will be blacklisted if it is in expected device file, but times out.
                logger.info('lsusb -v %s:%s timed out.', bus_num, dev_num)
    return devices
Exemplo n.º 11
0
    def UnmapAllDevicePorts(device):
        """Unmaps all the previously forwarded ports for the provided device.

    Args:
      device: A DeviceUtils instance.
      port_pairs: A list of tuples (device_port, host_port) to unmap.
    """
        with _FileLock(Forwarder._LOCK_PATH):
            instance = Forwarder._GetInstanceLocked(None)
            unmap_all_cmd = [
                instance._host_forwarder_path,
                '--adb=%s' % adb_wrapper.AdbWrapper.GetAdbPath(),
                '--serial-id=%s' % device.serial, '--unmap-all'
            ]
            try:
                exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                    unmap_all_cmd, Forwarder._TIMEOUT)
            except cmd_helper.TimeoutError as e:
                raise HostForwarderError('`%s` timed out:\n%s' %
                                         (' '.join(unmap_all_cmd), e.output))
            if exit_code != 0:
                error_msg = [
                    '`%s` exited with %d' %
                    (' '.join(unmap_all_cmd), exit_code)
                ]
                if isinstance(output, list):
                    error_msg += output
                else:
                    error_msg += [output]
                raise HostForwarderError('\n'.join(error_msg))

            # Clean out any entries from the device & host map.
            device_map = instance._device_to_host_port_map
            host_map = instance._host_to_device_port_map
            for device_serial_and_port, host_port in device_map.items():
                device_serial = device_serial_and_port[0]
                if device_serial == device.serial:
                    del device_map[device_serial_and_port]
                    del host_map[host_port]

            # Kill the device forwarder.
            tool = base_tool.BaseTool()
            instance._KillDeviceLocked(device, tool)
Exemplo n.º 12
0
def _lsusbv_on_device(bus_id, dev_id):
    """Calls lsusb -v on device."""
    _, raw_output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
        ['lsusb', '-v', '-s', '%s:%s' % (bus_id, dev_id)], timeout=10)

    device = {'bus': bus_id, 'device': dev_id}
    depth_stack = [device]

    # This builds a nested dict -- a tree, basically -- that corresponds
    # to the lsusb output. It looks first for a line containing
    #
    #   "Bus <bus number> Device <device number>: ..."
    #
    # and uses that to create the root node. It then parses all remaining
    # lines as a tree, with the indentation level determining the
    # depth of the new node.
    #
    # This expects two kinds of lines:
    #   - "groups", which take the form
    #       "<Group name>:"
    #     and typically have children, and
    #   - "entries", which take the form
    #       "<entry name>   <entry value>  <possible entry description>"
    #     and typically do not have children (but can).
    #
    # This maintains a stack containing all current ancestor nodes in
    # order to add new nodes to the proper place in the tree.
    # The stack is added to when a new node is parsed. Nodes are removed
    # from the stack when they are either at the same indentation level as
    # or a deeper indentation level than the current line.
    #
    # e.g. the following lsusb output:
    #
    # Bus 123 Device 456: School bus
    # Device Descriptor:
    #   bDeviceClass 5 Actual School Bus
    #   Configuration Descriptor:
    #     bLength 20 Rows
    #
    # would produce the following dict:
    #
    # {
    #   'bus': 123,
    #   'device': 456,
    #   'desc': 'School bus',
    #   'Device Descriptor': {
    #     'bDeviceClass': {
    #       '_value': '5',
    #       '_desc': 'Actual School Bus',
    #     },
    #     'Configuration Descriptor': {
    #       'bLength': {
    #         '_value': '20',
    #         '_desc': 'Rows',
    #       },
    #     },
    #   }
    # }
    for line in raw_output.splitlines():
        # Ignore blank lines.
        if not line:
            continue
        # Filter out error mesage about opening device.
        if _COULDNT_OPEN_ERROR_RE.match(line):
            continue
        # Find start of device information.
        m = _LSUSB_BUS_DEVICE_RE.match(line)
        if m:
            if m.group(1) != bus_id:
                logger.warning('Expected bus_id value: %r, seen %r', bus_id,
                               m.group(1))
            if m.group(2) != dev_id:
                logger.warning('Expected dev_id value: %r, seen %r', dev_id,
                               m.group(2))
            device['desc'] = m.group(3)
            continue

        # Skip any lines that aren't indented, as they're not part of the
        # device descriptor.
        indent_match = _INDENTATION_RE.match(line)
        if not indent_match:
            continue

        # Determine the indentation depth.
        depth = 1 + len(indent_match.group(1)) / 2
        if depth > len(depth_stack):
            logger.error('lsusb parsing error: unexpected indentation: "%s"',
                         line)
            continue

        # Pop everything off the depth stack that isn't a parent of
        # this element.
        while depth < len(depth_stack):
            depth_stack.pop()

        cur = depth_stack[-1]

        m = _LSUSB_GROUP_RE.match(line)
        if m:
            new_group = {}
            cur[m.group(1)] = new_group
            depth_stack.append(new_group)
            continue

        m = _LSUSB_ENTRY_RE.match(line)
        if m:
            new_entry = {
                '_value': m.group(2),
                '_desc': m.group(3),
            }
            cur[m.group(1)] = new_entry
            depth_stack.append(new_entry)
            continue

        logger.error('lsusb parsing error: unrecognized line: "%s"', line)

    return device
Exemplo n.º 13
0
def _lsusbv_on_device(bus_id, dev_id):
  """Calls lsusb -v on device."""
  _, raw_output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
      ['lsusb', '-v', '-s', '%s:%s' % (bus_id, dev_id)], timeout=10)

  device = {'bus': bus_id, 'device': dev_id}
  depth_stack = [device]

  # TODO(jbudorick): Add documentation for parsing.
  for line in raw_output.splitlines():
    # Ignore blank lines.
    if not line:
      continue
    # Filter out error mesage about opening device.
    if _COULDNT_OPEN_ERROR_RE.match(line):
      continue
    # Find start of device information.
    m = _LSUSB_BUS_DEVICE_RE.match(line)
    if m:
      if m.group(1) != bus_id:
        logging.warning(
            'Expected bus_id value: %r, seen %r', bus_id, m.group(1))
      if m.group(2) != dev_id:
        logging.warning(
            'Expected dev_id value: %r, seen %r', dev_id, m.group(2))
      continue

    indent_match = _INDENTATION_RE.match(line)
    if not indent_match:
      continue

    depth = 1 + len(indent_match.group(1)) / 2
    if depth > len(depth_stack):
      logging.error(
          'lsusb parsing error: unexpected indentation: "%s"', line)
      continue

    while depth < len(depth_stack):
      depth_stack.pop()

    cur = depth_stack[-1]

    m = _LSUSB_GROUP_RE.match(line)
    if m:
      new_group = {}
      cur[m.group(1)] = new_group
      depth_stack.append(new_group)
      continue

    m = _LSUSB_ENTRY_RE.match(line)
    if m:
      new_entry = {
        '_value': m.group(2),
        '_desc': m.group(3),
      }
      cur[m.group(1)] = new_entry
      depth_stack.append(new_entry)
      continue

    logging.error('lsusb parsing error: unrecognized line: "%s"', line)

  return device
Exemplo n.º 14
0
    def _LaunchPerfTest(self, test_name):
        """Runs a perf test.

    Args:
      test_name: the name of the test to be executed.

    Returns:
      A tuple containing (Output, base_test_result.ResultType)
    """
        if not self._CheckDeviceAffinity(test_name):
            return '', base_test_result.ResultType.PASS

        try:
            logging.warning('Unmapping device ports')
            forwarder.Forwarder.UnmapAllDevicePorts(self.device)
            self.device.RestartAdbd()
        except Exception as e:  # pylint: disable=broad-except
            logging.error('Exception when tearing down device %s', e)

        test_config = self._tests['steps'][test_name]
        cmd = ('%s --device %s' % (test_config['cmd'], self.device_serial))

        if (self._options.collect_chartjson_data
                or test_config.get('archive_output_dir')):
            self._output_dir = tempfile.mkdtemp()
            self._WriteBuildBotJson()
            cmd = cmd + ' --output-dir=%s' % self._output_dir

        logging.info(
            'temperature: %s (0.1 C)',
            str(self._device_battery.GetBatteryInfo().get('temperature')))
        if self._options.max_battery_temp:
            self._device_battery.LetBatteryCoolToTemperature(
                self._options.max_battery_temp)

        logging.info('Charge level: %s%%',
                     str(self._device_battery.GetBatteryInfo().get('level')))
        if self._options.min_battery_level:
            self._device_battery.ChargeDeviceToLevel(
                self._options.min_battery_level)

        logging.info('%s : %s', test_name, cmd)
        start_time = time.time()

        timeout = test_config.get('timeout', 3600)
        if self._options.no_timeout:
            timeout = None
        logging.info('Timeout for %s test: %s', test_name, timeout)
        full_cmd = cmd
        if self._options.dry_run:
            full_cmd = 'echo %s' % cmd

        logfile = sys.stdout
        archive_bytes = None
        if self._options.single_step:
            # Just print a heart-beat so that the outer buildbot scripts won't timeout
            # without response.
            logfile = _HeartBeatLogger()
        cwd = os.path.abspath(constants.DIR_SOURCE_ROOT)
        if full_cmd.startswith('src/'):
            cwd = os.path.abspath(
                os.path.join(constants.DIR_SOURCE_ROOT, os.pardir))
        try:
            exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                full_cmd, timeout, cwd=cwd, shell=True, logfile=logfile)
            json_output = self._ReadChartjsonOutput()
            if test_config.get('archive_output_dir'):
                archive_bytes = self._ArchiveOutputDir()
        except cmd_helper.TimeoutError as e:
            exit_code = -1
            output = e.output
            json_output = ''
        finally:
            self._CleanupOutputDirectory()
            if self._options.single_step:
                logfile.stop()
        end_time = time.time()
        if exit_code is None:
            exit_code = -1
        logging.info('%s : exit_code=%d in %d secs at %s', test_name,
                     exit_code, end_time - start_time, self.device_serial)

        if exit_code == 0:
            result_type = base_test_result.ResultType.PASS
        else:
            result_type = base_test_result.ResultType.FAIL
            # Since perf tests use device affinity, give the device a chance to
            # recover if it is offline after a failure. Otherwise, the master sharder
            # will remove it from the pool and future tests on this device will fail.
            try:
                self.device.WaitUntilFullyBooted(timeout=120)
            except device_errors.CommandTimeoutError as e:
                logging.error('Device failed to return after %s: %s',
                              test_name, e)

        actual_exit_code = exit_code
        if test_name in self._flaky_tests:
            # The exit_code is used at the second stage when printing the
            # test output. If the test is flaky, force to "0" to get that step green
            # whilst still gathering data to the perf dashboards.
            # The result_type is used by the test_dispatcher to retry the test.
            exit_code = 0

        persisted_result = {
            'name': test_name,
            'output': [output],
            'chartjson': json_output,
            'archive_bytes': archive_bytes,
            'exit_code': exit_code,
            'actual_exit_code': actual_exit_code,
            'result_type': result_type,
            'start_time': start_time,
            'end_time': end_time,
            'total_time': end_time - start_time,
            'device': self.device_serial,
            'cmd': cmd,
        }
        self._SaveResult(persisted_result)

        return (output, result_type)
Exemplo n.º 15
0
    with _FileLock(Forwarder._LOCK_PATH):
      instance = Forwarder._GetInstanceLocked(tool)
      instance._InitDeviceLocked(presentation.device, tool)

      device_serial = str(presentation.device)
      map_arg_lists = [
          ['--adb=' + adb_wrapper.AdbWrapper.GetAdbPath(),
           '--serial-id=' + device_serial,
           '--map', str(device_port), str(host_port)]
          for device_port, host_port in port_pairs]
      logger.info('Forwarding using commands: %s', map_arg_lists)

      for map_arg_list in map_arg_lists:
        try:
          map_cmd = [instance._host_forwarder_path] + map_arg_list
          (exit_code, output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
              map_cmd, Forwarder._TIMEOUT)
        except cmd_helper.TimeoutError as e:
          raise HostForwarderError(
              '`%s` timed out:\n%s' % (' '.join(map_cmd), e.output))
        except OSError as e:
          if e.errno == 2:
            raise HostForwarderError(
                'Unable to start host forwarder. '
                'Make sure you have built host_forwarder.')
          else: raise
        if exit_code != 0:
          try:
            instance._KillDeviceLocked(presentation.device, tool)
          except device_errors.CommandFailedError:
            # We don't want the failure to kill the presentation.device forwarder to
            # supersede the original failure to map.
Exemplo n.º 16
0
    def Map(port_pairs, device, tool=None):
        """Runs the forwarder.

    Args:
      port_pairs: A list of tuples (device_port, host_port) to forward. Note
                 that you can specify 0 as a device_port, in which case a
                 port will by dynamically assigned on the device. You can
                 get the number of the assigned port using the
                 DevicePortForHostPort method.
      device: A DeviceUtils instance.
      tool: Tool class to use to get wrapper, if necessary, for executing the
            forwarder (see valgrind_tools.py).

    Raises:
      Exception on failure to forward the port.
    """
        if not tool:
            tool = base_tool.BaseTool()
        with _FileLock(Forwarder._LOCK_PATH):
            instance = Forwarder._GetInstanceLocked(tool)
            instance._InitDeviceLocked(device, tool)

            device_serial = str(device)
            map_arg_lists = [[
                '--adb=' + adb_wrapper.AdbWrapper.GetAdbPath(),
                '--serial-id=' + device_serial, '--map',
                str(device_port),
                str(host_port)
            ] for device_port, host_port in port_pairs]
            logger.info('Forwarding using commands: %s', map_arg_lists)

            for map_arg_list in map_arg_lists:
                try:
                    map_cmd = [instance._host_forwarder_path] + map_arg_list
                    (exit_code,
                     output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
                         map_cmd, Forwarder._TIMEOUT)
                except cmd_helper.TimeoutError as e:
                    raise HostForwarderError('`%s` timed out:\n%s' %
                                             (' '.join(map_cmd), e.output))
                except OSError as e:
                    if e.errno == 2:
                        raise HostForwarderError(
                            'Unable to start host forwarder. '
                            'Make sure you have built host_forwarder.')
                    else:
                        raise
                if exit_code != 0:
                    try:
                        instance._KillDeviceLocked(device, tool)
                    except (device_errors.CommandFailedError,
                            device_errors.DeviceUnreachableError):
                        # We don't want the failure to kill the device forwarder to
                        # supersede the original failure to map.
                        logger.warning(
                            'Failed to kill the device forwarder after map failure: %s',
                            str(e))
                    _LogMapFailureDiagnostics(device)
                    formatted_output = ('\n'.join(output) if isinstance(
                        output, list) else output)
                    raise HostForwarderError(
                        '`%s` exited with %d:\n%s' %
                        (' '.join(map_cmd), exit_code, formatted_output))
                tokens = output.split(':')
                if len(tokens) != 2:
                    raise HostForwarderError(
                        'Unexpected host forwarder output "%s", '
                        'expected "device_port:host_port"' % output)
                device_port = int(tokens[0])
                host_port = int(tokens[1])
                serial_with_port = (device_serial, device_port)
                instance._device_to_host_port_map[serial_with_port] = host_port
                instance._host_to_device_port_map[host_port] = serial_with_port
                logger.info('Forwarding device port: %d to host port: %d.',
                            device_port, host_port)