1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-20 20:09:11 +00:00

Workload: Fixes apk resolution when not present on host.

Previously apk resolution would fail if the application apk was not present on
device as this was used to retrieve information e.g. the package name. To work
around this, the resolution process now supports searching the device for either
a list of package names retrieved from the workload or as a parameter passed by
the user at runtime and if found on the device will be pulled to the host to
perform its analysis.
This commit is contained in:
Marc Bonnici 2017-06-07 17:45:27 +01:00
parent 0c3e1c2526
commit 4523fb74b6

View File

@ -14,6 +14,7 @@
#
import logging
import os
import re
import time
from wa.framework.plugin import TargetedPlugin
@ -24,6 +25,7 @@ from wa.utils.revent import ReventRecorder
from wa.utils.exec_control import once
from devlib.utils.android import ApkInfo
from devlib.exception import TargetError
class Workload(TargetedPlugin):
@ -101,6 +103,7 @@ class ApkUIWorkload(Workload):
# May be optionally overwritten by subclasses
# Times are in seconds
loading_time = 10
package_names = []
def __init__(self, target, **kwargs):
super(ApkUIWorkload, self).__init__(target, **kwargs)
@ -108,7 +111,6 @@ class ApkUIWorkload(Workload):
self.gui = None
def init_resources(self, context):
self.apk.init_resources(context.resolver)
self.gui.init_resources(context.resolver)
self.gui.init_commands()
@ -336,13 +338,14 @@ class ReventGUI(object):
class PackageHandler(object):
def __init__(self, owner, install_timeout=300, version=None, variant=None,
strict=True, force_install=False, uninstall=False):
package=None, strict=False, force_install=False, uninstall=False):
self.logger = logging.getLogger('apk')
self.owner = owner
self.target = self.owner.target
self.install_timeout = install_timeout
self.version = version
self.variant = variant
self.package = package
self.strict = strict
self.force_install = force_install
self.uninstall = uninstall
@ -351,49 +354,78 @@ class PackageHandler(object):
self.apk_version = None
self.logcat_log = None
def init_resources(self, resolver):
self.apk_file = resolver.get(ApkFile(self.owner,
variant=self.variant,
version=self.version),
strict=self.strict)
self.apk_info = ApkInfo(self.apk_file)
def initialize(self, context):
self.resolve_package(context)
self.initialize_package(context)
def setup(self, context):
self.initialize_package(context)
self.start_activity()
self.target.execute('am kill-all') # kill all *background* activities
self.target.clear_logcat()
def resolve_package(self, context):
self.apk_file = context.resolver.get(ApkFile(self.owner,
variant=self.variant,
version=self.version,
package=self.package),
strict=self.strict)
if self.apk_file:
self.apk_info = ApkInfo(self.apk_file)
else:
if not self.owner.package_names and not self.package:
msg = 'No package name(s) specified and no matching APK file found on host'
raise WorkloadError(msg)
self.resolve_package_from_target(context)
def resolve_package_from_target(self, context):
if self.package:
if not self.target.package_is_installed(self.package):
msg = 'Package "{}" cannot be found on the host or device'
raise WorkloadError(msg.format(self.package))
else:
installed_versions = []
for package in self.owner.package_names:
if self.target.package_is_installed(package):
installed_versions.append(package)
if self.version:
for package in installed_versions:
if self.version == self.target.get_package_version(package):
self.package = package
break
else:
if len(installed_versions) == 1:
self.package = installed_versions[0]
else:
msg = 'Package version not set and multiple versions found on device'
raise WorkloadError(msg)
if not self.package:
raise WorkloadError('No matching package found')
self.pull_apk(self.package)
self.apk_file = context.resolver.get(ApkFile(self.owner,
variant=self.variant,
version=self.version,
package=self.package),
strict=self.strict)
self.apk_info = ApkInfo(self.apk_file)
def initialize_package(self, context):
installed_version = self.target.get_package_version(self.apk_info.package)
if self.strict:
self.initialize_with_host_apk(context, installed_version)
else:
if not installed_version:
message = '{} not found found on the device and check_apk is set '\
'to "False" so host version was not checked.'
raise WorkloadError(message.format(self.apk_info.package))
message = 'Version {} installed on device; skipping host APK check.'
self.logger.debug(message.format(installed_version))
self.reset(context)
self.version = installed_version
def initialize_with_host_apk(self, context, installed_version):
host_version = self.apk_info.version_name
if installed_version != host_version:
if installed_version:
message = '{} host version: {}, device version: {}; re-installing...'
self.logger.debug(message.format(os.path.basename(self.apk_file),
host_version, installed_version))
self.logger.debug(message.format(self.owner.name, host_version,
installed_version))
else:
message = '{} host version: {}, not found on device; installing...'
self.logger.debug(message.format(os.path.basename(self.apk_file),
host_version))
self.logger.debug(message.format(self.owner.name, host_version))
self.force_install = True # pylint: disable=attribute-defined-outside-init
else:
message = '{} version {} found on both device and host.'
self.logger.debug(message.format(os.path.basename(self.apk_file),
host_version))
self.logger.debug(message.format(self.owner.name, host_version))
if self.force_install:
if installed_version:
self.target.uninstall_package(self.apk_info.package)
@ -427,6 +459,14 @@ class PackageHandler(object):
else:
self.logger.debug(output)
def pull_apk(self, package):
if not self.target.package_is_installed(package):
message = 'Cannot retrieve "{}" as not installed on Target'
raise WorkloadError(message.format(package))
package_info = self.target.execute('pm list packages -f {}'.format(package))
apk_path = re.match('package:(.*)=', package_info).group(1)
self.target.pull(apk_path, self.owner.dependencies_directory)
def teardown(self):
self.target.execute('am force-stop {}'.format(self.apk_info.package))
if self.uninstall: