| #!/usr/bin/env python |
| # Copyright 2017 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. |
| |
| import os |
| import sys |
| import unittest |
| |
| if __name__ == '__main__': |
| sys.path.append( |
| os.path.abspath( |
| os.path.join(os.path.dirname(__file__), '..', '..', '..'))) |
| |
| from devil import devil_env |
| from devil.android import device_utils |
| from devil.android.sdk import adb_wrapper |
| from devil.android.sdk import version_codes |
| from devil.android.tools import system_app |
| |
| with devil_env.SysPath(devil_env.PYMOCK_PATH): |
| import mock |
| |
| _PACKAGE_NAME = 'com.android' |
| _PACKAGE_PATH = '/path/to/com.android.apk' |
| _PM_LIST_PACKAGES_COMMAND = [ |
| 'pm', 'list', 'packages', '-f', '-u', _PACKAGE_NAME |
| ] |
| _PM_LIST_PACKAGES_OUTPUT_WITH_PATH = [ |
| 'package:/path/to/other=' + _PACKAGE_NAME + '.other', |
| 'package:' + _PACKAGE_PATH + '=' + _PACKAGE_NAME |
| ] |
| _PM_LIST_PACKAGES_OUTPUT_WITHOUT_PATH = [ |
| 'package:/path/to/other=' + _PACKAGE_NAME + '.other' |
| ] |
| |
| |
| class SystemAppTest(unittest.TestCase): |
| def testDoubleEnableModification(self): |
| """Ensures that system app modification logic isn't repeated. |
| |
| If EnableSystemAppModification uses are nested, inner calls should |
| not need to perform any of the expensive modification logic. |
| """ |
| # pylint: disable=no-self-use,protected-access |
| mock_device = mock.Mock(spec=device_utils.DeviceUtils) |
| mock_device.adb = mock.Mock(spec=adb_wrapper.AdbWrapper) |
| type(mock_device).build_version_sdk = mock.PropertyMock( |
| return_value=version_codes.LOLLIPOP) |
| |
| system_props = {} |
| |
| def dict_setprop(prop_name, value): |
| system_props[prop_name] = value |
| |
| def dict_getprop(prop_name): |
| return system_props.get(prop_name, '') |
| |
| mock_device.SetProp.side_effect = dict_setprop |
| mock_device.GetProp.side_effect = dict_getprop |
| |
| with system_app.EnableSystemAppModification(mock_device): |
| mock_device.EnableRoot.assert_called_once_with() |
| mock_device.GetProp.assert_called_once_with( |
| system_app._ENABLE_MODIFICATION_PROP) |
| mock_device.SetProp.assert_called_once_with( |
| system_app._ENABLE_MODIFICATION_PROP, '1') |
| mock_device.reset_mock() |
| |
| with system_app.EnableSystemAppModification(mock_device): |
| self.assertFalse(mock_device.EnableRoot.mock_calls) # assert not called |
| mock_device.GetProp.assert_called_once_with( |
| system_app._ENABLE_MODIFICATION_PROP) |
| self.assertFalse(mock_device.SetProp.mock_calls) # assert not called |
| mock_device.reset_mock() |
| |
| mock_device.SetProp.assert_called_once_with( |
| system_app._ENABLE_MODIFICATION_PROP, '0') |
| |
| def test_GetApplicationPaths_found(self): |
| """Path found in output along with another package having similar name.""" |
| # pylint: disable=protected-access |
| mock_device = mock.Mock(spec=device_utils.DeviceUtils) |
| mock_device.RunShellCommand.configure_mock( |
| return_value=_PM_LIST_PACKAGES_OUTPUT_WITH_PATH) |
| |
| paths = system_app._GetApplicationPaths(mock_device, _PACKAGE_NAME) |
| |
| self.assertEquals([_PACKAGE_PATH], paths) |
| mock_device.RunShellCommand.assert_called_once_with( |
| _PM_LIST_PACKAGES_COMMAND, check_return=True) |
| |
| def test_GetApplicationPaths_notFound(self): |
| """Path not found in output, only another package with similar name.""" |
| # pylint: disable=protected-access |
| mock_device = mock.Mock(spec=device_utils.DeviceUtils) |
| mock_device.RunShellCommand.configure_mock( |
| return_value=_PM_LIST_PACKAGES_OUTPUT_WITHOUT_PATH) |
| |
| paths = system_app._GetApplicationPaths(mock_device, _PACKAGE_NAME) |
| |
| self.assertEquals([], paths) |
| mock_device.RunShellCommand.assert_called_once_with( |
| _PM_LIST_PACKAGES_COMMAND, check_return=True) |
| |
| def test_GetApplicationPaths_noPaths(self): |
| """Nothing containing text of package name found in output.""" |
| # pylint: disable=protected-access |
| mock_device = mock.Mock(spec=device_utils.DeviceUtils) |
| mock_device.RunShellCommand.configure_mock(return_value=[]) |
| |
| paths = system_app._GetApplicationPaths(mock_device, _PACKAGE_NAME) |
| |
| self.assertEquals([], paths) |
| mock_device.RunShellCommand.assert_called_once_with( |
| _PM_LIST_PACKAGES_COMMAND, check_return=True) |
| |
| def test_GetApplicationPaths_emptyName(self): |
| """Called with empty name, should not return any packages.""" |
| # pylint: disable=protected-access |
| mock_device = mock.Mock(spec=device_utils.DeviceUtils) |
| mock_device.RunShellCommand.configure_mock( |
| return_value=_PM_LIST_PACKAGES_OUTPUT_WITH_PATH) |
| |
| paths = system_app._GetApplicationPaths(mock_device, '') |
| |
| self.assertEquals([], paths) |
| mock_device.RunShellCommand.assert_called_once_with( |
| _PM_LIST_PACKAGES_COMMAND[:-1] + [''], check_return=True) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |