1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-06 19:01:15 +01:00

Check APK version and ABI when installing

- Check the APK's versionName property against the workload's
  expected version if specified
- If workload specifies check_abi param, try to get APK from
  ABI-specific path on the host
- Add variant_name param to APK resource-getter for backwards
  compatibility of dex2oat and peacekeeper
This commit is contained in:
muendelezaji 2016-06-22 19:34:04 +01:00
parent fab6a977aa
commit bb33123b17
6 changed files with 76 additions and 18 deletions

View File

@ -362,9 +362,9 @@ class AndroidDevice(BaseLinuxDevice): # pylint: disable=W0223
if ext == '.apk':
flags = []
if replace:
flags.append('-r') # Replace existing APK
flags.append('-r') # Replace existing APK
if self.get_sdk_version() >= 23:
flags.append('-g') # Grant all runtime permissions
flags.append('-g') # Grant all runtime permissions
self.logger.debug("Replace APK = {}, ADB flags = '{}'".format(replace, ' '.join(flags)))
return adb_command(self.adb_name, "install {} '{}'".format(' '.join(flags), filepath), timeout=timeout)
else:

View File

@ -34,3 +34,10 @@ class JarFile(FileResource):
class ApkFile(FileResource):
name = 'apk'
def __init__(self, owner, platform=None):
super(ApkFile, self).__init__(owner)
self.platform = platform
def __str__(self):
return '<{}\'s {} APK>'.format(self.owner, self.platform)

View File

@ -20,6 +20,7 @@ import time
from wlauto.core.extension import Parameter
from wlauto.core.workload import Workload
from wlauto.core.resource import NO_ONE
from wlauto.common.android.resources import ApkFile
from wlauto.common.resources import ExtensionAsset, Executable
from wlauto.exceptions import WorkloadError, ResourceError, ConfigError
from wlauto.utils.android import ApkInfo, ANDROID_NORMAL_PERMISSIONS
@ -160,6 +161,11 @@ class ApkWorkload(Workload):
'''),
Parameter('uninstall_apk', kind=boolean, default=False,
description='If ``True``, will uninstall workload\'s APK as part of teardown.'),
Parameter('check_abi', kind=bool, default=False,
description='''
If ``True``, workload will check that the APK matches the target
device ABI, otherwise any APK found will be used.
'''),
]
def __init__(self, device, _call_super=True, **kwargs):
@ -169,12 +175,14 @@ class ApkWorkload(Workload):
self.apk_version = None
self.logcat_log = None
def init_resources(self, context):
self.apk_file = context.resolver.get(wlauto.common.android.resources.ApkFile(self),
def initialize(self, context):
# Get APK for the correct version and device ABI
self.apk_file = context.resolver.get(ApkFile(self, self.device.abi),
version=getattr(self, 'version', None),
check_abi=getattr(self, 'check_abi', False),
variant_name=getattr(self, 'variant_name', None),
strict=self.check_apk)
def validate(self):
# Validate the APK
if self.check_apk:
if not self.apk_file:
raise WorkloadError('No APK file found for workload {}.'.format(self.name))
@ -223,7 +231,7 @@ class ApkWorkload(Workload):
if installed_version:
self.device.uninstall(self.package)
# It's possible that the uninstall above fails, which might result in a warning
# and/or failure during installation. Hower execution should proceed, so need
# and/or failure during installation. However execution should proceed, so need
# to make sure that the right apk_vesion is reported in the end.
if self.install_apk(context):
self.apk_version = host_version

View File

@ -30,6 +30,7 @@ import requests
from wlauto import ResourceGetter, GetterPriority, Parameter, NO_ONE, settings, __file__ as __base_filepath
from wlauto.exceptions import ResourceError
from wlauto.utils.android import ApkInfo
from wlauto.utils.misc import ensure_directory_exists as _d, ensure_file_directory_exists as _f, sha256, urljoin
from wlauto.utils.types import boolean
@ -61,9 +62,11 @@ class PackageFileGetter(ResourceGetter):
class EnvironmentFileGetter(ResourceGetter):
name = 'environment_file'
description = """Looks for exactly one file with the specified extension in the owner's directory. If a version
description = """
Looks for exactly one file with the specified extension in the owner's directory. If a version
is specified on invocation of get, it will filter the discovered file based on that version.
Versions are treated as case-insensitive."""
Versions are treated as case-insensitive.
"""
extension = None
@ -102,6 +105,22 @@ class PackageApkGetter(PackageFileGetter):
name = 'package_apk'
extension = 'apk'
description = """
Uses the same dependency resolution mechanism as ``PackageFileGetter`` with one addition.
If an ABI is specified in the resource request, then the getter will try to locate the file in
the ABI-specific folder in the form ``<root>/apk/<abi>/<apk_name>``. Where ``root`` is the base
resource location e.g. ``~/.workload_automation/dependencies/<extension_name>`` and ``<abi>``
is the ABI for which the APK has been compiled, as returned by ``resource.platform``.
"""
def get(self, resource, **kwargs):
resource_dir = os.path.dirname(sys.modules[resource.owner.__module__].__file__)
version = kwargs.get('version')
variant = kwargs.get('variant_name')
if kwargs.get('check_abi', False):
resource_dir = os.path.join(resource_dir, self.extension, resource.platform)
return get_from_location_by_extension(resource, resource_dir, self.extension, version, variant=variant)
class PackageJarGetter(PackageFileGetter):
name = 'package_jar'
@ -120,6 +139,22 @@ class EnvironmentApkGetter(EnvironmentFileGetter):
name = 'environment_apk'
extension = 'apk'
description = """
Uses the same dependency resolution mechanism as ``EnvironmentFileGetter`` with one addition.
If an ABI is specified in the resource request, then the getter will try to locate the file in
the ABI-specific folder in the form ``<root>/apk/<abi>/<apk_name>``. Where ``root`` is the base
resource location e.g. ``~/.workload_automation/dependencies/<extension_name>`` and ``<abi>``
is the ABI for which the APK has been compiled, as returned by ``resource.platform``.
"""
def get(self, resource, **kwargs):
resource_dir = resource.owner.dependencies_directory
version = kwargs.get('version')
variant = kwargs.get('variant_name')
if kwargs.get('check_abi', False):
resource_dir = os.path.join(resource_dir, self.extension, resource.platform)
return get_from_location_by_extension(resource, resource_dir, self.extension, version, variant=variant)
class EnvironmentJarGetter(EnvironmentFileGetter):
name = 'environment_jar'
@ -427,6 +462,10 @@ class RemoteFilerGetter(ResourceGetter):
if resource.owner:
remote_path = os.path.join(self.remote_path, resource.owner.name)
local_path = os.path.join(settings.environment_root, '__filer', resource.owner.dependencies_directory)
if resource.name == 'apk' and kwargs.get('check_abi', False):
local_path = os.path.join(local_path, 'apk', resource.platform)
message = 'resource={}, version={}, remote_path={}, local_path={}'
self.logger.debug(message.format(resource, version, remote_path, local_path))
return self.try_get_resource(resource, version, remote_path, local_path)
else:
result = None
@ -489,24 +528,28 @@ class RemoteFilerGetter(ResourceGetter):
# Utility functions
def get_from_location_by_extension(resource, location, extension, version=None):
def get_from_location_by_extension(resource, location, extension, version=None, variant=None):
try:
found_files = [os.path.join(location, f) for f in os.listdir(location)]
except OSError:
return None
try:
return get_from_list_by_extension(resource, found_files, extension, version)
return get_from_list_by_extension(resource, found_files, extension, version, variant=variant)
except ResourceError:
raise ResourceError('More than one .{} found in {} for {}.'.format(extension,
location,
resource.owner.name))
def get_from_list_by_extension(resource, filelist, extension, version=None):
filelist = [ff for ff in filelist
if os.path.splitext(ff)[1].lower().endswith(extension)]
def get_from_list_by_extension(resource, filelist, extension, version=None, variant=None):
filelist = [ff for ff in filelist if os.path.splitext(ff)[1].lower().endswith(extension)]
if variant:
filelist = [ff for ff in filelist if variant.lower() in os.path.basename(ff).lower()]
if version:
filelist = [ff for ff in filelist if version.lower() in os.path.basename(ff).lower()]
if extension == 'apk':
filelist = [ff for ff in filelist if version.lower() in ApkInfo(ff).version_name.lower()]
else:
filelist = [ff for ff in filelist if version.lower() in os.path.basename(ff).lower()]
if len(filelist) == 1:
return filelist[0]
elif not filelist:

View File

@ -53,7 +53,8 @@ class Dex2oatBenchmark(Workload):
def init_resources(self, context):
# TODO: find a better APK to use for this.
peacekeeper = ExtensionLoader().get_workload('peacekeeper', self.device)
self.apk_file = context.resolver.get(wlauto.common.android.resources.ApkFile(peacekeeper), version='chrome')
self.apk_file = context.resolver.get(wlauto.common.android.resources.ApkFile(peacekeeper),
variant_name='chrome')
self.package = ApkInfo(self.apk_file).package
def setup(self, context):
@ -119,4 +120,3 @@ class Dex2oatBenchmark(Workload):
def teardown(self, context):
self.device.delete_file(self.on_device_oat)

View File

@ -63,7 +63,7 @@ class Peacekeeper(AndroidUiAutoBenchmark):
def __init__(self, device, **kwargs):
super(Peacekeeper, self).__init__(device, **kwargs)
self.version = self.browser
self.variant_name = self.browser
def update_result(self, context):
super(Peacekeeper, self).update_result(context)