blob: 3f4ef597b6dedbee91e3d535d635142841775775 [file] [log] [blame]
#!/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 device_utils.py (mostly DeviceUtils).
"""
# pylint: disable=C0321
# pylint: disable=W0212
# pylint: disable=W0613
import collections
import datetime
import logging
import os
import re
import signal
import sys
import unittest
from pylib import android_commands
from pylib import cmd_helper
from pylib import constants
from pylib.device import adb_wrapper
from pylib.device import device_errors
from pylib.device import device_utils
from pylib.device import intent
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
class DeviceUtilsInitTest(unittest.TestCase):
def testInitWithStr(self):
serial_as_str = str('0123456789abcdef')
d = device_utils.DeviceUtils('0123456789abcdef')
self.assertEqual(serial_as_str, d.adb.GetDeviceSerial())
def testInitWithUnicode(self):
serial_as_unicode = unicode('fedcba9876543210')
d = device_utils.DeviceUtils(serial_as_unicode)
self.assertEqual(serial_as_unicode, d.adb.GetDeviceSerial())
def testInitWithAdbWrapper(self):
serial = '123456789abcdef0'
a = adb_wrapper.AdbWrapper(serial)
d = device_utils.DeviceUtils(a)
self.assertEqual(serial, d.adb.GetDeviceSerial())
def testInitWithAndroidCommands(self):
serial = '0fedcba987654321'
a = android_commands.AndroidCommands(device=serial)
d = device_utils.DeviceUtils(a)
self.assertEqual(serial, d.adb.GetDeviceSerial())
def testInitWithMissing_fails(self):
with self.assertRaises(ValueError):
device_utils.DeviceUtils(None)
with self.assertRaises(ValueError):
device_utils.DeviceUtils('')
class DeviceUtilsGetAVDsTest(mock_calls.TestCase):
def testGetAVDs(self):
with self.assertCall(
mock.call.pylib.cmd_helper.GetCmdOutput([mock.ANY, 'list', 'avd']),
'Available Android Virtual Devices:\n'
' Name: my_android5.0\n'
' Path: /some/path/to/.android/avd/my_android5.0.avd\n'
' Target: Android 5.0 (API level 21)\n'
' Tag/ABI: default/x86\n'
' Skin: WVGA800\n'):
self.assertEquals(['my_android5.0'],
device_utils.GetAVDs())
class DeviceUtilsRestartServerTest(mock_calls.TestCase):
@mock.patch('time.sleep', mock.Mock())
def testRestartServer_succeeds(self):
with self.assertCalls(
mock.call.pylib.device.adb_wrapper.AdbWrapper.KillServer(),
(mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
(1, '')),
mock.call.pylib.device.adb_wrapper.AdbWrapper.StartServer(),
(mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
(1, '')),
(mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
(0, '123\n'))):
device_utils.RestartServer()
class MockTempFile(object):
def __init__(self, name='/tmp/some/file'):
self.file = mock.MagicMock(spec=file)
self.file.name = name
self.file.name_quoted = cmd_helper.SingleQuote(name)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
pass
class _PatchedFunction(object):
def __init__(self, patched=None, mocked=None):
self.patched = patched
self.mocked = mocked
def _AdbWrapperMock(test_serial):
adb = mock.Mock(spec=adb_wrapper.AdbWrapper)
adb.__str__ = mock.Mock(return_value=test_serial)
adb.GetDeviceSerial.return_value = test_serial
return adb
class DeviceUtilsTest(mock_calls.TestCase):
def setUp(self):
self.adb = _AdbWrapperMock('0123456789abcdef')
self.device = device_utils.DeviceUtils(
self.adb, default_timeout=10, default_retries=0)
self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial'])
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 TimeoutError(self, msg=None):
if msg is None:
msg = 'Operation timed out'
return mock.Mock(side_effect=device_errors.CommandTimeoutError(
msg, str(self.device)))
def CommandError(self, msg=None):
if msg is None:
msg = 'Command failed'
return mock.Mock(side_effect=device_errors.CommandFailedError(
msg, str(self.device)))
class DeviceUtilsIsOnlineTest(DeviceUtilsTest):
def testIsOnline_true(self):
with self.assertCall(self.call.adb.GetState(), 'device'):
self.assertTrue(self.device.IsOnline())
def testIsOnline_false(self):
with self.assertCall(self.call.adb.GetState(), 'offline'):
self.assertFalse(self.device.IsOnline())
def testIsOnline_error(self):
with self.assertCall(self.call.adb.GetState(), self.CommandError()):
self.assertFalse(self.device.IsOnline())
class DeviceUtilsHasRootTest(DeviceUtilsTest):
def testHasRoot_true(self):
with self.assertCall(self.call.adb.Shell('ls /root'), 'foo\n'):
self.assertTrue(self.device.HasRoot())
def testHasRoot_false(self):
with self.assertCall(self.call.adb.Shell('ls /root'), self.ShellError()):
self.assertFalse(self.device.HasRoot())
class DeviceUtilsEnableRootTest(DeviceUtilsTest):
def testEnableRoot_succeeds(self):
with self.assertCalls(
(self.call.device.IsUserBuild(), False),
self.call.adb.Root(),
self.call.adb.WaitForDevice()):
self.device.EnableRoot()
def testEnableRoot_userBuild(self):
with self.assertCalls(
(self.call.device.IsUserBuild(), True)):
with self.assertRaises(device_errors.CommandFailedError):
self.device.EnableRoot()
def testEnableRoot_rootFails(self):
with self.assertCalls(
(self.call.device.IsUserBuild(), False),
(self.call.adb.Root(), self.CommandError())):
with self.assertRaises(device_errors.CommandFailedError):
self.device.EnableRoot()
class DeviceUtilsIsUserBuildTest(DeviceUtilsTest):
def testIsUserBuild_yes(self):
with self.assertCall(
self.call.device.GetProp('ro.build.type', cache=True), 'user'):
self.assertTrue(self.device.IsUserBuild())
def testIsUserBuild_no(self):
with self.assertCall(
self.call.device.GetProp('ro.build.type', cache=True), 'userdebug'):
self.assertFalse(self.device.IsUserBuild())
class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest):
def testGetExternalStoragePath_succeeds(self):
with self.assertCall(
self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '/fake/storage/path\n'):
self.assertEquals('/fake/storage/path',
self.device.GetExternalStoragePath())
def testGetExternalStoragePath_fails(self):
with self.assertCall(self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '\n'):
with self.assertRaises(device_errors.CommandFailedError):
self.device.GetExternalStoragePath()
class DeviceUtilsGetApplicationPathTest(DeviceUtilsTest):
def testGetApplicationPath_exists(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
(self.call.adb.Shell('pm path android'),
'package:/path/to/android.apk\n')):
self.assertEquals('/path/to/android.apk',
self.device.GetApplicationPath('android'))
def testGetApplicationPath_notExists(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
(self.call.adb.Shell('pm path not.installed.app'), '')):
self.assertEquals(None,
self.device.GetApplicationPath('not.installed.app'))
def testGetApplicationPath_fails(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
(self.call.adb.Shell('pm path android'),
self.CommandError('ERROR. Is package manager running?\n'))):
with self.assertRaises(device_errors.CommandFailedError):
self.device.GetApplicationPath('android')
@mock.patch('time.sleep', mock.Mock())
class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsTest):
def testWaitUntilFullyBooted_succeedsNoWifi(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), ''),
# pm_ready
(self.call.device.GetApplicationPath('android'),
'package:/some/fake/path'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), '1')):
self.device.WaitUntilFullyBooted(wifi=False)
def testWaitUntilFullyBooted_succeedsWithWifi(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), ''),
# pm_ready
(self.call.device.GetApplicationPath('android'),
'package:/some/fake/path'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), '1'),
# wifi_enabled
(self.call.adb.Shell('dumpsys wifi'),
'stuff\nWi-Fi is enabled\nmore stuff\n')):
self.device.WaitUntilFullyBooted(wifi=True)
def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), self.CommandError())):
with self.assertRaises(device_errors.CommandFailedError):
self.device.WaitUntilFullyBooted(wifi=False)
def testWaitUntilFullyBooted_sdCardReadyFails_notExists(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'),
self.TimeoutError())):
with self.assertRaises(device_errors.CommandTimeoutError):
self.device.WaitUntilFullyBooted(wifi=False)
def testWaitUntilFullyBooted_devicePmFails(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), ''),
# pm_ready
(self.call.device.GetApplicationPath('android'), self.CommandError()),
# pm_ready
(self.call.device.GetApplicationPath('android'), self.CommandError()),
# pm_ready
(self.call.device.GetApplicationPath('android'), self.TimeoutError())):
with self.assertRaises(device_errors.CommandTimeoutError):
self.device.WaitUntilFullyBooted(wifi=False)
def testWaitUntilFullyBooted_bootFails(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), ''),
# pm_ready
(self.call.device.GetApplicationPath('android'),
'package:/some/fake/path'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), '0'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), '0'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), self.TimeoutError())):
with self.assertRaises(device_errors.CommandTimeoutError):
self.device.WaitUntilFullyBooted(wifi=False)
def testWaitUntilFullyBooted_wifiFails(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
# sd_card_ready
(self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
(self.call.adb.Shell('test -d /fake/storage/path'), ''),
# pm_ready
(self.call.device.GetApplicationPath('android'),
'package:/some/fake/path'),
# boot_completed
(self.call.device.GetProp('sys.boot_completed'), '1'),
# wifi_enabled
(self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
# wifi_enabled
(self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
# wifi_enabled
(self.call.adb.Shell('dumpsys wifi'), self.TimeoutError())):
with self.assertRaises(device_errors.CommandTimeoutError):
self.device.WaitUntilFullyBooted(wifi=True)
@mock.patch('time.sleep', mock.Mock())
class DeviceUtilsRebootTest(DeviceUtilsTest):
def testReboot_nonBlocking(self):
with self.assertCalls(
self.call.adb.Reboot(),
(self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False)):
self.device.Reboot(block=False)
def testReboot_blocking(self):
with self.assertCalls(
self.call.adb.Reboot(),
(self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False),
self.call.device.WaitUntilFullyBooted(wifi=False)):
self.device.Reboot(block=True)
def testReboot_blockUntilWifi(self):
with self.assertCalls(
self.call.adb.Reboot(),
(self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False),
self.call.device.WaitUntilFullyBooted(wifi=True)):
self.device.Reboot(block=True, wifi=True)
class DeviceUtilsInstallTest(DeviceUtilsTest):
def testInstall_noPriorInstall(self):
with self.assertCalls(
(mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
'this.is.a.test.package'),
(self.call.device.GetApplicationPath('this.is.a.test.package'), None),
self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
self.device.Install('/fake/test/app.apk', retries=0)
def testInstall_differentPriorInstall(self):
with self.assertCalls(
(mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
'this.is.a.test.package'),
(self.call.device.GetApplicationPath('this.is.a.test.package'),
'/fake/data/app/this.is.a.test.package.apk'),
(self.call.device._GetChangedFilesImpl(
'/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
[('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')]),
self.call.adb.Uninstall('this.is.a.test.package'),
self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
self.device.Install('/fake/test/app.apk', retries=0)
def testInstall_differentPriorInstall_reinstall(self):
with self.assertCalls(
(mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
'this.is.a.test.package'),
(self.call.device.GetApplicationPath('this.is.a.test.package'),
'/fake/data/app/this.is.a.test.package.apk'),
(self.call.device._GetChangedFilesImpl(
'/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
[('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')]),
self.call.adb.Install('/fake/test/app.apk', reinstall=True)):
self.device.Install('/fake/test/app.apk', reinstall=True, retries=0)
def testInstall_identicalPriorInstall(self):
with self.assertCalls(
(mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
'this.is.a.test.package'),
(self.call.device.GetApplicationPath('this.is.a.test.package'),
'/fake/data/app/this.is.a.test.package.apk'),
(self.call.device._GetChangedFilesImpl(
'/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
[])):
self.device.Install('/fake/test/app.apk', retries=0)
def testInstall_fails(self):
with self.assertCalls(
(mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
'this.is.a.test.package'),
(self.call.device.GetApplicationPath('this.is.a.test.package'), None),
(self.call.adb.Install('/fake/test/app.apk', reinstall=False),
self.CommandError('Failure\r\n'))):
with self.assertRaises(device_errors.CommandFailedError):
self.device.Install('/fake/test/app.apk', retries=0)
class DeviceUtilsRunShellCommandTest(DeviceUtilsTest):
def setUp(self):
super(DeviceUtilsRunShellCommandTest, self).setUp()
self.device.NeedsSU = mock.Mock(return_value=False)
def testRunShellCommand_commandAsList(self):
with self.assertCall(self.call.adb.Shell('pm list packages'), ''):
self.device.RunShellCommand(['pm', 'list', 'packages'])
def testRunShellCommand_commandAsListQuoted(self):
with self.assertCall(self.call.adb.Shell("echo 'hello world' '$10'"), ''):
self.device.RunShellCommand(['echo', 'hello world', '$10'])
def testRunShellCommand_commandAsString(self):
with self.assertCall(self.call.adb.Shell('echo "$VAR"'), ''):
self.device.RunShellCommand('echo "$VAR"')
def testNewRunShellImpl_withEnv(self):
with self.assertCall(
self.call.adb.Shell('VAR=some_string echo "$VAR"'), ''):
self.device.RunShellCommand('echo "$VAR"', env={'VAR': 'some_string'})
def testNewRunShellImpl_withEnvQuoted(self):
with self.assertCall(
self.call.adb.Shell('PATH="$PATH:/other/path" run_this'), ''):
self.device.RunShellCommand('run_this', env={'PATH': '$PATH:/other/path'})
def testNewRunShellImpl_withEnv_failure(self):
with self.assertRaises(KeyError):
self.device.RunShellCommand('some_cmd', env={'INVALID NAME': 'value'})
def testNewRunShellImpl_withCwd(self):
with self.assertCall(self.call.adb.Shell('cd /some/test/path && ls'), ''):
self.device.RunShellCommand('ls', cwd='/some/test/path')
def testNewRunShellImpl_withCwdQuoted(self):
with self.assertCall(
self.call.adb.Shell("cd '/some test/path with/spaces' && ls"), ''):
self.device.RunShellCommand('ls', cwd='/some test/path with/spaces')
def testRunShellCommand_withHugeCmd(self):
payload = 'hi! ' * 1024
expected_cmd = "echo '%s'" % payload
with self.assertCalls(
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(
self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
(self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
self.assertEquals([payload],
self.device.RunShellCommand(['echo', payload]))
def testRunShellCommand_withHugeCmdAmdSU(self):
payload = 'hi! ' * 1024
expected_cmd = """su -c sh -c 'echo '"'"'%s'"'"''""" % payload
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(
self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
(self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
self.assertEquals(
[payload],
self.device.RunShellCommand(['echo', payload], as_root=True))
def testRunShellCommand_withSu(self):
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'setprop service.adb.root 0'"), '')):
self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
def testRunShellCommand_manyLines(self):
cmd = 'ls /some/path'
with self.assertCall(self.call.adb.Shell(cmd), 'file1\nfile2\nfile3\n'):
self.assertEquals(['file1', 'file2', 'file3'],
self.device.RunShellCommand(cmd))
def testRunShellCommand_singleLine_success(self):
cmd = 'echo $VALUE'
with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'):
self.assertEquals('some value',
self.device.RunShellCommand(cmd, single_line=True))
def testRunShellCommand_singleLine_successEmptyLine(self):
cmd = 'echo $VALUE'
with self.assertCall(self.call.adb.Shell(cmd), '\n'):
self.assertEquals('',
self.device.RunShellCommand(cmd, single_line=True))
def testRunShellCommand_singleLine_successWithoutEndLine(self):
cmd = 'echo -n $VALUE'
with self.assertCall(self.call.adb.Shell(cmd), 'some value'):
self.assertEquals('some value',
self.device.RunShellCommand(cmd, single_line=True))
def testRunShellCommand_singleLine_successNoOutput(self):
cmd = 'echo -n $VALUE'
with self.assertCall(self.call.adb.Shell(cmd), ''):
self.assertEquals('',
self.device.RunShellCommand(cmd, single_line=True))
def testRunShellCommand_singleLine_failTooManyLines(self):
cmd = 'echo $VALUE'
with self.assertCall(self.call.adb.Shell(cmd),
'some value\nanother value\n'):
with self.assertRaises(device_errors.CommandFailedError):
self.device.RunShellCommand(cmd, single_line=True)
def testRunShellCommand_checkReturn_success(self):
cmd = 'echo $ANDROID_DATA'
output = '/data\n'
with self.assertCall(self.call.adb.Shell(cmd), output):
self.assertEquals([output.rstrip()],
self.device.RunShellCommand(cmd, check_return=True))
def testRunShellCommand_checkReturn_failure(self):
cmd = 'ls /root'
output = 'opendir failed, Permission denied\n'
with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
with self.assertRaises(device_errors.AdbCommandFailedError):
self.device.RunShellCommand(cmd, check_return=True)
def testRunShellCommand_checkReturn_disabled(self):
cmd = 'ls /root'
output = 'opendir failed, Permission denied\n'
with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
self.assertEquals([output.rstrip()],
self.device.RunShellCommand(cmd, check_return=False))
class DeviceUtilsGetDevicePieWrapper(DeviceUtilsTest):
def testGetDevicePieWrapper_jb(self):
with self.assertCall(
self.call.device.build_version_sdk(),
constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN):
self.assertEqual('', self.device.GetDevicePieWrapper())
def testGetDevicePieWrapper_ics(self):
with self.assertCalls(
(self.call.device.build_version_sdk(),
constants.ANDROID_SDK_VERSION_CODES.ICE_CREAM_SANDWICH),
(mock.call.pylib.constants.GetOutDirectory(), '/foo/bar'),
(mock.call.os.path.exists(mock.ANY), True),
(self.call.adb.Push(mock.ANY, mock.ANY), '')):
self.assertNotEqual('', self.device.GetDevicePieWrapper())
@mock.patch('time.sleep', mock.Mock())
class DeviceUtilsKillAllTest(DeviceUtilsTest):
def testKillAll_noMatchingProcesses(self):
with self.assertCall(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'):
with self.assertRaises(device_errors.CommandFailedError):
self.device.KillAll('test_process')
def testKillAll_nonblocking(self):
with self.assertCalls(
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.adb.Shell('kill -9 1234'), '')):
self.assertEquals(1,
self.device.KillAll('some.process', blocking=False))
def testKillAll_blocking(self):
with self.assertCalls(
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.adb.Shell('kill -9 1234'), ''),
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n')):
self.assertEquals(1,
self.device.KillAll('some.process', blocking=True))
def testKillAll_root(self):
with self.assertCalls(
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')):
self.assertEquals(1,
self.device.KillAll('some.process', as_root=True))
def testKillAll_sigterm(self):
with self.assertCalls(
(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.adb.Shell('kill -15 1234'), '')):
self.assertEquals(1,
self.device.KillAll('some.process', signum=signal.SIGTERM))
class DeviceUtilsStartActivityTest(DeviceUtilsTest):
def testStartActivity_actionOnly(self):
test_intent = intent.Intent(action='android.intent.action.VIEW')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_success(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_failure(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Error: Failed to start test activity'):
with self.assertRaises(device_errors.CommandFailedError):
self.device.StartActivity(test_intent)
def testStartActivity_blocking(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCall(
self.call.adb.Shell('am start '
'-W '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent, blocking=True)
def testStartActivity_withCategory(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
category='android.intent.category.HOME')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-c android.intent.category.HOME '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withMultipleCategories(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
category=['android.intent.category.HOME',
'android.intent.category.BROWSABLE'])
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-c android.intent.category.HOME '
'-c android.intent.category.BROWSABLE '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withData(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
data='http://www.google.com/')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-d http://www.google.com/ '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withStringExtra(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
extras={'foo': 'test'})
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--es foo test'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withBoolExtra(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
extras={'foo': True})
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--ez foo True'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withIntExtra(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
extras={'foo': 123})
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--ei foo 123'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
def testStartActivity_withTraceFile(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCall(
self.call.adb.Shell('am start '
'--start-profiler test_trace_file.out '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent,
trace_file_name='test_trace_file.out')
def testStartActivity_withForceStop(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCall(
self.call.adb.Shell('am start '
'-S '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent, force_stop=True)
def testStartActivity_withFlags(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
flags='0x10000000')
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'-f 0x10000000'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
class DeviceUtilsStartInstrumentationTest(DeviceUtilsTest):
def testStartInstrumentation_nothing(self):
with self.assertCalls(
self.call.device.RunShellCommand(
['am', 'instrument', 'test.package/.TestInstrumentation'],
check_return=True)):
self.device.StartInstrumentation(
'test.package/.TestInstrumentation',
finish=False, raw=False, extras=None)
def testStartInstrumentation_finish(self):
with self.assertCalls(
(self.call.device.RunShellCommand(
['am', 'instrument', '-w', 'test.package/.TestInstrumentation'],
check_return=True),
['OK (1 test)'])):
output = self.device.StartInstrumentation(
'test.package/.TestInstrumentation',
finish=True, raw=False, extras=None)
self.assertEquals(['OK (1 test)'], output)
def testStartInstrumentation_raw(self):
with self.assertCalls(
self.call.device.RunShellCommand(
['am', 'instrument', '-r', 'test.package/.TestInstrumentation'],
check_return=True)):
self.device.StartInstrumentation(
'test.package/.TestInstrumentation',
finish=False, raw=True, extras=None)
def testStartInstrumentation_extras(self):
with self.assertCalls(
self.call.device.RunShellCommand(
['am', 'instrument', '-e', 'foo', 'Foo', '-e', 'bar', 'Bar',
'test.package/.TestInstrumentation'],
check_return=True)):
self.device.StartInstrumentation(
'test.package/.TestInstrumentation',
finish=False, raw=False, extras={'foo': 'Foo', 'bar': 'Bar'})
class DeviceUtilsBroadcastIntentTest(DeviceUtilsTest):
def testBroadcastIntent_noExtras(self):
test_intent = intent.Intent(action='test.package.with.an.INTENT')
with self.assertCall(
self.call.adb.Shell('am broadcast -a test.package.with.an.INTENT'),
'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
self.device.BroadcastIntent(test_intent)
def testBroadcastIntent_withExtra(self):
test_intent = intent.Intent(action='test.package.with.an.INTENT',
extras={'foo': 'bar value'})
with self.assertCall(
self.call.adb.Shell(
"am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"),
'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
self.device.BroadcastIntent(test_intent)
def testBroadcastIntent_withExtra_noValue(self):
test_intent = intent.Intent(action='test.package.with.an.INTENT',
extras={'foo': None})
with self.assertCall(
self.call.adb.Shell(
'am broadcast -a test.package.with.an.INTENT --esn foo'),
'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
self.device.BroadcastIntent(test_intent)
class DeviceUtilsGoHomeTest(DeviceUtilsTest):
def testGoHome(self):
with self.assertCall(
self.call.adb.Shell('am start -W -a android.intent.action.MAIN '
'-c android.intent.category.HOME'),
'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
self.device.GoHome()
class DeviceUtilsForceStopTest(DeviceUtilsTest):
def testForceStop(self):
with self.assertCall(
self.call.adb.Shell('am force-stop this.is.a.test.package'),
''):
self.device.ForceStop('this.is.a.test.package')
class DeviceUtilsClearApplicationStateTest(DeviceUtilsTest):
def testClearApplicationState_packageDoesntExist(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
(self.call.device.GetApplicationPath('this.package.does.not.exist'),
None)):
self.device.ClearApplicationState('this.package.does.not.exist')
def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
(self.call.adb.Shell('pm clear this.package.does.not.exist'),
'Failed\r\n')):
self.device.ClearApplicationState('this.package.does.not.exist')
def testClearApplicationState_packageExists(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
(self.call.device.GetApplicationPath('this.package.exists'),
'/data/app/this.package.exists.apk'),
(self.call.adb.Shell('pm clear this.package.exists'),
'Success\r\n')):
self.device.ClearApplicationState('this.package.exists')
def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
(self.call.adb.Shell('pm clear this.package.exists'),
'Success\r\n')):
self.device.ClearApplicationState('this.package.exists')
class DeviceUtilsSendKeyEventTest(DeviceUtilsTest):
def testSendKeyEvent(self):
with self.assertCall(self.call.adb.Shell('input keyevent 66'), ''):
self.device.SendKeyEvent(66)
class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsTest):
def testPushChangedFilesIndividually_empty(self):
test_files = []
with self.assertCalls():
self.device._PushChangedFilesIndividually(test_files)
def testPushChangedFilesIndividually_single(self):
test_files = [('/test/host/path', '/test/device/path')]
with self.assertCalls(self.call.adb.Push(*test_files[0])):
self.device._PushChangedFilesIndividually(test_files)
def testPushChangedFilesIndividually_multiple(self):
test_files = [
('/test/host/path/file1', '/test/device/path/file1'),
('/test/host/path/file2', '/test/device/path/file2')]
with self.assertCalls(
self.call.adb.Push(*test_files[0]),
self.call.adb.Push(*test_files[1])):
self.device._PushChangedFilesIndividually(test_files)
class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsTest):
def testPushChangedFilesZipped_empty(self):
test_files = []
with self.assertCalls():
self.device._PushChangedFilesZipped(test_files)
def _testPushChangedFilesZipped_spec(self, test_files):
mock_zip_temp = mock.mock_open()
mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip'
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp),
(mock.call.multiprocessing.Process(
target=device_utils.DeviceUtils._CreateDeviceZip,
args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()),
(self.call.device.GetExternalStoragePath(),
'/test/device/external_dir'),
self.call.adb.Push(
'/test/temp/file/tmp.zip', '/test/device/external_dir/tmp.zip'),
self.call.device.RunShellCommand(
['unzip', '/test/device/external_dir/tmp.zip'],
as_root=True,
env={'PATH': '/data/local/tmp/bin:$PATH'},
check_return=True),
(self.call.device.IsOnline(), True),
self.call.device.RunShellCommand(
['rm', '/test/device/external_dir/tmp.zip'], check_return=True)):
self.device._PushChangedFilesZipped(test_files)
def testPushChangedFilesZipped_single(self):
self._testPushChangedFilesZipped_spec(
[('/test/host/path/file1', '/test/device/path/file1')])
def testPushChangedFilesZipped_multiple(self):
self._testPushChangedFilesZipped_spec(
[('/test/host/path/file1', '/test/device/path/file1'),
('/test/host/path/file2', '/test/device/path/file2')])
class DeviceUtilsFileExistsTest(DeviceUtilsTest):
def testFileExists_usingTest_fileExists(self):
with self.assertCall(
self.call.device.RunShellCommand(
['test', '-e', '/path/file.exists'], check_return=True), ''):
self.assertTrue(self.device.FileExists('/path/file.exists'))
def testFileExists_usingTest_fileDoesntExist(self):
with self.assertCall(
self.call.device.RunShellCommand(
['test', '-e', '/does/not/exist'], check_return=True),
self.ShellError('', 1)):
self.assertFalse(self.device.FileExists('/does/not/exist'))
class DeviceUtilsPullFileTest(DeviceUtilsTest):
def testPullFile_existsOnDevice(self):
with mock.patch('os.path.exists', return_value=True):
with self.assertCall(
self.call.adb.Pull('/data/app/test.file.exists',
'/test/file/host/path')):
self.device.PullFile('/data/app/test.file.exists',
'/test/file/host/path')
def testPullFile_doesntExistOnDevice(self):
with mock.patch('os.path.exists', return_value=True):
with self.assertCall(
self.call.adb.Pull('/data/app/test.file.does.not.exist',
'/test/file/host/path'),
self.CommandError('remote object does not exist')):
with self.assertRaises(device_errors.CommandFailedError):
self.device.PullFile('/data/app/test.file.does.not.exist',
'/test/file/host/path')
class DeviceUtilsReadFileTest(DeviceUtilsTest):
def testReadFile_exists(self):
with self.assertCall(
self.call.adb.Shell('cat /read/this/test/file'),
'this is a test file\r\n'):
self.assertEqual('this is a test file\n',
self.device.ReadFile('/read/this/test/file'))
def testReadFile_doesNotExist(self):
with self.assertCall(
self.call.adb.Shell('cat /this/file/does.not.exist'),
self.ShellError('/system/bin/sh: cat: /this/file/does.not.exist: '
'No such file or directory')):
with self.assertRaises(device_errors.AdbCommandFailedError):
self.device.ReadFile('/this/file/does.not.exist')
def testReadFile_withSU(self):
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'cat /this/file/can.be.read.with.su'"),
'this is a test file\nread with su')):
self.assertEqual(
'this is a test file\nread with su\n',
self.device.ReadFile('/this/file/can.be.read.with.su',
as_root=True))
class DeviceUtilsWriteFileTest(DeviceUtilsTest):
def testWriteFileWithPush_success(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'some interesting contents'
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')):
self.device._WriteFileWithPush('/path/to/device/file', contents)
tmp_host.file.write.assert_called_once_with(contents)
def testWriteFileWithPush_rejected(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'some interesting contents'
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
(self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'),
self.CommandError())):
with self.assertRaises(device_errors.CommandFailedError):
self.device._WriteFileWithPush('/path/to/device/file', contents)
def testWriteFile_withPush(self):
contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
with self.assertCalls(
self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
self.device.WriteFile('/path/to/device/file', contents)
def testWriteFile_withPushForced(self):
contents = 'tiny contents'
with self.assertCalls(
self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
self.device.WriteFile('/path/to/device/file', contents, force_push=True)
def testWriteFile_withPushAndSU(self):
contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
MockTempFile('/sdcard/tmp/on.device')),
self.call.device._WriteFileWithPush('/sdcard/tmp/on.device', contents),
self.call.device.RunShellCommand(
['cp', '/sdcard/tmp/on.device', '/path/to/device/file'],
as_root=True, check_return=True)):
self.device.WriteFile('/path/to/device/file', contents, as_root=True)
def testWriteFile_withEcho(self):
with self.assertCall(self.call.adb.Shell(
"echo -n the.contents > /test/file/to.write"), ''):
self.device.WriteFile('/test/file/to.write', 'the.contents')
def testWriteFile_withEchoAndQuotes(self):
with self.assertCall(self.call.adb.Shell(
"echo -n 'the contents' > '/test/file/to write'"), ''):
self.device.WriteFile('/test/file/to write', 'the contents')
def testWriteFile_withEchoAndSU(self):
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'echo -n contents > /test/file'"),
'')):
self.device.WriteFile('/test/file', 'contents', as_root=True)
class DeviceUtilsLsTest(DeviceUtilsTest):
def testLs_directory(self):
result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
with self.assertCalls(
(self.call.adb.Ls('/data/local/tmp'), result)):
self.assertEquals(result,
self.device.Ls('/data/local/tmp'))
def testLs_nothing(self):
with self.assertCalls(
(self.call.adb.Ls('/data/local/tmp/testfile.txt'), [])):
self.assertEquals([],
self.device.Ls('/data/local/tmp/testfile.txt'))
class DeviceUtilsStatTest(DeviceUtilsTest):
def testStat_file(self):
result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
with self.assertCalls(
(self.call.adb.Ls('/data/local/tmp'), result)):
self.assertEquals(adb_wrapper.DeviceStat(33206, 3, 1417436122),
self.device.Stat('/data/local/tmp/testfile.txt'))
def testStat_directory(self):
result = [('.', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
('tmp', adb_wrapper.DeviceStat(16889, 4096, 1417436123))]
with self.assertCalls(
(self.call.adb.Ls('/data/local'), result)):
self.assertEquals(adb_wrapper.DeviceStat(16889, 4096, 1417436123),
self.device.Stat('/data/local/tmp'))
def testStat_doesNotExist(self):
result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
with self.assertCalls(
(self.call.adb.Ls('/data/local/tmp'), result)):
with self.assertRaises(device_errors.CommandFailedError):
self.device.Stat('/data/local/tmp/does.not.exist.txt')
class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest):
def testSetJavaAsserts_enable(self):
with self.assertCalls(
(self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
'some.example.prop=with an example value\n'
'some.other.prop=value_ok\n'),
self.call.device.WriteFile(
constants.DEVICE_LOCAL_PROPERTIES_PATH,
'some.example.prop=with an example value\n'
'some.other.prop=value_ok\n'
'dalvik.vm.enableassertions=all\n'),
(self.call.device.GetProp('dalvik.vm.enableassertions'), ''),
self.call.device.SetProp('dalvik.vm.enableassertions', 'all')):
self.assertTrue(self.device.SetJavaAsserts(True))
def testSetJavaAsserts_disable(self):
with self.assertCalls(
(self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
'some.example.prop=with an example value\n'
'dalvik.vm.enableassertions=all\n'
'some.other.prop=value_ok\n'),
self.call.device.WriteFile(
constants.DEVICE_LOCAL_PROPERTIES_PATH,
'some.example.prop=with an example value\n'
'some.other.prop=value_ok\n'),
(self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'),
self.call.device.SetProp('dalvik.vm.enableassertions', '')):
self.assertTrue(self.device.SetJavaAsserts(False))
def testSetJavaAsserts_alreadyEnabled(self):
with self.assertCalls(
(self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
'some.example.prop=with an example value\n'
'dalvik.vm.enableassertions=all\n'
'some.other.prop=value_ok\n'),
(self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')):
self.assertFalse(self.device.SetJavaAsserts(True))
class DeviceUtilsGetPropTest(DeviceUtilsTest):
def testGetProp_exists(self):
with self.assertCall(
self.call.adb.Shell('getprop test.property'), 'property_value\n'):
self.assertEqual('property_value',
self.device.GetProp('test.property'))
def testGetProp_doesNotExist(self):
with self.assertCall(
self.call.adb.Shell('getprop property.does.not.exist'), '\n'):
self.assertEqual('', self.device.GetProp('property.does.not.exist'))
def testGetProp_cachedRoProp(self):
with self.assertCall(
self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n'):
self.assertEqual('userdebug',
self.device.GetProp('ro.build.type', cache=True))
self.assertEqual('userdebug',
self.device.GetProp('ro.build.type', cache=True))
def testGetProp_retryAndCache(self):
with self.assertCalls(
(self.call.adb.Shell('getprop ro.build.type'), self.ShellError()),
(self.call.adb.Shell('getprop ro.build.type'), self.ShellError()),
(self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n')):
self.assertEqual('userdebug',
self.device.GetProp('ro.build.type',
cache=True, retries=3))
self.assertEqual('userdebug',
self.device.GetProp('ro.build.type',
cache=True, retries=3))
class DeviceUtilsSetPropTest(DeviceUtilsTest):
def testSetProp(self):
with self.assertCall(
self.call.adb.Shell("setprop test.property 'test value'"), ''):
self.device.SetProp('test.property', 'test value')
def testSetProp_check_succeeds(self):
with self.assertCalls(
(self.call.adb.Shell('setprop test.property new_value'), ''),
(self.call.adb.Shell('getprop test.property'), 'new_value')):
self.device.SetProp('test.property', 'new_value', check=True)
def testSetProp_check_fails(self):
with self.assertCalls(
(self.call.adb.Shell('setprop test.property new_value'), ''),
(self.call.adb.Shell('getprop test.property'), 'old_value')):
with self.assertRaises(device_errors.CommandFailedError):
self.device.SetProp('test.property', 'new_value', check=True)
class DeviceUtilsGetPidsTest(DeviceUtilsTest):
def testGetPids_noMatches(self):
with self.assertCall(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'user 1000 100 1024 1024 ffffffff 00000000 no.match\n'):
self.assertEqual({}, self.device.GetPids('does.not.match'))
def testGetPids_oneMatch(self):
with self.assertCall(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'user 1000 100 1024 1024 ffffffff 00000000 not.a.match\n'
'user 1001 100 1024 1024 ffffffff 00000000 one.match\n'):
self.assertEqual({'one.match': '1001'}, self.device.GetPids('one.match'))
def testGetPids_mutlipleMatches(self):
with self.assertCall(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'user 1000 100 1024 1024 ffffffff 00000000 not\n'
'user 1001 100 1024 1024 ffffffff 00000000 one.match\n'
'user 1002 100 1024 1024 ffffffff 00000000 two.match\n'
'user 1003 100 1024 1024 ffffffff 00000000 three.match\n'):
self.assertEqual(
{'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
self.device.GetPids('match'))
def testGetPids_exactMatch(self):
with self.assertCall(self.call.adb.Shell('ps'),
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'user 1000 100 1024 1024 ffffffff 00000000 not.exact.match\n'
'user 1234 100 1024 1024 ffffffff 00000000 exact.match\n'):
self.assertEqual(
{'not.exact.match': '1000', 'exact.match': '1234'},
self.device.GetPids('exact.match'))
class DeviceUtilsTakeScreenshotTest(DeviceUtilsTest):
def testTakeScreenshot_fileNameProvided(self):
with self.assertCalls(
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(
self.adb, suffix='.png'),
MockTempFile('/tmp/path/temp-123.png')),
(self.call.adb.Shell('/system/bin/screencap -p /tmp/path/temp-123.png'),
''),
self.call.device.PullFile('/tmp/path/temp-123.png',
'/test/host/screenshot.png')):
self.device.TakeScreenshot('/test/host/screenshot.png')
class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest):
def setUp(self):
super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp()
def testGetMemoryUsageForPid_validPid(self):
with self.assertCalls(
(self.call.device.RunShellCommand(
['showmap', '1234'], as_root=True, check_return=True),
['100 101 102 103 104 105 106 107 TOTAL']),
(self.call.device.ReadFile('/proc/1234/status', as_root=True),
'VmHWM: 1024 kB\n')):
self.assertEqual(
{
'Size': 100,
'Rss': 101,
'Pss': 102,
'Shared_Clean': 103,
'Shared_Dirty': 104,
'Private_Clean': 105,
'Private_Dirty': 106,
'VmHWM': 1024
},
self.device.GetMemoryUsageForPid(1234))
def testGetMemoryUsageForPid_noSmaps(self):
with self.assertCalls(
(self.call.device.RunShellCommand(
['showmap', '4321'], as_root=True, check_return=True),
['cannot open /proc/4321/smaps: No such file or directory']),
(self.call.device.ReadFile('/proc/4321/status', as_root=True),
'VmHWM: 1024 kb\n')):
self.assertEquals({'VmHWM': 1024}, self.device.GetMemoryUsageForPid(4321))
def testGetMemoryUsageForPid_noStatus(self):
with self.assertCalls(
(self.call.device.RunShellCommand(
['showmap', '4321'], as_root=True, check_return=True),
['100 101 102 103 104 105 106 107 TOTAL']),
(self.call.device.ReadFile('/proc/4321/status', as_root=True),
self.CommandError())):
self.assertEquals(
{
'Size': 100,
'Rss': 101,
'Pss': 102,
'Shared_Clean': 103,
'Shared_Dirty': 104,
'Private_Clean': 105,
'Private_Dirty': 106,
},
self.device.GetMemoryUsageForPid(4321))
class DeviceUtilsStrTest(DeviceUtilsTest):
def testStr_returnsSerial(self):
with self.assertCalls(
(self.call.adb.GetDeviceSerial(), '0123456789abcdef')):
self.assertEqual('0123456789abcdef', str(self.device))
class DeviceUtilsParallelTest(mock_calls.TestCase):
def testParallel_default(self):
test_serials = ['0123456789abcdef', 'fedcba9876543210']
with self.assertCall(
mock.call.pylib.device.adb_wrapper.AdbWrapper.GetDevices(),
[_AdbWrapperMock(serial) for serial in test_serials]):
parallel_devices = device_utils.DeviceUtils.parallel()
for serial, device in zip(test_serials, parallel_devices.pGet(None)):
self.assertTrue(
isinstance(device, device_utils.DeviceUtils)
and serial == str(device),
'Expected a DeviceUtils object with serial %s' % serial)
def testParallel_noDevices(self):
with self.assertCall(
mock.call.pylib.device.adb_wrapper.AdbWrapper.GetDevices(), []):
with self.assertRaises(device_errors.NoDevicesError):
device_utils.DeviceUtils.parallel()
if __name__ == '__main__':
logging.getLogger().setLevel(logging.DEBUG)
unittest.main(verbosity=2)