Update to latest catapult (1ff7619f)
bug:21925298
bug:29643805
bug:30299278
bug:30397774
bug:30953297
Change-Id: I4d73c3c5454541a50703253ebeb63e5b2ea01fec
diff --git a/catapult/devil/devil/android/device_utils_test.py b/catapult/devil/devil/android/device_utils_test.py
index 38849ec..18fda54 100755
--- a/catapult/devil/devil/android/device_utils_test.py
+++ b/catapult/devil/devil/android/device_utils_test.py
@@ -10,7 +10,10 @@
# pylint: disable=protected-access
# pylint: disable=unused-argument
+import json
import logging
+import os
+import stat
import unittest
from devil import devil_env
@@ -27,6 +30,17 @@
import mock # pylint: disable=import-error
+class AnyStringWith(object):
+ def __init__(self, value):
+ self._value = value
+
+ def __eq__(self, other):
+ return self._value in other
+
+ def __repr__(self):
+ return '<AnyStringWith: %s>' % self._value
+
+
class _MockApkHelper(object):
def __init__(self, path, package_name, perms=None):
@@ -41,6 +55,10 @@
return self.perms
+class _MockMultipleDevicesError(Exception):
+ pass
+
+
class DeviceUtilsInitTest(unittest.TestCase):
def testInitWithStr(self):
@@ -172,6 +190,12 @@
return mock.Mock(side_effect=device_errors.CommandTimeoutError(
msg, str(self.device)))
+ def EnsureCacheInitialized(self, props=None, sdcard='/sdcard'):
+ props = props or []
+ ret = [sdcard, 'TOKEN'] + props
+ return (self.call.device.RunShellCommand(
+ AnyStringWith('getprop'), check_return=True, large_output=True), ret)
+
class DeviceUtilsEqTest(DeviceUtilsTest):
@@ -305,13 +329,14 @@
class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest):
def testGetExternalStoragePath_succeeds(self):
- with self.assertCall(
- self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '/fake/storage/path\n'):
+ with self.assertCalls(
+ self.EnsureCacheInitialized(sdcard='/fake/storage/path')):
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.assertCalls(
+ self.EnsureCacheInitialized(sdcard='')):
with self.assertRaises(device_errors.CommandFailedError):
self.device.GetExternalStoragePath()
@@ -451,6 +476,23 @@
(self.call.device.GetProp('sys.boot_completed', cache=False), '1')):
self.device.WaitUntilFullyBooted(wifi=False)
+ def testWaitUntilFullyBooted_deviceBrieflyOffline(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._GetApplicationPathsInternal('android',
+ skip_cache=True),
+ ['package:/some/fake/path']),
+ # boot_completed
+ (self.call.device.GetProp('sys.boot_completed', cache=False),
+ self.AdbCommandError()),
+ # boot_completed
+ (self.call.device.GetProp('sys.boot_completed', cache=False), '1')):
+ self.device.WaitUntilFullyBooted(wifi=False)
+
def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self):
with self.assertCalls(
self.call.adb.WaitForDevice(),
@@ -835,6 +877,12 @@
self.assertEquals(['file1', 'file2', 'file3'],
self.device.RunShellCommand(cmd))
+ def testRunShellCommand_manyLinesRawOutput(self):
+ cmd = 'ls /some/path'
+ with self.assertCall(self.call.adb.Shell(cmd), '\rfile1\nfile2\r\nfile3\n'):
+ self.assertEquals('\rfile1\nfile2\r\nfile3\n',
+ self.device.RunShellCommand(cmd, raw_output=True))
+
def testRunShellCommand_singleLine_success(self):
cmd = 'echo $VALUE'
with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'):
@@ -1198,12 +1246,15 @@
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='test.package',
activity='.Main',
- flags='0x10000000')
+ flags=[
+ intent.FLAG_ACTIVITY_NEW_TASK,
+ intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ ])
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n test.package/.Main '
- '-f 0x10000000'),
+ '-f 0x10200000'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)
@@ -1599,10 +1650,7 @@
def testReadFile_exists(self):
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/read/this/test/file'],
- as_root=False, check_return=True),
- ['-rw-rw---- root foo 256 1970-01-01 00:00 file']),
+ (self.call.device.FileSize('/read/this/test/file', as_root=False), 256),
(self.call.device.RunShellCommand(
['cat', '/read/this/test/file'],
as_root=False, check_return=True),
@@ -1613,10 +1661,7 @@
def testReadFile_exists2(self):
# Same as testReadFile_exists, but uses Android N ls output.
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/read/this/test/file'],
- as_root=False, check_return=True),
- ['-rw-rw-rw- 1 root root 256 2016-03-15 03:27 /read/this/test/file']),
+ (self.call.device.FileSize('/read/this/test/file', as_root=False), 256),
(self.call.device.RunShellCommand(
['cat', '/read/this/test/file'],
as_root=False, check_return=True),
@@ -1626,19 +1671,15 @@
def testReadFile_doesNotExist(self):
with self.assertCall(
- self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/does.not.exist'],
- as_root=False, check_return=True),
+ self.call.device.FileSize('/this/file/does.not.exist', as_root=False),
self.CommandError('File does not exist')):
with self.assertRaises(device_errors.CommandFailedError):
self.device.ReadFile('/this/file/does.not.exist')
def testReadFile_zeroSize(self):
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/has/zero/size'],
- as_root=False, check_return=True),
- ['-r--r--r-- root foo 0 1970-01-01 00:00 zero_size_file']),
+ (self.call.device.FileSize('/this/file/has/zero/size', as_root=False),
+ 0),
(self.call.device._ReadFileWithPull('/this/file/has/zero/size'),
'but it has contents\n')):
self.assertEqual('but it has contents\n',
@@ -1646,10 +1687,8 @@
def testReadFile_withSU(self):
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/can.be.read.with.su'],
- as_root=True, check_return=True),
- ['-rw------- root root 256 1970-01-01 00:00 can.be.read.with.su']),
+ (self.call.device.FileSize(
+ '/this/file/can.be.read.with.su', as_root=True), 256),
(self.call.device.RunShellCommand(
['cat', '/this/file/can.be.read.with.su'],
as_root=True, check_return=True),
@@ -1662,10 +1701,8 @@
def testReadFile_withPull(self):
contents = 'a' * 123456
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/read/this/big/test/file'],
- as_root=False, check_return=True),
- ['-rw-rw---- root foo 123456 1970-01-01 00:00 file']),
+ (self.call.device.FileSize('/read/this/big/test/file', as_root=False),
+ 123456),
(self.call.device._ReadFileWithPull('/read/this/big/test/file'),
contents)):
self.assertEqual(
@@ -1674,10 +1711,8 @@
def testReadFile_withPullAndSU(self):
contents = 'b' * 123456
with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/big/file/can.be.read.with.su'],
- as_root=True, check_return=True),
- ['-rw------- root root 123456 1970-01-01 00:00 can.be.read.with.su']),
+ (self.call.device.FileSize(
+ '/this/big/file/can.be.read.with.su', as_root=True), 123456),
(self.call.device.NeedsSU(), True),
(mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb),
MockTempFile('/sdcard/tmp/on.device')),
@@ -1768,52 +1803,189 @@
self.device.WriteFile('/test/file', 'contents', as_root=True)
-class DeviceUtilsLsTest(DeviceUtilsTest):
+class DeviceUtilsStatDirectoryTest(DeviceUtilsTest):
+ # Note: Also tests ListDirectory in testStatDirectory_fileList.
- 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'))
+ EXAMPLE_LS_OUTPUT = [
+ 'total 12345',
+ 'drwxr-xr-x 19 root root 0 1970-04-06 18:03 .',
+ 'drwxr-xr-x 19 root root 0 1970-04-06 18:03 ..',
+ 'drwxr-xr-x 6 root root 1970-01-01 00:00 some_dir',
+ '-rw-r--r-- 1 root root 723 1971-01-01 07:04 some_file',
+ '-rw-r----- 1 root root 327 2009-02-13 23:30 My Music File',
+ # Older Android versions do not print st_nlink
+ 'lrwxrwxrwx root root 1970-01-01 00:00 lnk -> /some/path',
+ 'srwxrwx--- system system 2016-05-31 17:25 a_socket1',
+ 'drwxrwxrwt system misc 1970-11-23 02:25 tmp',
+ 'drwxr-s--- system shell 1970-11-23 02:24 my_cmd',
+ 'cr--r----- root system 10, 183 1971-01-01 07:04 random',
+ 'brw------- root root 7, 0 1971-01-01 07:04 block_dev',
+ '-rwS------ root shell 157404 2015-04-13 15:44 silly',
+ ]
- 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'))
+ FILENAMES = [
+ 'some_dir', 'some_file', 'My Music File', 'lnk', 'a_socket1',
+ 'tmp', 'my_cmd', 'random', 'block_dev', 'silly']
+
+ def getStatEntries(self, path_given='/', path_listed='/'):
+ with self.assertCall(
+ self.call.device.RunShellCommand(
+ ['ls', '-a', '-l', path_listed],
+ check_return=True, as_root=False, env={'TZ': 'utc'}),
+ self.EXAMPLE_LS_OUTPUT):
+ entries = self.device.StatDirectory(path_given)
+ return {f['filename']: f for f in entries}
+
+ def getListEntries(self):
+ with self.assertCall(
+ self.call.device.RunShellCommand(
+ ['ls', '-a', '-l', '/'],
+ check_return=True, as_root=False, env={'TZ': 'utc'}),
+ self.EXAMPLE_LS_OUTPUT):
+ return self.device.ListDirectory('/')
+
+ def testStatDirectory_forceTrailingSlash(self):
+ self.getStatEntries(path_given='/foo/bar/', path_listed='/foo/bar/')
+ self.getStatEntries(path_given='/foo/bar', path_listed='/foo/bar/')
+
+ def testStatDirectory_fileList(self):
+ self.assertItemsEqual(self.getStatEntries().keys(), self.FILENAMES)
+ self.assertItemsEqual(self.getListEntries(), self.FILENAMES)
+
+ def testStatDirectory_fileModes(self):
+ expected_modes = (
+ ('some_dir', stat.S_ISDIR),
+ ('some_file', stat.S_ISREG),
+ ('lnk', stat.S_ISLNK),
+ ('a_socket1', stat.S_ISSOCK),
+ ('block_dev', stat.S_ISBLK),
+ ('random', stat.S_ISCHR),
+ )
+ entries = self.getStatEntries()
+ for filename, check in expected_modes:
+ self.assertTrue(check(entries[filename]['st_mode']))
+
+ def testStatDirectory_filePermissions(self):
+ should_have = (
+ ('some_file', stat.S_IWUSR), # Owner can write.
+ ('tmp', stat.S_IXOTH), # Others can execute.
+ ('tmp', stat.S_ISVTX), # Has sticky bit.
+ ('my_cmd', stat.S_ISGID), # Has set-group-ID bit.
+ ('silly', stat.S_ISUID), # Has set UID bit.
+ )
+ should_not_have = (
+ ('some_file', stat.S_IWOTH), # Others can't write.
+ ('block_dev', stat.S_IRGRP), # Group can't read.
+ ('silly', stat.S_IXUSR), # Owner can't execute.
+ )
+ entries = self.getStatEntries()
+ for filename, bit in should_have:
+ self.assertTrue(entries[filename]['st_mode'] & bit)
+ for filename, bit in should_not_have:
+ self.assertFalse(entries[filename]['st_mode'] & bit)
+
+ def testStatDirectory_numHardLinks(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['some_dir']['st_nlink'], 6)
+ self.assertEqual(entries['some_file']['st_nlink'], 1)
+ self.assertFalse('st_nlink' in entries['tmp'])
+
+ def testStatDirectory_fileOwners(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['some_dir']['st_owner'], 'root')
+ self.assertEqual(entries['my_cmd']['st_owner'], 'system')
+ self.assertEqual(entries['my_cmd']['st_group'], 'shell')
+ self.assertEqual(entries['tmp']['st_group'], 'misc')
+
+ def testStatDirectory_fileSize(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['some_file']['st_size'], 723)
+ self.assertEqual(entries['My Music File']['st_size'], 327)
+ # Sizes are sometimes not reported for non-regular files, don't try to
+ # guess the size in those cases.
+ self.assertFalse('st_size' in entries['some_dir'])
+
+ def testStatDirectory_fileDateTime(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['some_dir']['st_mtime'], 0) # Epoch!
+ self.assertEqual(entries['My Music File']['st_mtime'], 1234567800)
+
+ def testStatDirectory_deviceType(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['random']['st_rdev_pair'], (10, 183))
+ self.assertEqual(entries['block_dev']['st_rdev_pair'], (7, 0))
+
+ def testStatDirectory_symbolicLinks(self):
+ entries = self.getStatEntries()
+ self.assertEqual(entries['lnk']['symbolic_link_to'], '/some/path')
+ for d in entries.itervalues():
+ self.assertEqual('symbolic_link_to' in d, stat.S_ISLNK(d['st_mode']))
-class DeviceUtilsStatTest(DeviceUtilsTest):
+class DeviceUtilsStatPathTest(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'))
+ EXAMPLE_DIRECTORY = [
+ {'filename': 'foo.txt', 'st_size': 123, 'st_time': 456},
+ {'filename': 'some_dir', 'st_time': 0}
+ ]
+ INDEX = {e['filename']: e for e in EXAMPLE_DIRECTORY}
- 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 testStatPath_file(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ self.assertEquals(self.INDEX['foo.txt'],
+ self.device.StatPath('/data/local/tmp/foo.txt'))
- 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)):
+ def testStatPath_directory(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ self.assertEquals(self.INDEX['some_dir'],
+ self.device.StatPath('/data/local/tmp/some_dir'))
+
+ def testStatPath_directoryWithTrailingSlash(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ self.assertEquals(self.INDEX['some_dir'],
+ self.device.StatPath('/data/local/tmp/some_dir/'))
+
+ def testStatPath_doesNotExist(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
with self.assertRaises(device_errors.CommandFailedError):
- self.device.Stat('/data/local/tmp/does.not.exist.txt')
+ self.device.StatPath('/data/local/tmp/does.not.exist.txt')
+
+
+class DeviceUtilsFileSizeTest(DeviceUtilsTest):
+
+ EXAMPLE_DIRECTORY = [
+ {'filename': 'foo.txt', 'st_size': 123, 'st_mtime': 456},
+ {'filename': 'some_dir', 'st_mtime': 0}
+ ]
+
+ def testFileSize_file(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ self.assertEquals(123,
+ self.device.FileSize('/data/local/tmp/foo.txt'))
+
+ def testFileSize_doesNotExist(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ with self.assertRaises(device_errors.CommandFailedError):
+ self.device.FileSize('/data/local/tmp/does.not.exist.txt')
+
+ def testFileSize_directoryWithNoSize(self):
+ with self.assertCall(
+ self.call.device.StatDirectory('/data/local/tmp', as_root=False),
+ self.EXAMPLE_DIRECTORY):
+ with self.assertRaises(device_errors.CommandFailedError):
+ self.device.FileSize('/data/local/tmp/some_dir')
class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest):
@@ -1866,6 +2038,34 @@
self.assertFalse(self.device.SetJavaAsserts(True))
+class DeviceUtilsEnsureCacheInitializedTest(DeviceUtilsTest):
+
+ def testEnsureCacheInitialized_noCache_success(self):
+ self.assertIsNone(self.device._cache['token'])
+ with self.assertCall(
+ self.call.device.RunShellCommand(
+ AnyStringWith('getprop'), check_return=True, large_output=True),
+ ['/sdcard', 'TOKEN']):
+ self.device._EnsureCacheInitialized()
+ self.assertIsNotNone(self.device._cache['token'])
+
+ def testEnsureCacheInitialized_noCache_failure(self):
+ self.assertIsNone(self.device._cache['token'])
+ with self.assertCall(
+ self.call.device.RunShellCommand(
+ AnyStringWith('getprop'), check_return=True, large_output=True),
+ self.TimeoutError()):
+ with self.assertRaises(device_errors.CommandTimeoutError):
+ self.device._EnsureCacheInitialized()
+ self.assertIsNone(self.device._cache['token'])
+
+ def testEnsureCacheInitialized_cache(self):
+ self.device._cache['token'] = 'TOKEN'
+ with self.assertCalls():
+ self.device._EnsureCacheInitialized()
+ self.assertIsNotNone(self.device._cache['token'])
+
+
class DeviceUtilsGetPropTest(DeviceUtilsTest):
def testGetProp_exists(self):
@@ -1889,30 +2089,12 @@
self.assertEqual('', self.device.GetProp('property.does.not.exist'))
def testGetProp_cachedRoProp(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['getprop'], check_return=True, large_output=True,
- timeout=self.device._default_timeout,
- retries=self.device._default_retries),
- ['[ro.build.type]: [userdebug]']):
- 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.device.RunShellCommand(
- ['getprop'], check_return=True, large_output=True,
- timeout=self.device._default_timeout,
- retries=3),
- ['[ro.build.type]: [userdebug]'])):
+ self.EnsureCacheInitialized(props=['[ro.build.type]: [userdebug]'])):
self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type',
- cache=True, retries=3))
+ self.device.GetProp('ro.build.type', cache=True))
self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type',
- cache=True, retries=3))
+ self.device.GetProp('ro.build.type', cache=True))
class DeviceUtilsSetPropTest(DeviceUtilsTest):
@@ -2139,7 +2321,7 @@
class DeviceUtilsHealthyDevicesTest(mock_calls.TestCase):
- def testHealthyDevices_emptyBlacklist(self):
+ def testHealthyDevices_emptyBlacklist_defaultDeviceArg(self):
test_serials = ['0123456789abcdef', 'fedcba9876543210']
with self.assertCalls(
(mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
@@ -2150,7 +2332,7 @@
self.assertTrue(isinstance(device, device_utils.DeviceUtils))
self.assertEquals(serial, device.adb.GetDeviceSerial())
- def testHealthyDevices_blacklist(self):
+ def testHealthyDevices_blacklist_defaultDeviceArg(self):
test_serials = ['0123456789abcdef', 'fedcba9876543210']
with self.assertCalls(
(mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
@@ -2162,6 +2344,81 @@
self.assertTrue(isinstance(devices[0], device_utils.DeviceUtils))
self.assertEquals('0123456789abcdef', devices[0].adb.GetDeviceSerial())
+ def testHealthyDevices_noneDeviceArg_multiple_attached(self):
+ test_serials = ['0123456789abcdef', 'fedcba9876543210']
+ with self.assertCalls(
+ (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
+ [_AdbWrapperMock(s) for s in test_serials]),
+ (mock.call.devil.android.device_errors.MultipleDevicesError(mock.ANY),
+ _MockMultipleDevicesError())):
+ with self.assertRaises(_MockMultipleDevicesError):
+ device_utils.DeviceUtils.HealthyDevices(device_arg=None)
+
+ def testHealthyDevices_noneDeviceArg_one_attached(self):
+ test_serials = ['0123456789abcdef']
+ with self.assertCalls(
+ (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
+ [_AdbWrapperMock(s) for s in test_serials])):
+ devices = device_utils.DeviceUtils.HealthyDevices(device_arg=None)
+ self.assertEquals(1, len(devices))
+
+ def testHealthyDevices_noneDeviceArg_no_attached(self):
+ test_serials = []
+ with self.assertCalls(
+ (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
+ [_AdbWrapperMock(s) for s in test_serials])):
+ with self.assertRaises(device_errors.NoDevicesError):
+ device_utils.DeviceUtils.HealthyDevices(device_arg=None)
+
+ def testHealthyDevices_noneDeviceArg_multiple_attached_ANDROID_SERIAL(self):
+ try:
+ os.environ['ANDROID_SERIAL'] = '0123456789abcdef'
+ with self.assertCalls(): # Should skip adb devices when device is known.
+ device_utils.DeviceUtils.HealthyDevices(device_arg=None)
+ finally:
+ del os.environ['ANDROID_SERIAL']
+
+ def testHealthyDevices_stringDeviceArg(self):
+ with self.assertCalls(): # Should skip adb devices when device is known.
+ devices = device_utils.DeviceUtils.HealthyDevices(
+ device_arg='0123456789abcdef')
+ self.assertEquals(1, len(devices))
+
+ def testHealthyDevices_EmptyListDeviceArg_multiple_attached(self):
+ test_serials = ['0123456789abcdef', 'fedcba9876543210']
+ with self.assertCalls(
+ (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
+ [_AdbWrapperMock(s) for s in test_serials])):
+ devices = device_utils.DeviceUtils.HealthyDevices(device_arg=())
+ self.assertEquals(2, len(devices))
+
+ def testHealthyDevices_EmptyListDeviceArg_ANDROID_SERIAL(self):
+ try:
+ os.environ['ANDROID_SERIAL'] = '0123456789abcdef'
+ with self.assertCalls(): # Should skip adb devices when device is known.
+ devices = device_utils.DeviceUtils.HealthyDevices(device_arg=())
+ finally:
+ del os.environ['ANDROID_SERIAL']
+ self.assertEquals(1, len(devices))
+
+ def testHealthyDevices_EmptyListDeviceArg_no_attached(self):
+ test_serials = []
+ with self.assertCalls(
+ (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
+ [_AdbWrapperMock(s) for s in test_serials])):
+ with self.assertRaises(device_errors.NoDevicesError):
+ device_utils.DeviceUtils.HealthyDevices(device_arg=[])
+
+ def testHealthyDevices_ListDeviceArg(self):
+ device_arg = ['0123456789abcdef', 'fedcba9876543210']
+ try:
+ os.environ['ANDROID_SERIAL'] = 'should-not-apply'
+ with self.assertCalls(): # Should skip adb devices when device is known.
+ devices = device_utils.DeviceUtils.HealthyDevices(device_arg=device_arg)
+ finally:
+ del os.environ['ANDROID_SERIAL']
+ self.assertEquals(2, len(devices))
+
class DeviceUtilsRestartAdbdTest(DeviceUtilsTest):
@@ -2307,6 +2564,31 @@
(self.call.device.IsScreenOn(), False)):
self.device.SetScreen(False)
+class DeviecUtilsLoadCacheData(DeviceUtilsTest):
+
+ def testTokenMissing(self):
+ with self.assertCalls(
+ self.EnsureCacheInitialized()):
+ self.assertFalse(self.device.LoadCacheData('{}'))
+
+ def testTokenStale(self):
+ with self.assertCalls(
+ self.EnsureCacheInitialized()):
+ self.assertFalse(self.device.LoadCacheData('{"token":"foo"}'))
+
+ def testTokenMatches(self):
+ with self.assertCalls(
+ self.EnsureCacheInitialized()):
+ self.assertTrue(self.device.LoadCacheData('{"token":"TOKEN"}'))
+
+ def testDumpThenLoad(self):
+ with self.assertCalls(
+ self.EnsureCacheInitialized()):
+ data = json.loads(self.device.DumpCacheData())
+ data['token'] = 'TOKEN'
+ self.assertTrue(self.device.LoadCacheData(json.dumps(data)))
+
+
if __name__ == '__main__':
logging.getLogger().setLevel(logging.DEBUG)
unittest.main(verbosity=2)