[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:
Родитель
e523d70dcf
Коммит
f117f4656f
|
@ -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))
|
||||
|
|
Загрузка…
Ссылка в новой задаче