1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-22 04:49:00 +00:00

framework/workload: Refactor apk resolution

Now allows a `prefer_host_package` parameter to be set to control
whether a package located on the host system (`True`) or on the target
(`False`) should be favoured during resolution.
This commit is contained in:
Marc Bonnici 2018-03-19 10:21:37 +00:00 committed by setrofim
parent 1cb8f1670a
commit daa1959fd1

View File

@ -214,7 +214,16 @@ class ApkWorkload(Workload):
description=""" description="""
If ``True``, workload will check that the APK matches the target If ``True``, workload will check that the APK matches the target
device ABI, otherwise any suitable APK found will be used. device ABI, otherwise any suitable APK found will be used.
""") """),
Parameter('prefer_host_package', kind=bool,
default=True,
aliases=['check_apk'],
description="""
If ``True`` then a package found on the host
will be preferred if it is a valid version and ABI, if not it
will fall back to the version on the target if available. If
``False`` then the version on the target is preferred instead.
"""),
] ]
@property @property
@ -237,7 +246,8 @@ class ApkWorkload(Workload):
force_install=self.force_install, force_install=self.force_install,
install_timeout=self.install_timeout, install_timeout=self.install_timeout,
uninstall=self.uninstall, uninstall=self.uninstall,
exact_abi=self.exact_abi) exact_abi=self.exact_abi,
prefer_host_package=self.prefer_host_package)
@once_per_instance @once_per_instance
def initialize(self, context): def initialize(self, context):
@ -614,7 +624,7 @@ class PackageHandler(object):
def __init__(self, owner, install_timeout=300, version=None, variant=None, def __init__(self, owner, install_timeout=300, version=None, variant=None,
package_name=None, strict=False, force_install=False, uninstall=False, package_name=None, strict=False, force_install=False, uninstall=False,
exact_abi=False): exact_abi=False, prefer_host_package=True):
self.logger = logging.getLogger('apk') self.logger = logging.getLogger('apk')
self.owner = owner self.owner = owner
self.target = self.owner.target self.target = self.owner.target
@ -626,6 +636,7 @@ class PackageHandler(object):
self.force_install = force_install self.force_install = force_install
self.uninstall = uninstall self.uninstall = uninstall
self.exact_abi = exact_abi self.exact_abi = exact_abi
self.prefer_host_package = prefer_host_package
self.apk_file = None self.apk_file = None
self.apk_info = None self.apk_info = None
self.apk_version = None self.apk_version = None
@ -646,6 +657,35 @@ class PackageHandler(object):
msg = 'Cannot Resolve package; No package name(s) specified' msg = 'Cannot Resolve package; No package name(s) specified'
raise WorkloadError(msg) raise WorkloadError(msg)
self.error_msg = None
if self.prefer_host_package:
self.resolve_package_from_host(context)
if not self.apk_file:
self.resolve_package_from_target(context)
else:
self.resolve_package_from_target(context)
if not self.apk_file:
self.resolve_package_from_host(context)
if self.apk_file:
self.apk_info = ApkInfo(self.apk_file)
else:
if self.error_msg:
raise WorkloadError(self.error_msg)
else:
if self.package_name:
message = 'Package "{package}" not found for workload {name} '\
'on host or target.'
elif self.version:
message = 'No matching package found for workload {name} '\
'(version {version}) on host or target.'
else:
message = 'No matching package found for workload {name} on host or target'
raise WorkloadError(message.format(name=self.owner.name, version=self.version,
package=self.package_name))
def resolve_package_from_host(self, context):
self.logger.debug('Resolving package on host system')
if self.package_name: if self.package_name:
self.apk_file = context.resolver.get(ApkFile(self.owner, self.apk_file = context.resolver.get(ApkFile(self.owner,
variant=self.variant, variant=self.variant,
@ -657,35 +697,26 @@ class PackageHandler(object):
else: else:
available_packages = [] available_packages = []
for package in self.owner.package_names: for package in self.owner.package_names:
available_packages.append(context.resolver.get(ApkFile(self.owner, apk_file = context.resolver.get(ApkFile(self.owner,
variant=self.variant, variant=self.variant,
version=self.version, version=self.version,
package=package, package=package,
exact_abi=self.exact_abi, exact_abi=self.exact_abi,
supported_abi=self.supported_abi), supported_abi=self.supported_abi),
strict=self.strict)) strict=self.strict)
if apk_file:
available_packages.append(apk_file)
if len(available_packages) == 1: if len(available_packages) == 1:
self.apk_file = available_packages[0] self.apk_file = available_packages[0]
elif len(available_packages) > 1: elif len(available_packages) > 1:
msg = 'Multiple matching packages found for "{}" on host: {}' msg = 'Multiple matching packages found for "{}" on host: {}'
raise WorkloadError(msg.format(self.owner, available_packages)) self.error_msg = msg.format(self.owner, available_packages)
if self.apk_file:
self.apk_info = ApkInfo(self.apk_file)
if self.version:
installed_version = self.target.get_package_version(self.apk_info.package)
host_version = self.apk_info.version_name
if (installed_version and installed_version != host_version and
loose_version_matching(self.version, installed_version)):
msg = 'Multiple matching packages found for {}; host version: {}, device version: {}'
raise WorkloadError(msg.format(self.owner, host_version, installed_version))
else:
self.resolve_package_from_target(context)
def resolve_package_from_target(self, context): def resolve_package_from_target(self, context):
self.logger.debug('Resolving package on target')
if self.package_name: if self.package_name:
if not self.target.package_is_installed(self.package_name): if not self.target.package_is_installed(self.package_name):
msg = 'Package "{}" cannot be found on the host or device' return
raise WorkloadError(msg.format(self.package_name))
else: else:
installed_versions = [] installed_versions = []
for package in self.owner.package_names: for package in self.owner.package_names:
@ -693,32 +724,25 @@ class PackageHandler(object):
installed_versions.append(package) installed_versions.append(package)
if self.version: if self.version:
matching_packages = []
for package in installed_versions: for package in installed_versions:
package_version = self.target.get_package_version(package) package_version = self.target.get_package_version(package)
if loose_version_matching(self.version, package_version): if loose_version_matching(self.version, package_version):
self.package_name = package matching_packages.append(package)
break if len(matching_packages) == 1:
self.package_name = matching_packages[0]
elif len(matching_packages) > 1:
msg = 'Multiple matches for version "{}" found on device.'
self.error_msg = msg.format(self.version)
else: else:
if len(installed_versions) == 1: if len(installed_versions) == 1:
self.package_name = installed_versions[0] self.package_name = installed_versions[0]
elif len(installed_versions) > 1: elif len(installed_versions) > 1:
msg = 'Package version not set and multiple versions found on device' self.error_msg = 'Package version not set and multiple versions found on device.'
raise WorkloadError(msg)
if not self.package_name: if self.package_name:
if self.version: self.logger.debug('Found matching package on target; Pulling to host.')
message = 'No matching package found for workload {name} (version {version})' self.apk_file = self.pull_apk(self.package_name)
else:
message = 'No matching package found for workload {name}'
raise WorkloadError(message.format(name=self.owner.name, version=self.version))
self.pull_apk(self.package_name)
self.apk_file = context.resolver.get(ApkFile(self.owner,
variant=self.variant,
version=self.version,
package=self.package_name),
strict=self.strict)
self.apk_info = ApkInfo(self.apk_file)
def initialize_package(self, context): def initialize_package(self, context):
installed_version = self.target.get_package_version(self.apk_info.package) installed_version = self.target.get_package_version(self.apk_info.package)
@ -733,7 +757,7 @@ class PackageHandler(object):
self.logger.debug(message.format(self.owner.name, host_version)) self.logger.debug(message.format(self.owner.name, host_version))
self.force_install = True # pylint: disable=attribute-defined-outside-init self.force_install = True # pylint: disable=attribute-defined-outside-init
else: else:
message = '{} version {} found on both device and host.' message = '{} version {} present on both device and host.'
self.logger.debug(message.format(self.owner.name, host_version)) self.logger.debug(message.format(self.owner.name, host_version))
if self.force_install: if self.force_install:
if installed_version: if installed_version: