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