Home | History | Annotate | Download | only in battor
      1 # Copyright 2016 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dependency_manager
      6 import logging
      7 import mock
      8 import subprocess
      9 import unittest
     10 
     11 from battor import battor_error
     12 from battor import battor_wrapper
     13 from devil.utils import battor_device_mapping
     14 from devil.utils import find_usb_devices
     15 
     16 import serial
     17 from serial.tools import list_ports
     18 
     19 
     20 class DependencyManagerMock(object):
     21   def __init__(self, _):
     22     self._fetch_return = 'path'
     23     self._version_return = 'cbaa843'
     24 
     25   def FetchPath(self, _, *unused):
     26     del unused
     27     return self._fetch_return
     28 
     29   def FetchPathWithVersion(self, _, *unused):
     30     del unused
     31     return self._fetch_return, self._version_return
     32 
     33 class PopenMock(object):
     34   def __init__(self, *unused):
     35     pass
     36 
     37   def poll(self):
     38     pass
     39 
     40   def kill(self):
     41     pass
     42 
     43 
     44 class IsBattOrConnectedTest(unittest.TestCase):
     45   def setUp(self):
     46     # Windows monkey patches.
     47     self._serial_tools_return = []
     48     self._comports = serial.tools.list_ports.comports
     49     serial.tools.list_ports.comports = lambda: self._serial_tools_return
     50 
     51     # Linux/Android monkey patches.
     52     self._generate_serial_map_return = {}
     53     self._generate_serial_map = battor_device_mapping.GenerateSerialMap
     54     battor_device_mapping.GenerateSerialMap = (
     55         lambda: self._generate_serial_map_return)
     56 
     57     self._read_serial_map_file_return = {}
     58     self._read_serial_map_file = battor_device_mapping.ReadSerialMapFile
     59     battor_device_mapping.ReadSerialMapFile = (
     60         lambda f: self._read_serial_map_file_return)
     61 
     62     self._get_bus_number_to_device_tree_map = (
     63         find_usb_devices.GetBusNumberToDeviceTreeMap)
     64     find_usb_devices.GetBusNumberToDeviceTreeMap = lambda fast=None: {}
     65 
     66     self._get_battor_list_return = []
     67     self._get_battor_list = battor_device_mapping.GetBattOrList
     68     battor_device_mapping.GetBattOrList = lambda x: self._get_battor_list_return
     69 
     70   def tearDown(self):
     71     serial.tools.list_ports.comports = self._comports
     72     battor_device_mapping.GenerateSerialMap = self._generate_serial_map
     73     battor_device_mapping.ReadSerialMapFile = self._read_serial_map_file
     74     find_usb_devices.GetBusNumberToDeviceTreeMap = (
     75         self._get_bus_number_to_device_tree_map)
     76     battor_device_mapping.GetBattOrList = self._get_battor_list
     77 
     78   def forceException(self):
     79     raise NotImplementedError
     80 
     81   def testAndroidWithBattOr(self):
     82     self._generate_serial_map_return = {'abc': '123'}
     83     self.assertTrue(battor_wrapper.IsBattOrConnected('android', 'abc'))
     84 
     85   def testAndroidWithoutMatchingBattOr(self):
     86     self._generate_serial_map_return = {'notabc': 'not123'}
     87     self.assertFalse(battor_wrapper.IsBattOrConnected('android', 'abc'))
     88 
     89   def testAndroidNoDevicePassed(self):
     90     with self.assertRaises(ValueError):
     91       battor_wrapper.IsBattOrConnected('android')
     92 
     93   def testAndroidWithMapAndFile(self):
     94     device_map = {'abc': '123'}
     95     battor_device_mapping.ReadSerialMapFile = self.forceException
     96     self.assertTrue(
     97         battor_wrapper.IsBattOrConnected('android', android_device='abc',
     98                                         android_device_map=device_map,
     99                                         android_device_file='file'))
    100 
    101   def testAndroidWithMap(self):
    102     self.assertTrue(
    103         battor_wrapper.IsBattOrConnected('android', android_device='abc',
    104                                         android_device_map={'abc', '123'}))
    105 
    106   def testAndroidWithFile(self):
    107     self._read_serial_map_file_return = {'abc': '123'}
    108     self.assertTrue(
    109       battor_wrapper.IsBattOrConnected('android', android_device='abc',
    110                                       android_device_file='file'))
    111 
    112   def testLinuxWithBattOr(self):
    113     self._get_battor_list_return = ['battor']
    114     self.assertTrue(battor_wrapper.IsBattOrConnected('linux'))
    115 
    116   def testLinuxWithoutBattOr(self):
    117     self._get_battor_list_return = []
    118     self.assertFalse(battor_wrapper.IsBattOrConnected('linux'))
    119 
    120   def testMacWithBattOr(self):
    121     self._serial_tools_return = [('/dev/tty.usbserial-MAA', 'BattOr v3.3', '')]
    122     self.assertTrue(battor_wrapper.IsBattOrConnected('mac'))
    123 
    124   def testMacWithoutBattOr(self):
    125     self._serial_tools_return = [('/dev/tty.usbserial-MAA', 'not_one', '')]
    126     self.assertFalse(battor_wrapper.IsBattOrConnected('mac'))
    127 
    128   def testWinWithBattOr(self):
    129     self._serial_tools_return = [('COM4', 'USB Serial Port', '')]
    130     self.assertTrue(battor_wrapper.IsBattOrConnected('win'))
    131 
    132   def testWinWithoutBattOr(self):
    133     self._get_battor_list_return = []
    134     self.assertFalse(battor_wrapper.IsBattOrConnected('win'))
    135 
    136 
    137 class BattOrWrapperTest(unittest.TestCase):
    138   def setUp(self):
    139     self._battor = None
    140     self._is_battor = True
    141     self._battor_list = ['battor1']
    142     self._should_pass = True
    143     self._fake_map = {'battor1': 'device1'}
    144     self._fake_return_code = None
    145     self._fake_battor_return = 'Done.\n'
    146 
    147     self._get_battor_path_from_phone_serial = (
    148         battor_device_mapping.GetBattOrPathFromPhoneSerial)
    149     self._get_bus_number_to_device_tree_map = (
    150         find_usb_devices.GetBusNumberToDeviceTreeMap)
    151     self._dependency_manager = dependency_manager.DependencyManager
    152     self._get_battor_list = battor_device_mapping.GetBattOrList
    153     self._is_battor = battor_device_mapping.IsBattOr
    154     self._generate_serial_map = battor_device_mapping.GenerateSerialMap
    155     self._serial_tools = serial.tools.list_ports.comports
    156 
    157     battor_device_mapping.GetBattOrPathFromPhoneSerial = (
    158         lambda x, serial_map_file=None, serial_map=None: x + '_battor')
    159     find_usb_devices.GetBusNumberToDeviceTreeMap = lambda fast=False: True
    160     dependency_manager.DependencyManager = DependencyManagerMock
    161     battor_device_mapping.GetBattOrList = lambda x: self._battor_list
    162     battor_device_mapping.IsBattOr = lambda x, y: self._is_battor
    163     battor_device_mapping.GenerateSerialMap = lambda: self._fake_map
    164     serial.tools.list_ports.comports = lambda: [('COM4', 'USB Serial Port', '')]
    165 
    166     self._subprocess_check_output_code = 0
    167     def subprocess_check_output_mock(*unused):
    168       if self._subprocess_check_output_code != 0:
    169         raise subprocess.CalledProcessError(None, None)
    170       return 0
    171     self._subprocess_check_output = subprocess.check_output
    172     subprocess.check_output = subprocess_check_output_mock
    173 
    174   def tearDown(self):
    175     battor_device_mapping.GetBattOrPathFromPhoneSerial = (
    176         self._get_battor_path_from_phone_serial)
    177     find_usb_devices.GetBusNumberToDeviceTreeMap = (
    178         self._get_bus_number_to_device_tree_map)
    179     dependency_manager.DependencyManager = self._dependency_manager
    180     battor_device_mapping.GetBattOrList = self._get_battor_list
    181     battor_device_mapping.IsBattOr = self._is_battor
    182     battor_device_mapping.GenerateSerialMap = self._generate_serial_map
    183     serial.tools.list_ports.comports = self._serial_tools
    184     subprocess.check_output = self._subprocess_check_output
    185 
    186   def _DefaultBattOrReplacements(self):
    187     battor_wrapper.DEFAULT_SHELL_CLOSE_TIMEOUT_S = .1
    188     self._battor._StartShellImpl = lambda *unused: PopenMock()
    189     self._battor.GetShellReturnCode = lambda *unused: self._fake_return_code
    190     self._battor._SendBattOrCommandImpl = lambda x: self._fake_battor_return
    191     self._battor._StopTracingImpl = lambda *unused: (self._fake_battor_return,
    192                                                      None)
    193 
    194   def testBadPlatform(self):
    195     with self.assertRaises(battor_error.BattOrError):
    196       self._battor = battor_wrapper.BattOrWrapper('unknown')
    197 
    198   def testInitAndroidWithBattOr(self):
    199     self._battor = battor_wrapper.BattOrWrapper('android', android_device='abc')
    200     self.assertEquals(self._battor._battor_path, 'abc_battor')
    201 
    202   def testInitAndroidWithoutBattOr(self):
    203     self._battor_list = []
    204     self._fake_map = {}
    205     battor_device_mapping.GetBattOrPathFromPhoneSerial = (
    206         self._get_battor_path_from_phone_serial)
    207     with self.assertRaises(battor_error.BattOrError):
    208       self._battor = battor_wrapper.BattOrWrapper('android',
    209                                                   android_device='abc')
    210 
    211   def testInitBattOrPathIsBattOr(self):
    212     battor_path = 'battor/path/here'
    213     self._battor = battor_wrapper.BattOrWrapper(
    214         'android', android_device='abc', battor_path=battor_path)
    215     self.assertEquals(self._battor._battor_path, battor_path)
    216 
    217   def testInitNonAndroidWithBattOr(self):
    218     self._battor = battor_wrapper.BattOrWrapper('win')
    219     self.assertEquals(self._battor._battor_path, 'COM4')
    220 
    221   def testInitNonAndroidWithMultipleBattOr(self):
    222     self._battor_list.append('battor2')
    223     with self.assertRaises(battor_error.BattOrError):
    224       self._battor = battor_wrapper.BattOrWrapper('linux')
    225 
    226   def testInitNonAndroidWithoutBattOr(self):
    227     self._battor_list = []
    228     serial.tools.list_ports.comports = lambda: [('COM4', 'None', '')]
    229     with self.assertRaises(battor_error.BattOrError):
    230       self._battor = battor_wrapper.BattOrWrapper('win')
    231 
    232   def testStartShellPass(self):
    233     self._battor = battor_wrapper.BattOrWrapper('win')
    234     self._DefaultBattOrReplacements()
    235     self._battor.StartShell()
    236     self.assertIsNotNone(self._battor._battor_shell)
    237 
    238   def testStartShellDoubleStart(self):
    239     self._battor = battor_wrapper.BattOrWrapper('win')
    240     self._DefaultBattOrReplacements()
    241     self._battor.StartShell()
    242     with self.assertRaises(AssertionError):
    243       self._battor.StartShell()
    244 
    245   def testStartShellFail(self):
    246     self._battor = battor_wrapper.BattOrWrapper('win')
    247     self._DefaultBattOrReplacements()
    248     self._battor.GetShellReturnCode = lambda *unused: 1
    249     with self.assertRaises(AssertionError):
    250       self._battor.StartShell()
    251 
    252   def testStartTracingPass(self):
    253     self._battor = battor_wrapper.BattOrWrapper('win')
    254     self._DefaultBattOrReplacements()
    255     self._battor.StartShell()
    256     self._battor.StartTracing()
    257     self.assertTrue(self._battor._tracing)
    258 
    259   def testStartTracingDoubleStart(self):
    260     self._battor = battor_wrapper.BattOrWrapper('win')
    261     self._DefaultBattOrReplacements()
    262     self._battor.StartShell()
    263     self._battor.StartTracing()
    264     with self.assertRaises(AssertionError):
    265       self._battor.StartTracing()
    266 
    267   def testStartTracingCommandFails(self):
    268     self._battor = battor_wrapper.BattOrWrapper('win')
    269     self._DefaultBattOrReplacements()
    270     self._battor._SendBattOrCommandImpl = lambda *unused: 'Fail.\n'
    271     self._battor.StartShell()
    272     with self.assertRaises(battor_error.BattOrError):
    273       self._battor.StartTracing()
    274 
    275   def testStopTracingPass(self):
    276     self._battor = battor_wrapper.BattOrWrapper('win')
    277     self._DefaultBattOrReplacements()
    278     self._battor.StartShell()
    279     self._battor.StartTracing()
    280     self._battor.GetShellReturnCode = lambda *unused: 0
    281     self._battor.StopTracing()
    282     self.assertFalse(self._battor._tracing)
    283 
    284   def testStopTracingNotRunning(self):
    285     self._battor = battor_wrapper.BattOrWrapper('win')
    286     self._DefaultBattOrReplacements()
    287     with self.assertRaises(AssertionError):
    288       self._battor.StopTracing()
    289 
    290   def testFlashFirmwarePass(self):
    291     self._battor = battor_wrapper.BattOrWrapper('linux')
    292     self._DefaultBattOrReplacements()
    293     self.assertTrue(self._battor.FlashFirmware('hex_path', 'config_path'))
    294 
    295   def testFlashFirmwareFail(self):
    296     self._battor = battor_wrapper.BattOrWrapper('linux')
    297     self._DefaultBattOrReplacements()
    298     self._subprocess_check_output_code = 1
    299     with self.assertRaises(battor_wrapper.BattOrFlashError):
    300       self._battor.FlashFirmware('hex_path', 'config_path')
    301 
    302   def testFlashFirmwareShellRunning(self):
    303     self._battor = battor_wrapper.BattOrWrapper('linux')
    304     self._DefaultBattOrReplacements()
    305     self._battor.StartShell()
    306     with self.assertRaises(AssertionError):
    307       self._battor.FlashFirmware('hex_path', 'config_path')
    308 
    309   def testGetFirmwareGitHashNotRunning(self):
    310     self._battor = battor_wrapper.BattOrWrapper('win')
    311     self._DefaultBattOrReplacements()
    312     with self.assertRaises(AssertionError):
    313       self._battor.GetFirmwareGitHash()
    314 
    315   def testGetFirmwareGitHashPass(self):
    316     self._battor = battor_wrapper.BattOrWrapper('win')
    317     self._DefaultBattOrReplacements()
    318     self._battor.StartShell()
    319     self._battor.GetFirmwareGitHash = lambda: 'cbaa843'
    320     self.assertTrue(isinstance(self._battor.GetFirmwareGitHash(), basestring))
    321 
    322   def testStopShellPass(self):
    323     self._battor = battor_wrapper.BattOrWrapper('win')
    324     self._DefaultBattOrReplacements()
    325     self._battor.StartShell()
    326     self._fake_return_code = 0
    327     self._battor.StopShell()
    328     self.assertIsNone(self._battor._battor_shell)
    329 
    330   @mock.patch('time.sleep', mock.Mock)
    331   def testStopShellTimeOutAndKill(self):
    332     self._battor = battor_wrapper.BattOrWrapper('win')
    333     self._DefaultBattOrReplacements()
    334     self._battor.StartShell()
    335     self._battor.StopShell()
    336     self.assertIsNone(self._battor._battor_shell)
    337 
    338   def testStopShellNotStarted(self):
    339     self._battor = battor_wrapper.BattOrWrapper('win')
    340     self._DefaultBattOrReplacements()
    341     with self.assertRaises(AssertionError):
    342       self._battor.StopShell()
    343 
    344   @mock.patch('time.sleep', mock.Mock)
    345   def testFlashBattOrSameGitHash(self):
    346     self._battor = battor_wrapper.BattOrWrapper('linux')
    347     self._DefaultBattOrReplacements()
    348     self._battor.StartShell()
    349     self._battor.GetFirmwareGitHash = lambda: 'cbaa843'
    350     dependency_manager.DependencyManager._version_return = 'cbaa843'
    351     self.assertFalse(self._battor._FlashBattOr())
    352 
    353   @mock.patch('time.sleep', mock.Mock)
    354   def testFlashBattOrDifferentGitHash(self):
    355     self._battor = battor_wrapper.BattOrWrapper('linux')
    356     self._DefaultBattOrReplacements()
    357     self._battor.StartShell()
    358     self._battor.GetFirmwareGitHash = lambda: 'bazz732'
    359     dependency_manager.DependencyManager._version_return = 'cbaa843'
    360     self.assertTrue(self._battor._FlashBattOr())
    361 
    362   def testCollectTraceDataNoStartTime(self):
    363     self._battor = battor_wrapper.BattOrWrapper('linux')
    364     self._DefaultBattOrReplacements()
    365     self._battor.StartShell()
    366     self._battor.StartTracing()
    367     self._battor.GetShellReturnCode = lambda *unused: 0
    368     self._battor.StopTracing()
    369     self._battor._start_tracing_time = None
    370     with self.assertRaises(battor_error.BattOrError):
    371       self._battor.CollectTraceData()
    372 
    373   def testCollectTraceDataNoStopTime(self):
    374     self._battor = battor_wrapper.BattOrWrapper('linux')
    375     self._DefaultBattOrReplacements()
    376     self._battor.StartShell()
    377     self._battor.StartTracing()
    378     self._battor.GetShellReturnCode = lambda *unused: 0
    379     self._battor.StopTracing()
    380     self._battor._stop_tracing_time = None
    381     with self.assertRaises(battor_error.BattOrError):
    382       self._battor.CollectTraceData()
    383 
    384 
    385 if __name__ == '__main__':
    386   logging.getLogger().setLevel(logging.DEBUG)
    387   unittest.main(verbosity=2)
    388