def prefer_host_apk(self, context, host_version, target_version): msg = "check_apk is 'True' " if host_version is None: try: self.validate_version(target_version) except ResourceError as e: msg += "but the APK was not found on the host and the target version is invalid:\n\t{}" raise ResourceError(msg.format(str(e))) else: msg += "but the APK was not found on the host, using target version" self.logger.debug(msg) return try: self.validate_version(host_version) except ResourceError as e1: msg += "but the host APK version is invalid:\n\t{}\n" if target_version is None: msg += "The target does not have the app either" raise ResourceError(msg.format(str(e1))) try: self.validate_version(target_version) except ResourceError as e2: msg += "The target version is also invalid:\n\t{}" raise ResourceError(msg.format(str(e1), str(e2))) else: msg += "using the target version instead" self.logger.debug(msg.format(str(e1))) else: # Host version is valid if target_version is not None and target_version == host_version: msg += " and a matching version is alread on the device, doing nothing" self.logger.debug(msg) return msg += " and the host version is not on the target, installing APK" self.logger.debug(msg) self.install_apk(context, replace=True)
def prefer_target_apk(self, context, host_version, target_version): msg = "check_apk is 'False' " if target_version is None: try: self.validate_version(host_version) except ResourceError as e: msg += "but the app was not found on the target and the host version is invalid:\n\t{}" raise ResourceError(msg.format(str(e))) else: msg += "and the app was not found on the target, using host version" self.logger.debug(msg) self.install_apk(context) return try: self.validate_version(target_version) except ResourceError as e1: msg += "but the target app version is invalid:\n\t{}\n" if host_version is None: msg += "The host does not have the APK either" raise ResourceError(msg.format(str(e1))) try: self.validate_version(host_version) except ResourceError as e2: msg += "The host version is also invalid:\n\t{}" raise ResourceError(msg.format(str(e1), str(e2))) else: msg += "Using the host APK instead" self.logger.debug(msg.format(str(e1))) self.install_apk(context, replace=True) else: msg += "and a valid version of the app is already on the target, using target app" self.logger.debug(msg)
def get(self, resource, strict=True, *args, **kwargs): """ Uses registered getters to attempt to discover a resource of the specified kind and matching the specified criteria. Returns path to the resource that has been discovered. If a resource has not been discovered, this will raise a ``ResourceError`` or, if ``strict`` has been set to ``False``, will return ``None``. """ self.logger.debug('Resolving {}'.format(resource)) for getter in self.getters[resource.name]: self.logger.debug('Trying {}'.format(getter)) result = getter.get(resource, *args, **kwargs) if result is not None: self.logger.debug('Resource {} found using {}:'.format( resource, getter)) self.logger.debug('\t{}'.format(result)) return result if strict: if kwargs: criteria = ', '.join( ['{}:{}'.format(k, v) for k, v in kwargs.iteritems()]) raise ResourceError('{} ({}) could not be found'.format( resource, criteria)) else: raise ResourceError('{} could not be found'.format(resource)) self.logger.debug('Resource {} not found.'.format(resource)) return None
def force_install_apk(self, context, host_version): if host_version is None: raise ResourceError("force_install is 'True' but could not find APK on the host") try: self.validate_version(host_version) except ResourceError as e: msg = "force_install is 'True' but the host version is invalid:\n\t{}" raise ResourceError(msg.format(str(e))) self.install_apk(context, replace=True)
def setup(self, context): Workload.setup(self, context) # Get target version target_version = self.device.get_installed_package_version( self.package) if target_version: target_version = LooseVersion(target_version) self.logger.debug( "Found version '{}' on target device".format(target_version)) # Get host version 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=False) host_version = None if self.apk_file is not None: host_version = ApkInfo(self.apk_file).version_name if host_version: host_version = LooseVersion(host_version) self.logger.debug( "Found version '{}' on host".format(host_version)) # Error if apk was not found anywhere if target_version is None and host_version is None: msg = "Could not find APK for '{}' on the host or target device" raise ResourceError(msg.format(self.name)) if self.exact_apk_version is not None: if self.exact_apk_version != target_version and self.exact_apk_version != host_version: msg = "APK version '{}' not found on the host '{}' or target '{}'" raise ResourceError( msg.format(self.exact_apk_version, host_version, target_version)) # Ensure the apk is setup on the device if self.force_install: self.force_install_apk(context, host_version) elif self.check_apk: self.prefer_host_apk(context, host_version, target_version) else: self.prefer_target_apk(context, host_version, target_version) self.reset(context) self.apk_version = self.device.get_installed_package_version( self.package) context.add_classifiers(apk_version=self.apk_version) if self.launch_main: self.launch_package( ) # launch default activity without intent data self.device.execute('am kill-all') # kill all *background* activities self.device.clear_logcat()
def init_resources(self, context): self.uiauto_file = context.resolver.get(ApkFile(self, uiauto=True)) if not self.uiauto_file: raise ResourceError('No UI automation APK file found for workload {}.'.format(self.name)) if not self.uiauto_package: self.uiauto_package = os.path.splitext(os.path.basename(self.uiauto_file))[0]
def verify_apk_version(self, target_version, target_abi, host_version): # Error if apk was not found anywhere if target_version is None and host_version is None: msg = "Could not find APK for '{}' on the host or target device" raise ResourceError(msg.format(self.name)) if self.exact_apk_version is not None: if self.exact_apk_version != target_version and self.exact_apk_version != host_version: msg = "APK version '{}' not found on the host '{}' or target '{}'" raise ResourceError(msg.format(self.exact_apk_version, host_version, target_version)) # Error if exact_abi and suitable apk not found on host and incorrect version on device if self.exact_abi and host_version is None: if target_abi != self.device.abi: msg = "APK abi '{}' not found on the host and target is '{}'" raise ResourceError(msg.format(self.device.abi, target_abi))
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: 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: return None else: raise ResourceError('More than one .{} found in {} for {}.'.format( extension, filelist, resource.owner.name))
def init_workload_resources(self, context): self.workload.uiauto_file = context.resolver.get(wlauto.common.android.resources.ApkFile(self.workload, uiauto=True)) if not self.workload.uiauto_file: raise ResourceError('No UI automation Uiauto APK file found for workload {}.'.format(self.workload.name)) self.workload.device_uiauto_file = self.device.path.join(self.device.working_directory, os.path.basename(self.workload.uiauto_file)) if not self.workload.uiauto_package: self.workload.uiauto_package = os.path.splitext(os.path.basename(self.workload.uiauto_file))[0]
def _deploy_rt_app_binary_if_necessary(self): # called from initialize() so gets invoked once per run RtApp.device_binary = self.device.get_binary_path("rt-app") if self.force_install or not RtApp.device_binary: if not self.host_binary: message = '''rt-app is not installed on the device and could not be found in workload resources''' raise ResourceError(message) RtApp.device_binary = self.device.install(self.host_binary)
def _deploy_rt_app_binary_if_necessary(self): # called from initialize() so gets invoked once per run if not self.device.is_installed(BINARY_NAME): if not self.host_binary: message = '''rt-app is not installed on the device and could not be found in workload resources''' raise ResourceError(message) RtApp.device_binary = self.device.install(self.host_binary) else: RtApp.device_binary = BINARY_NAME
def get_from_location_by_extension(resource, location, extension, version=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) except ResourceError: raise ResourceError('More than one .{} found in {} for {}.'.format(extension, location, resource.owner.name))
def get_from_location_by_extension(resource, location, extension, version=None): found_files = glob.glob(os.path.join(location, '*.{}'.format(extension))) if version: found_files = [ff for ff in found_files if version.lower() in os.path.basename(ff).lower()] if len(found_files) == 1: return found_files[0] elif not found_files: return None else: raise ResourceError('More than one .{} found in {} for {}.'.format(extension, location, resource.owner.name))
def validate_version(self, version): min_apk_version = getattr(self, 'min_apk_version', None) max_apk_version = getattr(self, 'max_apk_version', None) if min_apk_version is not None and max_apk_version is not None: if version < LooseVersion(min_apk_version) or \ version > LooseVersion(max_apk_version): msg = "version '{}' not supported. " \ "Minimum version required: '{}', Maximum version known to work: '{}'" raise ResourceError(msg.format(version, min_apk_version, max_apk_version)) elif min_apk_version is not None: if version < LooseVersion(min_apk_version): msg = "version '{}' not supported. " \ "Minimum version required: '{}'" raise ResourceError(msg.format(version, min_apk_version)) elif max_apk_version is not None: if version > LooseVersion(max_apk_version): msg = "version '{}' not supported. " \ "Maximum version known to work: '{}'" raise ResourceError(msg.format(version, max_apk_version))
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: 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 extension == 'apk': filelist = [ ff for ff in filelist if not ApkInfo(ff).native_code or resource.platform in ApkInfo(ff).native_code ] filelist = [ ff for ff in filelist if not resource.package or resource.package == ApkInfo(ff).package ] filelist = [ ff for ff in filelist if resource.uiauto == ( 'com.arm.wlauto.uiauto' in ApkInfo(ff).package) ] if len(filelist) == 1: return filelist[0] elif not filelist: return None else: raise ResourceError('More than one .{} found in {} for {}.'.format( extension, filelist, resource.owner.name))