Example #1
0
def GetBattOrPathFromPhoneSerial(serial, serial_map=None,
                                 serial_map_file=None):
  """Gets the TTY path (e.g. '/dev/ttyUSB0')  to communicate with the BattOr.

  (1) If serial_map is given, it is treated as a dictionary mapping
  phone serial numbers to BattOr serial numbers. This function will get the
  TTY path for the given BattOr serial number.

  (2) If serial_map_file is given, it is treated as the name of a
  phone-to-BattOr mapping file (generated with GenerateSerialMapFile)
  and this will be loaded and used as the dict to map port numbers to
  BattOr serial numbers.

  You can only give one of serial_map and serial_map_file.

  Args:
    serial: Serial number of phone connected on the same physical port that
    the BattOr is connected to.
    serial_map: Map of phone serial numbers to BattOr serial numbers, given
    as a dictionary.
    serial_map_file: Map of phone serial numbers to BattOr serial numbers,
    given as a file.
    hub_types: List of hub types to check for. Used only if serial_map_file
    is None.

  Returns:
    Device string used to communicate with presentation.device.

  Raises:
    ValueError: If serial number is not given.
    BattOrError: If BattOr not found or unexpected USB topology.
  """
  # If there's only one BattOr connected to the system, just use that one.
  # This allows for use on, e.g., a developer's workstation with no hubs.
  devtree = find_usb_devices.GetBusNumberToDeviceTreeMap()
  all_battors = GetBattOrList(devtree)
  if len(all_battors) == 1:
    return '/dev/' + all_battors[0]

  if not serial:
    raise battor_error.BattOrError(
        'Two or more BattOrs connected, no serial provided')

  if serial_map and serial_map_file:
    raise ValueError('Cannot specify both serial_map and serial_map_file')

  if serial_map_file:
    serial_map = ReadSerialMapFile(serial_map_file)

  tty_string = _PhoneToPathMap(serial, serial_map, devtree)

  if not tty_string:
    raise battor_error.BattOrError(
        'No presentation.device with given serial number detected.')

  if IsBattOr(tty_string, devtree):
    return '/dev/' + tty_string
  else:
    raise battor_error.BattOrError(
        'Device with given serial number is not a BattOr.')
Example #2
0
    def _GetBattOrPath(self,
                       target_platform,
                       android_device=None,
                       battor_path=None,
                       battor_map_file=None,
                       battor_map=None):
        """Determines most likely path to the correct BattOr."""
        if target_platform not in self._SUPPORTED_PLATFORMS:
            raise battor_error.BattOrError('%s is an unsupported platform.' %
                                           target_platform)
        if target_platform in ['win']:
            # Right now, the BattOr agent binary isn't able to automatically detect
            # the BattOr port on Windows. To get around this, we know that the BattOr
            # shows up with a name of 'USB Serial Port', so use the COM port that
            # corresponds to a presentation.device with that name.
            for (port, desc, _) in serial.tools.list_ports.comports():
                if 'USB Serial Port' in desc:
                    return port
            raise battor_error.BattOrError(
                'Could not find BattOr attached to machine.')
        if target_platform in ['mac']:
            for (port, desc, _) in serial.tools.list_ports.comports():
                if 'BattOr' in desc:
                    return port

        if target_platform in ['android', 'linux']:
            device_tree = find_usb_devices.GetBusNumberToDeviceTreeMap(
                fast=True)
            if battor_path:
                if not isinstance(battor_path, basestring):
                    raise battor_error.BattOrError(
                        'An invalid BattOr path was specified.')
                return battor_path

            if target_platform == 'android':
                if not android_device:
                    raise battor_error.BattOrError(
                        'Must specify presentation.device for Android platform.'
                    )
                if not battor_map_file and not battor_map:
                    # No map was passed, so must create one.
                    battor_map = battor_device_mapping.GenerateSerialMap()

                return battor_device_mapping.GetBattOrPathFromPhoneSerial(
                    str(android_device),
                    serial_map_file=battor_map_file,
                    serial_map=battor_map)

            # Not Android and no explicitly passed BattOr.
            battors = battor_device_mapping.GetBattOrList(device_tree)
            if len(battors) != 1:
                raise battor_error.BattOrError(
                    'For non-Android platforms, exactly one BattOr must be '
                    'attached unless address is explicitly given.')
            return '/dev/%s' % battors.pop()

        raise NotImplementedError(
            'BattOr Wrapper not implemented for given platform')
Example #3
0
  def CollectTraceData(self, timeout=None):
    """Collect trace data from battor.
    Args:
      timeout: timeout for waiting on the BattOr process to terminate in
        seconds.
    Returns: Trace data in form of a list.
    """
    if not self._stop_tracing_time or not self._start_tracing_time:
      raise battor_error.BattOrError(
          'No start or stop time detected when collecting BattOr trace.\n'
          'Start: %s \n Stop: %s' % (self._start_tracing_time,
                                     self._stop_tracing_time))

    # The BattOr shell terminates after returning the results.
    if timeout is None:
      timeout = self._stop_tracing_time - self._start_tracing_time
    py_utils.WaitFor(lambda: self.GetShellReturnCode() != None, timeout)

    # TODO(charliea): Once we understand why BattOrs are crashing, only do
    # this on failure.
    # http://crbug.com/699581
    logging.info('CollectTraceData serial log:')
    self._UploadSerialLogToCloudStorage()

    with open(self._trace_results_path) as results:
      self._trace_results = results.read()
    self._battor_shell = None
    self._serial_log_file = None
    return self._trace_results
Example #4
0
def _PhoneToPathMap(serial, serial_map, devtree):
  """Maps phone serial number to TTY path, assuming serial map is provided."""
  try:
    battor_serial = serial_map[serial]
  except KeyError:
    raise battor_error.BattOrError('Serial number not found in serial map.')
  for tree in devtree.values():
    for node in tree.AllNodes():
      if isinstance(node, find_usb_devices.USBDeviceNode):
        if node.serial == battor_serial:
          bus_device_to_tty = find_usb_devices.GetBusDeviceToTTYMap()
          bus_device = (node.bus_num, node.device_num)
          try:
            return bus_device_to_tty[bus_device]
          except KeyError:
            raise battor_error.BattOrError(
                'Device with given serial number not a BattOr '
                '(does not have TTY path)')
  def _SendBattOrCommand(self, cmd, check_return=True):
    status = self._SendBattOrCommandImpl(cmd)

    if check_return and not 'Done.' in status:
      self.KillBattOrShell()
      self._UploadSerialLogToCloudStorage()
      self._serial_log_file = None
      raise battor_error.BattOrError(
          'BattOr did not complete command \'%s\' correctly.\n'
          'Outputted: %s' % (cmd, status))
    return status
 def testStopTracingReturnsStopTracingBattOrError(self):
     self.controller._supported_agents_classes = [
         FakeTracingAgentStopRaisesBattOrError,
     ]
     self.assertFalse(self.controller.is_tracing_running)
     self.assertTrue(self.controller.StartTracing(self.config, 30))
     self.assertTrue(self.controller.is_tracing_running)
     _, errors = self.controller.StopTracing()
     self.assertEqual(errors, [battor_error.BattOrError('foo')])
     self.assertFalse(self.controller.is_tracing_running)
     self.assertEqual(self.controller._trace_log, None)
 def testStopTracingReturnsCollectAgentTraceDataBattOrError(self):
     self.controller._supported_agents_classes = [
         FakeTracingAgentCollectRaisesBattOrError,
     ]
     self.assertFalse(self.controller.is_tracing_running)
     self.assertTrue(self.controller.StartTracing(self.config, 30))
     self.assertTrue(self.controller.is_tracing_running)
     data, errors = self.controller.StopTracing()
     self.assertEqual(errors, [battor_error.BattOrError('foo')])
     self.assertEqual(self._getSyncCount(data), 1)
     self.assertFalse(self.controller.is_tracing_running)
     self.assertEqual(self.controller._trace_log, None)
Example #8
0
    def test_get_devices_with_no_battors(self, mock_usb_context,
                                         mock_generate_map):
        d1 = self.libusb_device
        d1.serial = 'serial1'
        d2 = copy.copy(self.libusb_device)
        d2.serial = 'serial2'
        self.usb_context = FakeUSBContext([d1, d2])
        mock_usb_context.return_value = self.usb_context
        mock_generate_map.side_effect = battor_error.BattOrError(
            'omg no battor')
        devices = usb_device.get_android_devices(None)

        self.assertEquals(devices[0].serial, 'serial1')
        self.assertEquals(devices[0].battor, None)
        self.assertEquals(devices[1].serial, 'serial2')
        self.assertEquals(devices[1].battor, None)
Example #9
0
 def throw_battor_error():
   raise battor_error.BattOrError('Forced Exception')
Example #10
0
def GenerateSerialMap(hub_types=None):
  """Generates a map of phone serial numbers to BattOr serial numbers.

  Generates a dict of:
  {<phone serial 1>: <battor serial 1>,
   <phone serial 2>: <battor serial 2>}
  indicating which phone serial numbers should be matched with
  which BattOr serial numbers. Mapping is based on the physical port numbers
  of the hubs that the BattOrs and phones are connected to.

  Args:
      hub_types: List of hub types to check for. If not specified, checks
      for all defined hub types. (see usb_hubs.py for details)
  """
  if hub_types:
    hub_types = [usb_hubs.GetHubType(x) for x in hub_types]
  else:
    hub_types = usb_hubs.ALL_HUBS

  devtree = find_usb_devices.GetBusNumberToDeviceTreeMap()

  # List of serial numbers in the system that represent BattOrs.
  battor_serials = list(GetBattOrSerialNumbers(devtree))

  # If there's only one BattOr in the system, then a serial number ma
  # is not necessary.
  if len(battor_serials) == 1:
    return {}

  # List of dictionaries, one for each hub, that maps the physical
  # port number to the serial number of that hub. For instance, in a 2
  # hub system, this could return [{1:'ab', 2:'cd'}, {1:'jkl', 2:'xyz'}]
  # where 'ab' and 'cd' are the phone serial numbers and 'jkl' and 'xyz'
  # are the BattOr serial numbers.
  port_to_serial = find_usb_devices.GetAllPhysicalPortToSerialMaps(
      hub_types, device_tree_map=devtree)

  class serials(object):
    def __init__(self):
      self.phone = None
      self.battor = None

  # Map of {physical port number: [phone serial #, BattOr serial #]. This
  # map is populated by executing the code below. For instance, in the above
  # example, after the code below is executed, port_to_devices would equal
  # {1: ['ab', 'jkl'], 2: ['cd', 'xyz']}
  port_to_devices = collections.defaultdict(serials)
  for hub in port_to_serial:
    for (port, serial) in hub.iteritems():
      if serial in battor_serials:
        if port_to_devices[port].battor is not None:
          raise battor_error.BattOrError('Multiple BattOrs on same port number')
        else:
          port_to_devices[port].battor = serial
      else:
        if port_to_devices[port].phone is not None:
          raise battor_error.BattOrError('Multiple phones on same port number')
        else:
          port_to_devices[port].phone = serial

  # Turn the port_to_devices map into a map of the form
  # {phone serial number: BattOr serial number}.
  result = {}
  for pair in port_to_devices.values():
    if pair.phone is None:
      continue
    if pair.battor is None:
      raise battor_error.BattOrError(
          'Phone detected with no corresponding BattOr')
    result[pair.phone] = pair.battor
  return result
 def FlushAgentTracing(self, config, timeout, trace_data_builder):
     raise battor_error.BattOrError('foo')
 def CollectAgentTraceData(self, trace_data_builder, timeout=None):
     raise battor_error.BattOrError('foo')
 def StopAgentTracing(self):
     raise battor_error.BattOrError('foo')
 def RecordClockSyncMarker(self, sync_id, callback):
     raise battor_error.BattOrError('foo')
 def StartAgentTracing(self, config, timeout):
     raise battor_error.BattOrError('foo')