1#!/usr/bin/env python 2# Copyright 2014 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6""" 7Unit tests for the contents of battery_utils.py 8""" 9 10# pylint: disable=protected-access,unused-argument 11 12import logging 13import unittest 14 15from devil import devil_env 16from devil.android import battery_utils 17from devil.android import device_errors 18from devil.android import device_utils 19from devil.android import device_utils_test 20from devil.utils import mock_calls 21 22with devil_env.SysPath(devil_env.PYMOCK_PATH): 23 import mock # pylint: disable=import-error 24 25_DUMPSYS_OUTPUT = [ 26 '9,0,i,uid,1000,test_package1', 27 '9,0,i,uid,1001,test_package2', 28 '9,1000,l,pwi,uid,1', 29 '9,1001,l,pwi,uid,2', 30 '9,0,l,pws,1728,2000,190,207', 31] 32 33 34class BatteryUtilsTest(mock_calls.TestCase): 35 36 _NEXUS_5 = { 37 'name': 'Nexus 5', 38 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT', 39 'enable_command': ( 40 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && ' 41 'echo 1 > /sys/class/power_supply/usb/online'), 42 'disable_command': ( 43 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && ' 44 'chmod 644 /sys/class/power_supply/usb/online && ' 45 'echo 0 > /sys/class/power_supply/usb/online'), 46 'charge_counter': None, 47 'voltage': None, 48 'current': None, 49 } 50 51 _NEXUS_6 = { 52 'name': 'Nexus 6', 53 'witness_file': None, 54 'enable_command': None, 55 'disable_command': None, 56 'charge_counter': ( 57 '/sys/class/power_supply/max170xx_battery/charge_counter_ext'), 58 'voltage': '/sys/class/power_supply/max170xx_battery/voltage_now', 59 'current': '/sys/class/power_supply/max170xx_battery/current_now', 60 } 61 62 _NEXUS_10 = { 63 'name': 'Nexus 10', 64 'witness_file': None, 65 'enable_command': None, 66 'disable_command': None, 67 'charge_counter': ( 68 '/sys/class/power_supply/ds2784-fuelgauge/charge_counter_ext'), 69 'voltage': '/sys/class/power_supply/ds2784-fuelgauge/voltage_now', 70 'current': '/sys/class/power_supply/ds2784-fuelgauge/current_now', 71 } 72 73 def ShellError(self, output=None, status=1): 74 def action(cmd, *args, **kwargs): 75 raise device_errors.AdbShellCommandFailedError( 76 cmd, output, status, str(self.device)) 77 if output is None: 78 output = 'Permission denied\n' 79 return action 80 81 def setUp(self): 82 self.adb = device_utils_test._AdbWrapperMock('0123456789abcdef') 83 self.device = device_utils.DeviceUtils( 84 self.adb, default_timeout=10, default_retries=0) 85 self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial']) 86 self.battery = battery_utils.BatteryUtils( 87 self.device, default_timeout=10, default_retries=0) 88 89 90class BatteryUtilsInitTest(unittest.TestCase): 91 92 def testInitWithDeviceUtil(self): 93 serial = '0fedcba987654321' 94 d = device_utils.DeviceUtils(serial) 95 b = battery_utils.BatteryUtils(d) 96 self.assertEqual(d, b._device) 97 98 def testInitWithMissing_fails(self): 99 with self.assertRaises(TypeError): 100 battery_utils.BatteryUtils(None) 101 with self.assertRaises(TypeError): 102 battery_utils.BatteryUtils('') 103 104 105class BatteryUtilsSetChargingTest(BatteryUtilsTest): 106 107 @mock.patch('time.sleep', mock.Mock()) 108 def testHardwareSetCharging_enabled(self): 109 self.battery._cache['profile'] = self._NEXUS_5 110 with self.assertCalls( 111 (self.call.device.RunShellCommand( 112 mock.ANY, check_return=True, as_root=True, large_output=True), []), 113 (self.call.battery.GetCharging(), False), 114 (self.call.battery.GetCharging(), True)): 115 self.battery._HardwareSetCharging(True) 116 117 def testHardwareSetCharging_alreadyEnabled(self): 118 self.battery._cache['profile'] = self._NEXUS_5 119 with self.assertCalls( 120 (self.call.device.RunShellCommand( 121 mock.ANY, check_return=True, as_root=True, large_output=True), []), 122 (self.call.battery.GetCharging(), True)): 123 self.battery._HardwareSetCharging(True) 124 125 @mock.patch('time.sleep', mock.Mock()) 126 def testHardwareSetCharging_disabled(self): 127 self.battery._cache['profile'] = self._NEXUS_5 128 with self.assertCalls( 129 (self.call.device.RunShellCommand( 130 mock.ANY, check_return=True, as_root=True, large_output=True), []), 131 (self.call.battery.GetCharging(), True), 132 (self.call.battery.GetCharging(), False)): 133 self.battery._HardwareSetCharging(False) 134 135 136class BatteryUtilsSetBatteryMeasurementTest(BatteryUtilsTest): 137 138 @mock.patch('time.sleep', mock.Mock()) 139 def testBatteryMeasurementWifi(self): 140 with self.patch_call(self.call.device.build_version_sdk, 141 return_value=22): 142 with self.assertCalls( 143 (self.call.battery._ClearPowerData(), True), 144 (self.call.device.RunShellCommand( 145 ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []), 146 (self.call.device.RunShellCommand( 147 ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), 148 []), 149 (self.call.battery.GetCharging(), False), 150 (self.call.device.RunShellCommand( 151 ['dumpsys', 'battery', 'reset'], check_return=True), []), 152 (self.call.battery.GetCharging(), False), 153 (self.call.device.RunShellCommand( 154 ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']), 155 (self.call.battery.GetCharging(), False), 156 (self.call.device.RunShellCommand( 157 ['dumpsys', 'battery'], check_return=True), [])): 158 with self.battery.BatteryMeasurement(): 159 pass 160 161 @mock.patch('time.sleep', mock.Mock()) 162 def testBatteryMeasurementUsb(self): 163 with self.patch_call(self.call.device.build_version_sdk, 164 return_value=22): 165 with self.assertCalls( 166 (self.call.battery._ClearPowerData(), True), 167 (self.call.device.RunShellCommand( 168 ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []), 169 (self.call.device.RunShellCommand( 170 ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), 171 []), 172 (self.call.battery.GetCharging(), False), 173 (self.call.device.RunShellCommand( 174 ['dumpsys', 'battery', 'reset'], check_return=True), []), 175 (self.call.battery.GetCharging(), False), 176 (self.call.device.RunShellCommand( 177 ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']), 178 (self.call.battery.GetCharging(), True)): 179 with self.battery.BatteryMeasurement(): 180 pass 181 182 183class BatteryUtilsGetPowerData(BatteryUtilsTest): 184 185 def testGetPowerData(self): 186 with self.assertCalls( 187 (self.call.device.RunShellCommand( 188 ['dumpsys', 'batterystats', '-c'], 189 check_return=True, large_output=True), 190 _DUMPSYS_OUTPUT)): 191 data = self.battery.GetPowerData() 192 check = { 193 'system_total': 2000.0, 194 'per_package': { 195 'test_package1': {'uid': '1000', 'data': [1.0]}, 196 'test_package2': {'uid': '1001', 'data': [2.0]} 197 } 198 } 199 self.assertEqual(data, check) 200 201 def testGetPowerData_packageCollisionSame(self): 202 self.battery._cache['uids'] = {'test_package1': '1000'} 203 with self.assertCall( 204 self.call.device.RunShellCommand( 205 ['dumpsys', 'batterystats', '-c'], 206 check_return=True, large_output=True), 207 _DUMPSYS_OUTPUT): 208 data = self.battery.GetPowerData() 209 check = { 210 'system_total': 2000.0, 211 'per_package': { 212 'test_package1': {'uid': '1000', 'data': [1.0]}, 213 'test_package2': {'uid': '1001', 'data': [2.0]} 214 } 215 } 216 self.assertEqual(data, check) 217 218 def testGetPowerData_packageCollisionDifferent(self): 219 self.battery._cache['uids'] = {'test_package1': '1'} 220 with self.assertCall( 221 self.call.device.RunShellCommand( 222 ['dumpsys', 'batterystats', '-c'], 223 check_return=True, large_output=True), 224 _DUMPSYS_OUTPUT): 225 with self.assertRaises(device_errors.CommandFailedError): 226 self.battery.GetPowerData() 227 228 def testGetPowerData_cacheCleared(self): 229 with self.assertCalls( 230 (self.call.device.RunShellCommand( 231 ['dumpsys', 'batterystats', '-c'], 232 check_return=True, large_output=True), 233 _DUMPSYS_OUTPUT)): 234 self.battery._cache.clear() 235 data = self.battery.GetPowerData() 236 check = { 237 'system_total': 2000.0, 238 'per_package': { 239 'test_package1': {'uid': '1000', 'data': [1.0]}, 240 'test_package2': {'uid': '1001', 'data': [2.0]} 241 } 242 } 243 self.assertEqual(data, check) 244 245 246class BatteryUtilsChargeDevice(BatteryUtilsTest): 247 248 @mock.patch('time.sleep', mock.Mock()) 249 def testChargeDeviceToLevel_pass(self): 250 with self.assertCalls( 251 (self.call.battery.SetCharging(True)), 252 (self.call.battery.GetBatteryInfo(), {'level': '50'}), 253 (self.call.battery.GetBatteryInfo(), {'level': '100'})): 254 self.battery.ChargeDeviceToLevel(95) 255 256 @mock.patch('time.sleep', mock.Mock()) 257 def testChargeDeviceToLevel_failureSame(self): 258 with self.assertCalls( 259 (self.call.battery.SetCharging(True)), 260 (self.call.battery.GetBatteryInfo(), {'level': '50'}), 261 (self.call.battery.GetBatteryInfo(), {'level': '50'}), 262 263 (self.call.battery.GetBatteryInfo(), {'level': '50'})): 264 with self.assertRaises(device_errors.DeviceChargingError): 265 old_max = battery_utils._MAX_CHARGE_ERROR 266 try: 267 battery_utils._MAX_CHARGE_ERROR = 2 268 self.battery.ChargeDeviceToLevel(95) 269 finally: 270 battery_utils._MAX_CHARGE_ERROR = old_max 271 272 @mock.patch('time.sleep', mock.Mock()) 273 def testChargeDeviceToLevel_failureDischarge(self): 274 with self.assertCalls( 275 (self.call.battery.SetCharging(True)), 276 (self.call.battery.GetBatteryInfo(), {'level': '50'}), 277 (self.call.battery.GetBatteryInfo(), {'level': '49'}), 278 (self.call.battery.GetBatteryInfo(), {'level': '48'})): 279 with self.assertRaises(device_errors.DeviceChargingError): 280 old_max = battery_utils._MAX_CHARGE_ERROR 281 try: 282 battery_utils._MAX_CHARGE_ERROR = 2 283 self.battery.ChargeDeviceToLevel(95) 284 finally: 285 battery_utils._MAX_CHARGE_ERROR = old_max 286 287 288class BatteryUtilsDischargeDevice(BatteryUtilsTest): 289 290 @mock.patch('time.sleep', mock.Mock()) 291 def testDischargeDevice_exact(self): 292 with self.assertCalls( 293 (self.call.battery.GetBatteryInfo(), {'level': '100'}), 294 (self.call.battery._HardwareSetCharging(False)), 295 (self.call.battery._HardwareSetCharging(True)), 296 (self.call.battery.GetBatteryInfo(), {'level': '99'})): 297 self.battery._DischargeDevice(1) 298 299 @mock.patch('time.sleep', mock.Mock()) 300 def testDischargeDevice_over(self): 301 with self.assertCalls( 302 (self.call.battery.GetBatteryInfo(), {'level': '100'}), 303 (self.call.battery._HardwareSetCharging(False)), 304 (self.call.battery._HardwareSetCharging(True)), 305 (self.call.battery.GetBatteryInfo(), {'level': '50'})): 306 self.battery._DischargeDevice(1) 307 308 @mock.patch('time.sleep', mock.Mock()) 309 def testDischargeDevice_takeslong(self): 310 with self.assertCalls( 311 (self.call.battery.GetBatteryInfo(), {'level': '100'}), 312 (self.call.battery._HardwareSetCharging(False)), 313 (self.call.battery._HardwareSetCharging(True)), 314 (self.call.battery.GetBatteryInfo(), {'level': '100'}), 315 (self.call.battery._HardwareSetCharging(False)), 316 (self.call.battery._HardwareSetCharging(True)), 317 (self.call.battery.GetBatteryInfo(), {'level': '99'}), 318 (self.call.battery._HardwareSetCharging(False)), 319 (self.call.battery._HardwareSetCharging(True)), 320 (self.call.battery.GetBatteryInfo(), {'level': '98'}), 321 (self.call.battery._HardwareSetCharging(False)), 322 (self.call.battery._HardwareSetCharging(True)), 323 (self.call.battery.GetBatteryInfo(), {'level': '97'})): 324 self.battery._DischargeDevice(3) 325 326 @mock.patch('time.sleep', mock.Mock()) 327 def testDischargeDevice_dischargeTooClose(self): 328 with self.assertCalls( 329 (self.call.battery.GetBatteryInfo(), {'level': '100'})): 330 self.battery._DischargeDevice(99) 331 332 @mock.patch('time.sleep', mock.Mock()) 333 def testDischargeDevice_percentageOutOfBounds(self): 334 with self.assertCalls( 335 (self.call.battery.GetBatteryInfo(), {'level': '100'})): 336 with self.assertRaises(ValueError): 337 self.battery._DischargeDevice(100) 338 with self.assertCalls( 339 (self.call.battery.GetBatteryInfo(), {'level': '100'})): 340 with self.assertRaises(ValueError): 341 self.battery._DischargeDevice(0) 342 343 344class BatteryUtilsGetBatteryInfoTest(BatteryUtilsTest): 345 346 def testGetBatteryInfo_normal(self): 347 with self.assertCalls( 348 (self.call.device.RunShellCommand( 349 ['dumpsys', 'battery'], check_return=True), 350 [ 351 'Current Battery Service state:', 352 ' AC powered: false', 353 ' USB powered: true', 354 ' level: 100', 355 ' temperature: 321', 356 ])): 357 self.assertEquals( 358 { 359 'AC powered': 'false', 360 'USB powered': 'true', 361 'level': '100', 362 'temperature': '321', 363 }, 364 self.battery.GetBatteryInfo()) 365 366 def testGetBatteryInfo_nothing(self): 367 with self.assertCalls( 368 (self.call.device.RunShellCommand( 369 ['dumpsys', 'battery'], check_return=True), [])): 370 self.assertEquals({}, self.battery.GetBatteryInfo()) 371 372 373class BatteryUtilsGetChargingTest(BatteryUtilsTest): 374 375 def testGetCharging_usb(self): 376 with self.assertCall( 377 self.call.battery.GetBatteryInfo(), {'USB powered': 'true'}): 378 self.assertTrue(self.battery.GetCharging()) 379 380 def testGetCharging_usbFalse(self): 381 with self.assertCall( 382 self.call.battery.GetBatteryInfo(), {'USB powered': 'false'}): 383 self.assertFalse(self.battery.GetCharging()) 384 385 def testGetCharging_ac(self): 386 with self.assertCall( 387 self.call.battery.GetBatteryInfo(), {'AC powered': 'true'}): 388 self.assertTrue(self.battery.GetCharging()) 389 390 def testGetCharging_wireless(self): 391 with self.assertCall( 392 self.call.battery.GetBatteryInfo(), {'Wireless powered': 'true'}): 393 self.assertTrue(self.battery.GetCharging()) 394 395 def testGetCharging_unknown(self): 396 with self.assertCall( 397 self.call.battery.GetBatteryInfo(), {'level': '42'}): 398 self.assertFalse(self.battery.GetCharging()) 399 400 401class BatteryUtilsGetNetworkDataTest(BatteryUtilsTest): 402 403 def testGetNetworkData_noDataUsage(self): 404 with self.assertCalls( 405 (self.call.device.RunShellCommand( 406 ['dumpsys', 'batterystats', '-c'], 407 check_return=True, large_output=True), 408 _DUMPSYS_OUTPUT), 409 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 410 self.ShellError()), 411 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 412 self.ShellError())): 413 self.assertEquals(self.battery.GetNetworkData('test_package1'), (0, 0)) 414 415 def testGetNetworkData_badPackage(self): 416 with self.assertCall( 417 self.call.device.RunShellCommand( 418 ['dumpsys', 'batterystats', '-c'], 419 check_return=True, large_output=True), 420 _DUMPSYS_OUTPUT): 421 self.assertEqual(self.battery.GetNetworkData('asdf'), None) 422 423 def testGetNetworkData_packageNotCached(self): 424 with self.assertCalls( 425 (self.call.device.RunShellCommand( 426 ['dumpsys', 'batterystats', '-c'], 427 check_return=True, large_output=True), 428 _DUMPSYS_OUTPUT), 429 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1), 430 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)): 431 self.assertEqual(self.battery.GetNetworkData('test_package1'), (1, 2)) 432 433 def testGetNetworkData_packageCached(self): 434 self.battery._cache['uids'] = {'test_package1': '1000'} 435 with self.assertCalls( 436 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1), 437 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)): 438 self.assertEqual(self.battery.GetNetworkData('test_package1'), (1, 2)) 439 440 def testGetNetworkData_clearedCache(self): 441 with self.assertCalls( 442 (self.call.device.RunShellCommand( 443 ['dumpsys', 'batterystats', '-c'], 444 check_return=True, large_output=True), 445 _DUMPSYS_OUTPUT), 446 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1), 447 (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)): 448 self.battery._cache.clear() 449 self.assertEqual(self.battery.GetNetworkData('test_package1'), (1, 2)) 450 451 452class BatteryUtilsLetBatteryCoolToTemperatureTest(BatteryUtilsTest): 453 454 @mock.patch('time.sleep', mock.Mock()) 455 def testLetBatteryCoolToTemperature_startUnder(self): 456 self.battery._cache['profile'] = self._NEXUS_6 457 with self.assertCalls( 458 (self.call.battery.EnableBatteryUpdates(), []), 459 (self.call.battery.GetBatteryInfo(), {'temperature': '500'})): 460 self.battery.LetBatteryCoolToTemperature(600) 461 462 @mock.patch('time.sleep', mock.Mock()) 463 def testLetBatteryCoolToTemperature_startOver(self): 464 self.battery._cache['profile'] = self._NEXUS_6 465 with self.assertCalls( 466 (self.call.battery.EnableBatteryUpdates(), []), 467 (self.call.battery.GetBatteryInfo(), {'temperature': '500'}), 468 (self.call.battery.GetBatteryInfo(), {'temperature': '400'})): 469 self.battery.LetBatteryCoolToTemperature(400) 470 471 @mock.patch('time.sleep', mock.Mock()) 472 def testLetBatteryCoolToTemperature_nexus5Hot(self): 473 self.battery._cache['profile'] = self._NEXUS_5 474 with self.assertCalls( 475 (self.call.battery.EnableBatteryUpdates(), []), 476 (self.call.battery.GetBatteryInfo(), {'temperature': '500'}), 477 (self.call.battery._DischargeDevice(1), []), 478 (self.call.battery.GetBatteryInfo(), {'temperature': '400'})): 479 self.battery.LetBatteryCoolToTemperature(400) 480 481 @mock.patch('time.sleep', mock.Mock()) 482 def testLetBatteryCoolToTemperature_nexus5Cool(self): 483 self.battery._cache['profile'] = self._NEXUS_5 484 with self.assertCalls( 485 (self.call.battery.EnableBatteryUpdates(), []), 486 (self.call.battery.GetBatteryInfo(), {'temperature': '400'})): 487 self.battery.LetBatteryCoolToTemperature(400) 488 489 490class BatteryUtilsSupportsFuelGaugeTest(BatteryUtilsTest): 491 492 def testSupportsFuelGauge_false(self): 493 self.battery._cache['profile'] = self._NEXUS_5 494 self.assertFalse(self.battery.SupportsFuelGauge()) 495 496 def testSupportsFuelGauge_trueMax(self): 497 self.battery._cache['profile'] = self._NEXUS_6 498 # TODO(rnephew): Change this to assertTrue when we have support for 499 # disabling hardware charging on nexus 6. 500 self.assertFalse(self.battery.SupportsFuelGauge()) 501 502 def testSupportsFuelGauge_trueDS(self): 503 self.battery._cache['profile'] = self._NEXUS_10 504 # TODO(rnephew): Change this to assertTrue when we have support for 505 # disabling hardware charging on nexus 10. 506 self.assertFalse(self.battery.SupportsFuelGauge()) 507 508 509class BatteryUtilsGetFuelGaugeChargeCounterTest(BatteryUtilsTest): 510 511 def testGetFuelGaugeChargeCounter_noFuelGauge(self): 512 self.battery._cache['profile'] = self._NEXUS_5 513 with self.assertRaises(device_errors.CommandFailedError): 514 self.battery.GetFuelGaugeChargeCounter() 515 516 def testGetFuelGaugeChargeCounter_fuelGaugePresent(self): 517 self.battery._cache['profile'] = self._NEXUS_6 518 with self.assertCalls( 519 (self.call.battery.SupportsFuelGauge(), True), 520 (self.call.device.ReadFile(mock.ANY), '123')): 521 self.assertEqual(self.battery.GetFuelGaugeChargeCounter(), 123) 522 523 524class BatteryUtilsSetCharging(BatteryUtilsTest): 525 526 @mock.patch('time.sleep', mock.Mock()) 527 def testSetCharging_softwareSetTrue(self): 528 self.battery._cache['profile'] = self._NEXUS_6 529 with self.assertCalls( 530 (self.call.battery.GetCharging(), False), 531 (self.call.device.RunShellCommand( 532 ['dumpsys', 'battery', 'reset'], check_return=True), []), 533 (self.call.battery.GetCharging(), False), 534 (self.call.device.RunShellCommand( 535 ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']), 536 (self.call.battery.GetCharging(), True)): 537 self.battery.SetCharging(True) 538 539 @mock.patch('time.sleep', mock.Mock()) 540 def testSetCharging_softwareSetFalse(self): 541 self.battery._cache['profile'] = self._NEXUS_6 542 with self.assertCalls( 543 (self.call.battery.GetCharging(), True), 544 (self.call.battery._ClearPowerData(), True), 545 (self.call.device.RunShellCommand( 546 ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []), 547 (self.call.device.RunShellCommand( 548 ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []), 549 (self.call.battery.GetCharging(), False)): 550 self.battery.SetCharging(False) 551 552 @mock.patch('time.sleep', mock.Mock()) 553 def testSetCharging_hardwareSetTrue(self): 554 self.battery._cache['profile'] = self._NEXUS_5 555 with self.assertCalls( 556 (self.call.battery.GetCharging(), False), 557 (self.call.battery._HardwareSetCharging(True))): 558 self.battery.SetCharging(True) 559 560 @mock.patch('time.sleep', mock.Mock()) 561 def testSetCharging_hardwareSetFalse(self): 562 self.battery._cache['profile'] = self._NEXUS_5 563 with self.assertCalls( 564 (self.call.battery.GetCharging(), True), 565 (self.call.battery._ClearPowerData(), True), 566 (self.call.battery._HardwareSetCharging(False))): 567 self.battery.SetCharging(False) 568 569 def testSetCharging_expectedStateAlreadyTrue(self): 570 with self.assertCalls((self.call.battery.GetCharging(), True)): 571 self.battery.SetCharging(True) 572 573 def testSetCharging_expectedStateAlreadyFalse(self): 574 with self.assertCalls((self.call.battery.GetCharging(), False)): 575 self.battery.SetCharging(False) 576 577 578class BatteryUtilsPowerMeasurement(BatteryUtilsTest): 579 580 def testPowerMeasurement_hardware(self): 581 self.battery._cache['profile'] = self._NEXUS_5 582 with self.assertCalls( 583 (self.call.battery.GetCharging(), True), 584 (self.call.battery._ClearPowerData(), True), 585 (self.call.battery._HardwareSetCharging(False)), 586 (self.call.battery.GetCharging(), False), 587 (self.call.battery._HardwareSetCharging(True))): 588 with self.battery.PowerMeasurement(): 589 pass 590 591 @mock.patch('time.sleep', mock.Mock()) 592 def testPowerMeasurement_software(self): 593 self.battery._cache['profile'] = self._NEXUS_6 594 with self.assertCalls( 595 (self.call.battery.GetCharging(), True), 596 (self.call.battery._ClearPowerData(), True), 597 (self.call.device.RunShellCommand( 598 ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []), 599 (self.call.device.RunShellCommand( 600 ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []), 601 (self.call.battery.GetCharging(), False), 602 (self.call.battery.GetCharging(), False), 603 (self.call.device.RunShellCommand( 604 ['dumpsys', 'battery', 'reset'], check_return=True), []), 605 (self.call.battery.GetCharging(), False), 606 (self.call.device.RunShellCommand( 607 ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']), 608 (self.call.battery.GetCharging(), True)): 609 with self.battery.PowerMeasurement(): 610 pass 611 612 613class BatteryUtilsDiscoverDeviceProfile(BatteryUtilsTest): 614 615 def testDiscoverDeviceProfile_known(self): 616 with self.patch_call(self.call.device.product_model, 617 return_value='Nexus 4'): 618 self.battery._DiscoverDeviceProfile() 619 self.assertEqual(self.battery._cache['profile']['name'], "Nexus 4") 620 621 def testDiscoverDeviceProfile_unknown(self): 622 with self.patch_call(self.call.device.product_model, 623 return_value='Other'): 624 self.battery._DiscoverDeviceProfile() 625 self.assertEqual(self.battery._cache['profile']['name'], None) 626 627 628class BatteryUtilsClearPowerData(BatteryUtilsTest): 629 630 def testClearPowerData_preL(self): 631 with self.patch_call(self.call.device.build_version_sdk, 632 return_value=20): 633 self.assertFalse(self.battery._ClearPowerData()) 634 635 def testClearPowerData_clearedL(self): 636 with self.patch_call(self.call.device.build_version_sdk, 637 return_value=22): 638 with self.assertCalls( 639 (self.call.device.RunShellCommand( 640 ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True), 641 []), 642 (self.call.device.RunShellCommand( 643 ['dumpsys', 'battery', 'set', 'ac', '1'], check_return=True), []), 644 (self.call.device.RunShellCommand( 645 ['dumpsys', 'batterystats', '--reset'], check_return=True), []), 646 (self.call.device.RunShellCommand( 647 ['dumpsys', 'batterystats', '--charged', '-c'], 648 check_return=True, large_output=True), []), 649 (self.call.device.RunShellCommand( 650 ['dumpsys', 'battery', 'reset'], check_return=True), [])): 651 self.assertTrue(self.battery._ClearPowerData()) 652 653 def testClearPowerData_notClearedL(self): 654 with self.patch_call(self.call.device.build_version_sdk, 655 return_value=22): 656 with self.assertCalls( 657 (self.call.device.RunShellCommand( 658 ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True), 659 []), 660 (self.call.device.RunShellCommand( 661 ['dumpsys', 'battery', 'set', 'ac', '1'], check_return=True), []), 662 (self.call.device.RunShellCommand( 663 ['dumpsys', 'batterystats', '--reset'], check_return=True), []), 664 (self.call.device.RunShellCommand( 665 ['dumpsys', 'batterystats', '--charged', '-c'], 666 check_return=True, large_output=True), 667 ['9,1000,l,pwi,uid,0.0327']), 668 (self.call.device.RunShellCommand( 669 ['dumpsys', 'battery', 'reset'], check_return=True), [])): 670 with self.assertRaises(device_errors.CommandFailedError): 671 self.battery._ClearPowerData() 672 673 674if __name__ == '__main__': 675 logging.getLogger().setLevel(logging.DEBUG) 676 unittest.main(verbosity=2) 677