mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-11-04 09:02:12 +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:
		@@ -214,7 +214,16 @@ class ApkWorkload(Workload):
 | 
			
		||||
                  description="""
 | 
			
		||||
                  If ``True``, workload will check that the APK matches the target
 | 
			
		||||
                  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
 | 
			
		||||
@@ -237,7 +246,8 @@ class ApkWorkload(Workload):
 | 
			
		||||
                                  force_install=self.force_install,
 | 
			
		||||
                                  install_timeout=self.install_timeout,
 | 
			
		||||
                                  uninstall=self.uninstall,
 | 
			
		||||
                                  exact_abi=self.exact_abi)
 | 
			
		||||
                                  exact_abi=self.exact_abi,
 | 
			
		||||
                                  prefer_host_package=self.prefer_host_package)
 | 
			
		||||
 | 
			
		||||
    @once_per_instance
 | 
			
		||||
    def initialize(self, context):
 | 
			
		||||
@@ -614,7 +624,7 @@ class PackageHandler(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, owner, install_timeout=300, version=None, variant=None,
 | 
			
		||||
                 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.owner = owner
 | 
			
		||||
        self.target = self.owner.target
 | 
			
		||||
@@ -626,6 +636,7 @@ class PackageHandler(object):
 | 
			
		||||
        self.force_install = force_install
 | 
			
		||||
        self.uninstall = uninstall
 | 
			
		||||
        self.exact_abi = exact_abi
 | 
			
		||||
        self.prefer_host_package = prefer_host_package
 | 
			
		||||
        self.apk_file = None
 | 
			
		||||
        self.apk_info = None
 | 
			
		||||
        self.apk_version = None
 | 
			
		||||
@@ -646,6 +657,35 @@ class PackageHandler(object):
 | 
			
		||||
            msg = 'Cannot Resolve package; No package name(s) specified'
 | 
			
		||||
            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:
 | 
			
		||||
            self.apk_file = context.resolver.get(ApkFile(self.owner,
 | 
			
		||||
                                                         variant=self.variant,
 | 
			
		||||
@@ -657,35 +697,26 @@ class PackageHandler(object):
 | 
			
		||||
        else:
 | 
			
		||||
            available_packages = []
 | 
			
		||||
            for package in self.owner.package_names:
 | 
			
		||||
                available_packages.append(context.resolver.get(ApkFile(self.owner,
 | 
			
		||||
                                                                       variant=self.variant,
 | 
			
		||||
                                                                       version=self.version,
 | 
			
		||||
                                                                       package=package,
 | 
			
		||||
                                                                       exact_abi=self.exact_abi,
 | 
			
		||||
                                                                       supported_abi=self.supported_abi),
 | 
			
		||||
                                                               strict=self.strict))
 | 
			
		||||
                apk_file = context.resolver.get(ApkFile(self.owner,
 | 
			
		||||
                                                        variant=self.variant,
 | 
			
		||||
                                                        version=self.version,
 | 
			
		||||
                                                        package=package,
 | 
			
		||||
                                                        exact_abi=self.exact_abi,
 | 
			
		||||
                                                        supported_abi=self.supported_abi),
 | 
			
		||||
                                                strict=self.strict)
 | 
			
		||||
                if apk_file:
 | 
			
		||||
                    available_packages.append(apk_file)
 | 
			
		||||
            if len(available_packages) == 1:
 | 
			
		||||
                self.apk_file = available_packages[0]
 | 
			
		||||
            elif len(available_packages) > 1:
 | 
			
		||||
                msg = 'Multiple matching packages found for "{}" on host: {}'
 | 
			
		||||
                raise WorkloadError(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)
 | 
			
		||||
                self.error_msg = msg.format(self.owner, available_packages)
 | 
			
		||||
 | 
			
		||||
    def resolve_package_from_target(self, context):
 | 
			
		||||
        self.logger.debug('Resolving package on target')
 | 
			
		||||
        if self.package_name:
 | 
			
		||||
            if not self.target.package_is_installed(self.package_name):
 | 
			
		||||
                msg = 'Package "{}" cannot be found on the host or device'
 | 
			
		||||
                raise WorkloadError(msg.format(self.package_name))
 | 
			
		||||
                return
 | 
			
		||||
        else:
 | 
			
		||||
            installed_versions = []
 | 
			
		||||
            for package in self.owner.package_names:
 | 
			
		||||
@@ -693,32 +724,25 @@ class PackageHandler(object):
 | 
			
		||||
                    installed_versions.append(package)
 | 
			
		||||
 | 
			
		||||
            if self.version:
 | 
			
		||||
                matching_packages = []
 | 
			
		||||
                for package in installed_versions:
 | 
			
		||||
                    package_version = self.target.get_package_version(package)
 | 
			
		||||
                    if loose_version_matching(self.version, package_version):
 | 
			
		||||
                        self.package_name = package
 | 
			
		||||
                        break
 | 
			
		||||
                        matching_packages.append(package)
 | 
			
		||||
                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:
 | 
			
		||||
                if len(installed_versions) == 1:
 | 
			
		||||
                    self.package_name = installed_versions[0]
 | 
			
		||||
                elif len(installed_versions) > 1:
 | 
			
		||||
                    msg = 'Package version not set and multiple versions found on device'
 | 
			
		||||
                    raise WorkloadError(msg)
 | 
			
		||||
                   self.error_msg = 'Package version not set and multiple versions found on device.'
 | 
			
		||||
 | 
			
		||||
            if not self.package_name:
 | 
			
		||||
                if self.version:
 | 
			
		||||
                    message = 'No matching package found for workload {name} (version {version})'
 | 
			
		||||
                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)
 | 
			
		||||
        if self.package_name:
 | 
			
		||||
            self.logger.debug('Found matching package on target; Pulling to host.')
 | 
			
		||||
            self.apk_file = self.pull_apk(self.package_name)
 | 
			
		||||
 | 
			
		||||
    def initialize_package(self, context):
 | 
			
		||||
        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.force_install = True  # pylint: disable=attribute-defined-outside-init
 | 
			
		||||
        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))
 | 
			
		||||
        if self.force_install:
 | 
			
		||||
            if installed_version:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user