| Index: build/android/pylib/device/battery_utils_test.py
 | 
| diff --git a/build/android/pylib/device/battery_utils_test.py b/build/android/pylib/device/battery_utils_test.py
 | 
| new file mode 100755
 | 
| index 0000000000000000000000000000000000000000..15b4c3441c9351a67b5ef8d91459c3a2a7ed2e39
 | 
| --- /dev/null
 | 
| +++ b/build/android/pylib/device/battery_utils_test.py
 | 
| @@ -0,0 +1,316 @@
 | 
| +#!/usr/bin/env python
 | 
| +# Copyright 2014 The Chromium Authors. All rights reserved.
 | 
| +# Use of this source code is governed by a BSD-style license that can be
 | 
| +# found in the LICENSE file.
 | 
| +
 | 
| +"""
 | 
| +Unit tests for the contents of battery_utils.py
 | 
| +"""
 | 
| +
 | 
| +# pylint: disable=W0613
 | 
| +
 | 
| +import logging
 | 
| +import os
 | 
| +import sys
 | 
| +import unittest
 | 
| +
 | 
| +from pylib import android_commands
 | 
| +from pylib import constants
 | 
| +from pylib.device import battery_utils
 | 
| +from pylib.device import device_errors
 | 
| +from pylib.device import device_utils
 | 
| +from pylib.device import device_utils_test
 | 
| +from pylib.utils import mock_calls
 | 
| +
 | 
| +# RunCommand from third_party/android_testrunner/run_command.py is mocked
 | 
| +# below, so its path needs to be in sys.path.
 | 
| +sys.path.append(os.path.join(
 | 
| +    constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
 | 
| +
 | 
| +sys.path.append(os.path.join(
 | 
| +    constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
 | 
| +import mock # pylint: disable=F0401
 | 
| +
 | 
| +_DUMPSYS_OUTPUT = [
 | 
| +    '9,0,i,uid,1000,test_package1',
 | 
| +    '9,0,i,uid,1001,test_package2',
 | 
| +    '9,1000,l,pwi,uid,1',
 | 
| +    '9,1001,l,pwi,uid,2'
 | 
| +]
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsTest(mock_calls.TestCase):
 | 
| +
 | 
| +  def ShellError(self, output=None, status=1):
 | 
| +    def action(cmd, *args, **kwargs):
 | 
| +      raise device_errors.AdbShellCommandFailedError(
 | 
| +          cmd, output, status, str(self.device))
 | 
| +    if output is None:
 | 
| +      output = 'Permission denied\n'
 | 
| +    return action
 | 
| +
 | 
| +  def setUp(self):
 | 
| +    self.adb = device_utils_test._AdbWrapperMock('0123456789abcdef')
 | 
| +    self.device = device_utils.DeviceUtils(
 | 
| +        self.adb, default_timeout=10, default_retries=0)
 | 
| +    self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial'])
 | 
| +    self.battery = battery_utils.BatteryUtils(
 | 
| +        self.device, default_timeout=10, default_retries=0)
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsInitTest(unittest.TestCase):
 | 
| +
 | 
| +  def testInitWithDeviceUtil(self):
 | 
| +    serial = '0fedcba987654321'
 | 
| +    a = android_commands.AndroidCommands(device=serial)
 | 
| +    d = device_utils.DeviceUtils(a)
 | 
| +    b = battery_utils.BatteryUtils(d)
 | 
| +    self.assertEqual(d, b._device)
 | 
| +
 | 
| +  def testInitWithMissing_fails(self):
 | 
| +    with self.assertRaises(TypeError):
 | 
| +      battery_utils.BatteryUtils(None)
 | 
| +    with self.assertRaises(TypeError):
 | 
| +      battery_utils.BatteryUtils('')
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsSetChargingTest(BatteryUtilsTest):
 | 
| +
 | 
| +  @mock.patch('time.sleep', mock.Mock())
 | 
| +  def testSetCharging_enabled(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.FileExists(mock.ANY), True),
 | 
| +        (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), False),
 | 
| +        (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), True)):
 | 
| +      self.battery.SetCharging(True)
 | 
| +
 | 
| +  def testSetCharging_alreadyEnabled(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.FileExists(mock.ANY), True),
 | 
| +        (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), True)):
 | 
| +      self.battery.SetCharging(True)
 | 
| +
 | 
| +  @mock.patch('time.sleep', mock.Mock())
 | 
| +  def testSetCharging_disabled(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.FileExists(mock.ANY), True),
 | 
| +        (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), True),
 | 
| +        (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), False)):
 | 
| +      self.battery.SetCharging(False)
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsSetBatteryMeasurementTest(BatteryUtilsTest):
 | 
| +
 | 
| +  def testBatteryMeasurement(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            mock.ANY, retries=0, single_line=True,
 | 
| +            timeout=10, check_return=True), '22'),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery', 'reset'], check_return=True), []),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '--reset'], check_return=True), []),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '--charged', '--checkin'],
 | 
| +            check_return=True), []),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), False),
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery', 'reset'], check_return=True), []),
 | 
| +        (self.call.battery.GetCharging(), True)):
 | 
| +      with self.battery.BatteryMeasurement():
 | 
| +        pass
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsGetPowerData(BatteryUtilsTest):
 | 
| +
 | 
| +  def testGetPowerData(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT)):
 | 
| +      data = self.battery.GetPowerData()
 | 
| +      check = {
 | 
| +          'test_package1': {'uid': '1000', 'data': [1.0]},
 | 
| +          'test_package2': {'uid': '1001', 'data': [2.0]}
 | 
| +      }
 | 
| +      self.assertEqual(data, check)
 | 
| +
 | 
| +  def testGetPowerData_packageCollisionSame(self):
 | 
| +      self.battery._cache['uids'] = {'test_package1': '1000'}
 | 
| +      with self.assertCall(
 | 
| +        self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT):
 | 
| +        data = self.battery.GetPowerData()
 | 
| +        check = {
 | 
| +            'test_package1': {'uid': '1000', 'data': [1.0]},
 | 
| +            'test_package2': {'uid': '1001', 'data': [2.0]}
 | 
| +        }
 | 
| +        self.assertEqual(data, check)
 | 
| +
 | 
| +  def testGetPowerData_packageCollisionDifferent(self):
 | 
| +      self.battery._cache['uids'] = {'test_package1': '1'}
 | 
| +      with self.assertCall(
 | 
| +        self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT):
 | 
| +        with self.assertRaises(device_errors.CommandFailedError):
 | 
| +          self.battery.GetPowerData()
 | 
| +
 | 
| +  def testGetPowerData_cacheCleared(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT)):
 | 
| +      self.battery._cache.clear()
 | 
| +      data = self.battery.GetPowerData()
 | 
| +      check = {
 | 
| +          'test_package1': {'uid': '1000', 'data': [1.0]},
 | 
| +          'test_package2': {'uid': '1001', 'data': [2.0]}
 | 
| +      }
 | 
| +      self.assertEqual(data, check)
 | 
| +
 | 
| +  def testGetPackagePowerData(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT)):
 | 
| +      data = self.battery.GetPackagePowerData('test_package2')
 | 
| +      self.assertEqual(data, {'uid': '1001', 'data': [2.0]})
 | 
| +
 | 
| +  def testGetPackagePowerData_badPackage(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT)):
 | 
| +      data = self.battery.GetPackagePowerData('not_a_package')
 | 
| +      self.assertEqual(data, None)
 | 
| +
 | 
| +
 | 
| +class BatteryUtilsChargeDevice(BatteryUtilsTest):
 | 
| +
 | 
| +  @mock.patch('time.sleep', mock.Mock())
 | 
| +  def testChargeDeviceToLevel(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.battery.SetCharging(True)),
 | 
| +        (self.call.battery.GetBatteryInfo(), {'level': '50'}),
 | 
| +        (self.call.battery.GetBatteryInfo(), {'level': '100'})):
 | 
| +      self.battery.ChargeDeviceToLevel(95)
 | 
| +
 | 
| +
 | 
| +class DeviceUtilsGetBatteryInfoTest(BatteryUtilsTest):
 | 
| +
 | 
| +  def testGetBatteryInfo_normal(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery'], check_return=True),
 | 
| +        [
 | 
| +          'Current Battery Service state:',
 | 
| +          '  AC powered: false',
 | 
| +          '  USB powered: true',
 | 
| +          '  level: 100',
 | 
| +          '  temperature: 321',
 | 
| +        ]):
 | 
| +      self.assertEquals(
 | 
| +          {
 | 
| +            'AC powered': 'false',
 | 
| +            'USB powered': 'true',
 | 
| +            'level': '100',
 | 
| +            'temperature': '321',
 | 
| +          },
 | 
| +          self.battery.GetBatteryInfo())
 | 
| +
 | 
| +  def testGetBatteryInfo_nothing(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'battery'], check_return=True), []):
 | 
| +      self.assertEquals({}, self.battery.GetBatteryInfo())
 | 
| +
 | 
| +
 | 
| +class DeviceUtilsGetChargingTest(BatteryUtilsTest):
 | 
| +
 | 
| +  def testGetCharging_usb(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.battery.GetBatteryInfo(), {'USB powered': 'true'}):
 | 
| +      self.assertTrue(self.battery.GetCharging())
 | 
| +
 | 
| +  def testGetCharging_usbFalse(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.battery.GetBatteryInfo(), {'USB powered': 'false'}):
 | 
| +      self.assertFalse(self.battery.GetCharging())
 | 
| +
 | 
| +  def testGetCharging_ac(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.battery.GetBatteryInfo(), {'AC powered': 'true'}):
 | 
| +      self.assertTrue(self.battery.GetCharging())
 | 
| +
 | 
| +  def testGetCharging_wireless(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.battery.GetBatteryInfo(), {'Wireless powered': 'true'}):
 | 
| +      self.assertTrue(self.battery.GetCharging())
 | 
| +
 | 
| +  def testGetCharging_unknown(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.battery.GetBatteryInfo(), {'level': '42'}):
 | 
| +      self.assertFalse(self.battery.GetCharging())
 | 
| +
 | 
| +
 | 
| +class DeviceUtilsGetNetworkDataTest(BatteryUtilsTest):
 | 
| +
 | 
| +  def testGetNetworkData_noDataUsage(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'),
 | 
| +            self.ShellError()),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'),
 | 
| +            self.ShellError())):
 | 
| +      self.assertEquals(self.battery.GetNetworkData('test_package1'), (0, 0))
 | 
| +
 | 
| +  def testGetNetworkData_badPackage(self):
 | 
| +    with self.assertCall(
 | 
| +        self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT):
 | 
| +      self.assertEqual(self.battery.GetNetworkData('asdf'), None)
 | 
| +
 | 
| +  def testGetNetworkData_packageNotCached(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
 | 
| +      self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
 | 
| +
 | 
| +  def testGetNetworkData_packageCached(self):
 | 
| +    self.battery._cache['uids'] = {'test_package1': '1000'}
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
 | 
| +      self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
 | 
| +
 | 
| +  def testGetNetworkData_clearedCache(self):
 | 
| +    with self.assertCalls(
 | 
| +        (self.call.device.RunShellCommand(
 | 
| +            ['dumpsys', 'batterystats', '-c'], check_return=True),
 | 
| +            _DUMPSYS_OUTPUT),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
 | 
| +        (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
 | 
| +      self.battery._cache.clear()
 | 
| +      self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
 | 
| +
 | 
| +
 | 
| +if __name__ == '__main__':
 | 
| +  logging.getLogger().setLevel(logging.DEBUG)
 | 
| +  unittest.main(verbosity=2)
 | 
| 
 |