[Android] Switch to DeviceUtils versions of Reboot and Install.

BUG=267773
NOTRY=true

Review URL: https://codereview.chromium.org/292313015

git-svn-id: http://src.chromium.org/svn/trunk/src/build@276702 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
jbudorick@chromium.org 2014-06-12 16:24:23 +00:00
Родитель e523d70dcf
Коммит f117f4656f
9 изменённых файлов: 148 добавлений и 32 удалений

Просмотреть файл

@ -13,7 +13,6 @@ import sys
from pylib import android_commands
from pylib import constants
from pylib.device import device_utils
from pylib.utils import apk_helper
def AddInstallAPKOption(option_parser):
@ -22,8 +21,8 @@ def AddInstallAPKOption(option_parser):
help=('DEPRECATED The name of the apk containing the'
' application (with the .apk extension).'))
option_parser.add_option('--apk_package',
help=('The package name used by the apk containing '
'the application.'))
help=('DEPRECATED The package name used by the apk '
'containing the application.'))
option_parser.add_option('--keep_data',
action='store_true',
default=False,
@ -74,11 +73,8 @@ def main(argv):
if not devices:
raise Exception('Error: no connected devices')
if not options.apk_package:
options.apk_package = apk_helper.GetPackageName(options.apk)
device_utils.DeviceUtils.parallel(devices).old_interface.ManagedInstall(
options.apk, options.keep_data, options.apk_package).pFinish(None)
device_utils.DeviceUtils.parallel(devices).Install(
options.apk, reinstall=options.keep_data)
if __name__ == '__main__':

Просмотреть файл

@ -28,7 +28,10 @@ def main(argv):
for device in [device_utils.DeviceUtils(serial) for serial in devices]:
if options.set_asserts != None:
if device.old_interface.SetJavaAssertsEnabled(options.set_asserts):
device.old_interface.Reboot(full_reboot=False)
# TODO(jbudorick) How to best do shell restarts after the
# android_commands refactor?
device.old_interface.RunShellCommand('stop')
device.old_interface.RunShellCommand('start')
if __name__ == '__main__':

Просмотреть файл

@ -131,7 +131,7 @@ def ProvisionDevices(options):
device.old_interface.EnableAdbRoot()
WipeDeviceData(device)
try:
device_utils.DeviceUtils.parallel(devices).old_interface.Reboot(True)
device_utils.DeviceUtils.parallel(devices).Reboot(True)
except errors.DeviceUnresponsiveError:
pass
for device_serial in devices:
@ -148,7 +148,7 @@ def ProvisionDevices(options):
device, device_settings.NETWORK_DISABLED_SETTINGS)
device.old_interface.RunShellCommandWithSU('date -u %f' % time.time())
try:
device_utils.DeviceUtils.parallel(devices).old_interface.Reboot(True)
device_utils.DeviceUtils.parallel(devices).Reboot(True)
except errors.DeviceUnresponsiveError:
pass
for device_serial in devices:
@ -186,8 +186,7 @@ def main(argv):
device = device_utils.DeviceUtils(device_serial)
WipeDeviceData(device)
try:
(device_utils.DeviceUtils.parallel(devices)
.old_interface.Reboot(True).pFinish(None))
device_utils.DeviceUtils.parallel(devices).Reboot(True)
except errors.DeviceUnresponsiveError:
pass
else:

Просмотреть файл

@ -2,8 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Provides a variety of device interactions based on adb.
"""Provides a variety of device interactions based on adb.
Eventually, this will be based on adb_wrapper.
"""
@ -15,6 +14,7 @@ import pylib.android_commands
from pylib.device import adb_wrapper
from pylib.device import decorators
from pylib.device import device_errors
from pylib.utils import apk_helper
from pylib.utils import parallelizer
_DEFAULT_TIMEOUT = 30
@ -24,7 +24,7 @@ _DEFAULT_RETRIES = 3
@decorators.WithExplicitTimeoutAndRetries(
_DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
def GetAVDs():
""" Returns a list of Android Virtual Devices.
"""Returns a list of Android Virtual Devices.
Returns:
A list containing the configured AVDs.
@ -35,7 +35,7 @@ def GetAVDs():
@decorators.WithExplicitTimeoutAndRetries(
_DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
def RestartServer():
""" Restarts the adb server.
"""Restarts the adb server.
Raises:
CommandFailedError if we fail to kill or restart the server.
@ -47,7 +47,7 @@ class DeviceUtils(object):
def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT,
default_retries=_DEFAULT_RETRIES):
""" DeviceUtils constructor.
"""DeviceUtils constructor.
Args:
device: Either a device serial, an existing AdbWrapper instance, an
@ -77,7 +77,7 @@ class DeviceUtils(object):
@decorators.WithTimeoutAndRetriesFromInstance()
def IsOnline(self, timeout=None, retries=None):
""" Checks whether the device is online.
"""Checks whether the device is online.
Args:
timeout: An integer containing the number of seconds to wait for the
@ -91,7 +91,7 @@ class DeviceUtils(object):
@decorators.WithTimeoutAndRetriesFromInstance()
def HasRoot(self, timeout=None, retries=None):
""" Checks whether or not adbd has root privileges.
"""Checks whether or not adbd has root privileges.
Args:
timeout: Same as for |IsOnline|.
@ -103,7 +103,7 @@ class DeviceUtils(object):
@decorators.WithTimeoutAndRetriesFromInstance()
def EnableRoot(self, timeout=None, retries=None):
""" Restarts adbd with root privileges.
"""Restarts adbd with root privileges.
Args:
timeout: Same as for |IsOnline|.
@ -113,11 +113,11 @@ class DeviceUtils(object):
"""
if not self.old_interface.EnableAdbRoot():
raise device_errors.CommandFailedError(
'adb root', 'Could not enable root.')
['adb', 'root'], 'Could not enable root.')
@decorators.WithTimeoutAndRetriesFromInstance()
def GetExternalStoragePath(self, timeout=None, retries=None):
""" Get the device's path to its SD card.
"""Get the device's path to its SD card.
Args:
timeout: Same as for |IsOnline|.
@ -128,11 +128,12 @@ class DeviceUtils(object):
try:
return self.old_interface.GetExternalStorage()
except AssertionError as e:
raise device_errors.CommandFailedError(str(e))
raise device_errors.CommandFailedError(
['adb', 'shell', 'echo', '$EXTERNAL_STORAGE'], str(e))
@decorators.WithTimeoutAndRetriesFromInstance()
def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None):
""" Wait for the device to fully boot.
"""Wait for the device to fully boot.
This means waiting for the device to boot, the package manager to be
available, and the SD card to be ready. It can optionally mean waiting
@ -146,6 +147,25 @@ class DeviceUtils(object):
CommandTimeoutError if one of the component waits times out.
DeviceUnreachableError if the device becomes unresponsive.
"""
self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout)
def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None):
""" Implementation of WaitUntilFullyBooted.
This is split from WaitUntilFullyBooted to allow other DeviceUtils methods
to call WaitUntilFullyBooted without spawning a new timeout thread.
TODO(jbudorick) Remove the timeout parameter once this is no longer
implemented via AndroidCommands.
Args:
wifi: Same as for |WaitUntilFullyBooted|.
timeout: Same as for |IsOnline|.
Raises:
Same as for |WaitUntilFullyBooted|.
"""
if timeout is None:
timeout = self._default_timeout
self.old_interface.WaitForSystemBootCompleted(timeout)
self.old_interface.WaitForDevicePm()
self.old_interface.WaitForSdCardReady(timeout)
@ -154,13 +174,71 @@ class DeviceUtils(object):
self.old_interface.RunShellCommand('dumpsys wifi')):
time.sleep(0.1)
@decorators.WithTimeoutAndRetriesDefaults(
10 * _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
def Reboot(self, block=True, timeout=None, retries=None):
"""Reboot the device.
Args:
block: A boolean indicating if we should wait for the reboot to complete.
timeout: Same as for |IsOnline|.
retries: Same as for |IsOnline|.
"""
self.old_interface.Reboot()
if block:
self._WaitUntilFullyBootedImpl(timeout=timeout)
@decorators.WithTimeoutAndRetriesDefaults(
4 * _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
def Install(self, apk_path, reinstall=False, timeout=None, retries=None):
"""Install an APK.
Noop if an identical APK is already installed.
Args:
apk_path: A string containing the path to the APK to install.
reinstall: A boolean indicating if we should keep any existing app data.
timeout: Same as for |IsOnline|.
retries: Same as for |IsOnline|.
Raises:
CommandFailedError if the installation fails.
CommandTimeoutError if the installation times out.
"""
package_name = apk_helper.GetPackageName(apk_path)
device_path = self.old_interface.GetApplicationPath(package_name)
if device_path is not None:
files_changed = self.old_interface.GetFilesChanged(
apk_path, device_path, ignore_filenames=True)
if len(files_changed) > 0:
should_install = True
if not reinstall:
out = self.old_interface.Uninstall(package_name)
for line in out.splitlines():
if 'Failure' in line:
raise device_errors.CommandFailedError(
['adb', 'uninstall', package_name], line.strip())
else:
should_install = False
else:
should_install = True
if should_install:
try:
out = self.old_interface.Install(apk_path, reinstall=reinstall)
for line in out.splitlines():
if 'Failure' in line:
raise device_errors.CommandFailedError(
['adb', 'install', apk_path], line.strip())
except AssertionError as e:
raise device_errors.CommandFailedError(
['adb', 'install', apk_path], str(e))
def __str__(self):
"""Returns the device serial."""
return self.old_interface.GetDevice()
@staticmethod
def parallel(devices=None, async=False):
""" Creates a Parallelizer to operate over the provided list of devices.
"""Creates a Parallelizer to operate over the provided list of devices.
If |devices| is either |None| or an empty list, the Parallelizer will
operate over all attached devices.

Просмотреть файл

@ -9,6 +9,7 @@ Unit tests for the contents of device_utils.py (mostly DeviceUtils).
# pylint: disable=W0212
# pylint: disable=W0613
import functools
import random
import time
import unittest
@ -20,10 +21,20 @@ from pylib.device import device_errors
from pylib.device import device_utils
def TestRequiresDevice(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
if len(adb_wrapper.AdbWrapper.GetDevices()) > 0:
return f(*args, **kwargs)
return unittest.skip('Test requires an attached device.')
return wrapper
class DeviceUtilsTest(unittest.TestCase):
def testGetAVDs(self):
pass
@TestRequiresDevice
def testRestartServerNotRunning(self):
self.assertEqual(0, cmd_helper.RunCmd(['pkill', 'adb']),
msg='Unable to kill adb during setup.')
@ -32,6 +43,7 @@ class DeviceUtilsTest(unittest.TestCase):
device_utils.RestartServer()
self.assertEqual(0, cmd_helper.RunCmd(['pgrep', 'adb']))
@TestRequiresDevice
def testRestartServerAlreadyRunning(self):
if cmd_helper.RunCmd(['pgrep', 'adb']) != 0:
device_utils.RestartServer()
@ -89,12 +101,14 @@ class DeviceUtilsTest(unittest.TestCase):
if serial not in used_devices:
return serial
@TestRequiresDevice
def testIsOnline(self):
d = device_utils.DeviceUtils(self._getTestAdbWrapper())
self.assertTrue(d is None or d.IsOnline())
d = device_utils.DeviceUtils(self._getUnusedSerial())
self.assertFalse(d.IsOnline())
@TestRequiresDevice
def testHasRoot(self):
a = self._getTestAdbWrapper()
d = device_utils.DeviceUtils(a)
@ -112,6 +126,7 @@ class DeviceUtilsTest(unittest.TestCase):
else:
self.assertTrue(d.HasRoot())
@TestRequiresDevice
def testEnableRoot(self):
a = self._getTestAdbWrapper()
d = device_utils.DeviceUtils(a)
@ -148,6 +163,7 @@ class DeviceUtilsTest(unittest.TestCase):
d.EnableRoot()
self.assertTrue(d.HasRoot())
@TestRequiresDevice
def testGetExternalStorage(self):
a = self._getTestAdbWrapper()
d = device_utils.DeviceUtils(a)
@ -156,6 +172,7 @@ class DeviceUtilsTest(unittest.TestCase):
if actual_external_storage and len(actual_external_storage) != 0:
self.assertEquals(actual_external_storage, d.GetExternalStoragePath())
@TestRequiresDevice
def testWaitUntilFullyBooted(self):
a = self._getTestAdbWrapper()
d = device_utils.DeviceUtils(a)
@ -172,7 +189,25 @@ class DeviceUtilsTest(unittest.TestCase):
self.assertTrue(
'Wi-Fi is enabled' in a.Shell('dumpsys wifi').splitlines())
@TestRequiresDevice
def testBlockingReboot(self):
a = self._getTestAdbWrapper()
d = device_utils.DeviceUtils(a)
old_boot_time = a.Shell('getprop ro.runtime.firstboot').strip()
if old_boot_time and len(old_boot_time):
d.Reboot(block=True, timeout=120)
self.assertNotEquals(old_boot_time,
a.Shell('getprop ro.runtime.firstboot').strip())
self.assertEquals(
'1', a.Shell('getprop sys.boot_completed').splitlines()[0])
self.assertTrue(
a.Shell('pm path android').splitlines()[0].startswith('package:'))
self.assertTrue(a.Shell('ls $EXTERNAL_STORAGE'))
else:
self.skipTest("No 'ro.runtime.firstboot' property on %s." % str(a))
if __name__ == '__main__':
unittest.main(verbosity=2, buffer=True)
unittest.main(verbosity=2)

Просмотреть файл

@ -131,5 +131,4 @@ class TestPackageApk(TestPackage):
#override
def Install(self, device):
self.tool.CopyFiles()
device.old_interface.ManagedInstall(
self.suite_path, False, package_name=self._package_info.package)
device.Install(self.suite_path)

Просмотреть файл

@ -34,6 +34,5 @@ class TestPackage(test_jar.TestJar):
# Override.
def Install(self, device):
device.old_interface.ManagedInstall(
self.GetApkPath(), package_name=self.GetPackageName())
device.Install(self.GetApkPath())

Просмотреть файл

@ -152,7 +152,10 @@ class TestRunner(base_test_runner.BaseTestRunner):
str(self.device))
else:
if self.device.old_interface.SetJavaAssertsEnabled(True):
self.device.old_interface.Reboot(full_reboot=False)
# TODO(jbudorick) How to best do shell restart after the
# android_commands refactor?
self.device.old_interface.RunShellCommand('stop')
self.device.old_interface.RunShellCommand('start')
# We give different default value to launch HTTP server based on shard index
# because it may have race condition when multiple processes are trying to

Просмотреть файл

@ -29,6 +29,7 @@ def _SaveAppData(device, package_name, from_apk=None, data_dir=None):
if from_apk:
logging.info('Installing %s...', from_apk)
# TODO(jbudorick) Switch to AdbWrapper.Install on the impl switch.
output = device.old_interface.Install(from_apk, reinstall=True)
if 'Success' not in output:
raise Exception('Unable to install %s. output: %s' % (from_apk, output))
@ -47,6 +48,7 @@ def _VerifyAppUpdate(device, to_apk, app_data, from_apk=None):
if from_apk:
logging.info('Installing %s...', from_apk)
# TODO(jbudorick) Switch to AdbWrapper.Install on the impl switch.
output = device.old_interface.Install(from_apk, reinstall=True)
if 'Success' not in output:
raise Exception('Unable to install %s. output: %s' % (from_apk, output))
@ -57,6 +59,7 @@ def _VerifyAppUpdate(device, to_apk, app_data, from_apk=None):
logging.info('Verifying that %s cannot be installed side-by-side...',
to_apk)
# TODO(jbudorick) Switch to AdbWrapper.Install on the impl switch.
output = device.old_interface.Install(to_apk)
if 'INSTALL_FAILED_ALREADY_EXISTS' not in output:
if 'Success' in output:
@ -65,6 +68,7 @@ def _VerifyAppUpdate(device, to_apk, app_data, from_apk=None):
raise Exception(output)
logging.info('Verifying that %s can be overinstalled...', to_apk)
# TODO(jbudorick) Switch to AdbWrapper.Install on the impl switch.
output = device.old_interface.Install(to_apk, reinstall=True)
if 'Success' not in output:
raise Exception('Unable to install %s.\n output: %s' % (to_apk, output))