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.')
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')
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
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)
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)
def throw_battor_error(): raise battor_error.BattOrError('Forced Exception')
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')