diff --git a/external/devlib/devlib/__init__.py b/external/devlib/devlib/__init__.py index e1c07e8573562f2d4ee2c0d17e4da6641ac06c97..da8d9e081b36d4e7fc8442ac1ea819867809741e 100644 --- a/external/devlib/devlib/__init__.py +++ b/external/devlib/devlib/__init__.py @@ -53,10 +53,11 @@ from devlib.host import LocalConnection from devlib.utils.android import AdbConnection from devlib.utils.ssh import SshConnection, TelnetConnection, Gem5Connection -from devlib.utils.version import get_commit as __get_commit +from devlib.utils.version import (get_devlib_version as __get_devlib_version, + get_commit as __get_commit) -__version__ = '1.1.dev1' +__version__ = __get_devlib_version() __commit = __get_commit() if __commit: diff --git a/external/devlib/devlib/host.py b/external/devlib/devlib/host.py index 48e785f2bc00e88b5dafac91d8a3d1630894a3be..8c19e192670e6233940532e6fd285e7c24f5c328 100644 --- a/external/devlib/devlib/host.py +++ b/external/devlib/devlib/host.py @@ -71,7 +71,7 @@ class LocalConnection(object): if self.unrooted: raise TargetStableError('unrooted') password = self._get_password() - command = 'echo {} | sudo -S '.format(quote(password)) + command + command = 'echo {} | sudo -S -- sh -c '.format(quote(password)) + quote(command) ignore = None if check_exit_code else 'all' try: return check_output(command, shell=True, timeout=timeout, ignore=ignore)[0] diff --git a/external/devlib/devlib/module/sched.py b/external/devlib/devlib/module/sched.py index a05725bf2b0f22d75aac3e7de75b76859cb388bb..0f35fc141a6232c195e6851b03873986a3cc80c3 100644 --- a/external/devlib/devlib/module/sched.py +++ b/external/devlib/devlib/module/sched.py @@ -440,10 +440,10 @@ class SchedModule(Module): sd_info = self.get_sd_info() for cpu in cpus: - if self.has_em(cpu, sd_info.cpus[cpu]): - capacities[cpu] = self.get_em_capacity(cpu, sd_info.cpus[cpu]) - elif self.has_dmips_capacity(cpu): + if self.has_dmips_capacity(cpu): capacities[cpu] = self.get_dmips_capacity(cpu) + elif self.has_em(cpu, sd_info.cpus[cpu]): + capacities[cpu] = self.get_em_capacity(cpu, sd_info.cpus[cpu]) else: if default != None: capacities[cpu] = default diff --git a/external/devlib/devlib/target.py b/external/devlib/devlib/target.py index 18fb59ca63d40835f64432215054117619fa89f4..92a6839c9d2d05d92b61caec5a2b81d8333fa850 100644 --- a/external/devlib/devlib/target.py +++ b/external/devlib/devlib/target.py @@ -30,6 +30,7 @@ import xml.dom.minidom import copy from collections import namedtuple, defaultdict from pipes import quote +from past.builtins import long from past.types import basestring from numbers import Number try: @@ -1792,7 +1793,7 @@ class KernelVersion(object): __repr__ = __str__ -class HexInt(int): +class HexInt(long): """ Subclass of :class:`int` that uses hexadecimal formatting by default. """ @@ -1805,7 +1806,7 @@ class HexInt(int): return super_new(cls, val, base=base) def __str__(self): - return hex(self) + return hex(self).strip('L') class KernelConfigTristate(Enum): diff --git a/external/devlib/devlib/utils/version.py b/external/devlib/devlib/utils/version.py index 16b4308b364d7e5050d5d28d9cbcdcce7f2601e5..8245e6f6e1d742ab44ff3188b4b95e5aa13e789f 100644 --- a/external/devlib/devlib/utils/version.py +++ b/external/devlib/devlib/utils/version.py @@ -15,8 +15,23 @@ import os import sys +from collections import namedtuple from subprocess import Popen, PIPE + +VersionTuple = namedtuple('Version', ['major', 'minor', 'revision', 'dev']) + +version = VersionTuple(1, 1, 1, 'dev1') + + +def get_devlib_version(): + version_string = '{}.{}.{}'.format( + version.major, version.minor, version.revision) + if version.dev: + version_string += '.{}'.format(version.dev) + return version_string + + def get_commit(): p = Popen(['git', 'rev-parse', 'HEAD'], cwd=os.path.dirname(__file__), stdout=PIPE, stderr=PIPE) diff --git a/external/devlib/setup.py b/external/devlib/setup.py index 4571be28e4736ec2467bcefbda2261d12cd63bee..757e450520ec3e786011544724d77711965fb145 100644 --- a/external/devlib/setup.py +++ b/external/devlib/setup.py @@ -41,23 +41,13 @@ except OSError: pass -with open(os.path.join(devlib_dir, '__init__.py')) as fh: - # Extract the version by parsing the text of the file, - # as may not be able to load as a module yet. - for line in fh: - if '__version__' in line: - parts = line.split("'") - __version__ = parts[1] - break - else: - raise RuntimeError('Did not see __version__') - - vh_path = os.path.join(devlib_dir, 'utils', 'version.py') - # can load this, as it does not have any devlib imports - version_helper = imp.load_source('version_helper', vh_path) - commit = version_helper.get_commit() - if commit: - __version__ = '{}+{}'.format(__version__, commit) +vh_path = os.path.join(devlib_dir, 'utils', 'version.py') +# can load this, as it does not have any devlib imports +version_helper = imp.load_source('version_helper', vh_path) +__version__ = version_helper.get_devlib_version() +commit = version_helper.get_commit() +if commit: + __version__ = '{}+{}'.format(__version__, commit) packages = [] diff --git a/external/workload-automation/doc/source/api/workload.rst b/external/workload-automation/doc/source/api/workload.rst index 468516b8bbcd2f87516f092ba2282b28ad62bc30..f1494f5cc6cf9605c28ace075f123febc26d163b 100644 --- a/external/workload-automation/doc/source/api/workload.rst +++ b/external/workload-automation/doc/source/api/workload.rst @@ -178,6 +178,11 @@ methods. locations) and device will be searched for an application with a matching package name. +``supported_versions`` + This attribute should be a list of apk versions that are suitable for this + workload, if a specific apk version is not specified then any available + supported version may be chosen. + ``view`` This is the "view" associated with the application. This is used by instruments like ``fps`` to monitor the current framerate being generated by diff --git a/external/workload-automation/doc/source/changes.rst b/external/workload-automation/doc/source/changes.rst index 982c8abcf129a5b2c7f80d7b02cae343216fdf56..fa4118da050892ad8fbc5d5a7d664fcfe9bcb076 100644 --- a/external/workload-automation/doc/source/changes.rst +++ b/external/workload-automation/doc/source/changes.rst @@ -2,6 +2,34 @@ What's New in Workload Automation ================================= +************* +Version 3.1.2 +************* + +Fixes/Improvements +================== + +Framework: +---------- + - Implement an explicit check for Devlib versions to ensure that versions + are kept in sync with each other. + - Added a ``View`` parameter to ApkWorkloads for use with certain instruments + for example ``fps``. + - Added ``"supported_versions"`` attribute to workloads to allow specifying a + list of supported version for a particular workload. + - Change default behaviour to run any available version of a workload if a + specific version is not specified. + +Output Processors: +------------------ + - ``Postgres``: Fix handling of ``screen_resoultion`` during processing. + +Other +----- + - Added additional information to documentation + - Added fix for Devlib's ``KernelConfig`` refactor + - Added a ``"label"`` property to ``Metrics`` + ************* Version 3.1.1 ************* diff --git a/external/workload-automation/doc/source/faq.rst b/external/workload-automation/doc/source/faq.rst index 86a8fcccfc6c6ad6ad277ae50824a60bc5ce43f7..a5e945d2e0e27d7cbd63d1e6e72ec6233eb207d1 100644 --- a/external/workload-automation/doc/source/faq.rst +++ b/external/workload-automation/doc/source/faq.rst @@ -106,3 +106,11 @@ may get something like: From these ``"SurfaceView - com.rovio.angrybirdsrio/com.rovio.fusion.App#0"`` is the mostly likely the View that needs to be set as the ``view`` workload parameter and will be picked up be the ``fps`` augmentation. + + +**Q:** I am getting an error which looks similar to ``'CONFIG_SND_BT87X is not exposed in kernel config'...`` +------------------------------------------------------------------------------------------------------------- +**A:** If you are receiving this under normal operation this can be caused by a +mismatch of your WA and devlib versions. Please update both to their latest +versions and delete your ``$USER_HOME/.workload_automation/cache/targets.json`` +(or equivalent) file. diff --git a/external/workload-automation/doc/source/user_information/installation.rst b/external/workload-automation/doc/source/user_information/installation.rst index 20722665b22c01f3e3efb68d4ef7da7941e34414..a036d822564429224673d98c27b714ae79b94f4f 100644 --- a/external/workload-automation/doc/source/user_information/installation.rst +++ b/external/workload-automation/doc/source/user_information/installation.rst @@ -199,6 +199,11 @@ Alternatively, you can also install the latest development version from GitHub cd workload-automation sudo -H python setup.py install +.. note:: Please note that if using pip to install from github this will most + likely result in an older and incompatible version of devlib being + installed alongside WA. If you wish to use pip please also manually + install the latest version of + `devlib `_. If the above succeeds, try :: @@ -222,7 +227,7 @@ image in a container. The Dockerfile can be found in the "extras" directory or online at ``_ -which contains addional information about how to build and to use the file. +which contains additional information about how to build and to use the file. (Optional) Post Installation diff --git a/external/workload-automation/extras/Dockerfile b/external/workload-automation/extras/Dockerfile index 4c97e2c5b55c4ae1b87cbcbb5441ec77a7587084..b417ebb48441a655dde59f9f5098878e4477943e 100644 --- a/external/workload-automation/extras/Dockerfile +++ b/external/workload-automation/extras/Dockerfile @@ -42,8 +42,8 @@ FROM ubuntu:17.10 # Please update the references below to use different versions of # devlib, WA or the Android SDK -ARG DEVLIB_REF=v1.1.0 -ARG WA_REF=v3.1.1 +ARG DEVLIB_REF=v1.1.1 +ARG WA_REF=v3.1.3 ARG ANDROID_SDK_URL=https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip RUN apt-get update diff --git a/external/workload-automation/setup.py b/external/workload-automation/setup.py index 04eb9a20dd1c64e56393b29b1f545d7bed7bbf12..45b2257a315b50056bc7ef0c4a157e7f0bbe935d 100755 --- a/external/workload-automation/setup.py +++ b/external/workload-automation/setup.py @@ -29,7 +29,8 @@ except ImportError: wa_dir = os.path.join(os.path.dirname(__file__), 'wa') sys.path.insert(0, os.path.join(wa_dir, 'framework')) -from version import get_wa_version, get_wa_version_with_commit +from version import (get_wa_version, get_wa_version_with_commit, + format_version, required_devlib_version) # happens if falling back to distutils warnings.filterwarnings('ignore', "Unknown distribution option: 'install_requires'") @@ -61,6 +62,8 @@ for root, dirs, files in os.walk(wa_dir): scripts = [os.path.join('scripts', s) for s in os.listdir('scripts')] + +devlib_version = format_version(required_devlib_version) params = dict( name='wlauto', description='A framework for automating workload execution and measurement collection on ARM devices.', @@ -81,15 +84,15 @@ params = dict( 'pexpect>=3.3', # Send/receive to/from device 'pyserial', # Serial port interface 'colorama', # Printing with colors - 'pyYAML', # YAML-formatted agenda parsing + 'pyYAML>=5.1b3', # YAML-formatted agenda parsing 'requests', # Fetch assets over HTTP - 'devlib>=1.1.dev1', # Interacting with devices + 'devlib>={}'.format(devlib_version), # Interacting with devices 'louie-latest', # callbacks dispatch 'wrapt', # better decorators 'pandas>=0.23.0', # Data analysis and manipulation 'future', # Python 2-3 compatiblity ], - dependency_links=['https://github.com/ARM-software/devlib/tarball/master#egg=devlib-1.1.dev1'], + dependency_links=['https://github.com/ARM-software/devlib/tarball/master#egg=devlib-{}'.format(devlib_version)], extras_require={ 'other': ['jinja2'], 'test': ['nose', 'mock'], @@ -123,7 +126,6 @@ class sdist(orig_sdist): orig_sdist.initialize_options(self) self.strip_commit = False - def run(self): if self.strip_commit: self.distribution.get_version = get_wa_version diff --git a/external/workload-automation/wa/framework/entrypoint.py b/external/workload-automation/wa/framework/entrypoint.py index 29a6e904576bf098e7a77e7dd5f54aed23bef512..b517fab6b191bdbe825fb9d8c7911fba1ba89e6e 100644 --- a/external/workload-automation/wa/framework/entrypoint.py +++ b/external/workload-automation/wa/framework/entrypoint.py @@ -21,14 +21,19 @@ import os import warnings import devlib +try: + from devlib.utils.version import version as installed_devlib_version +except ImportError: + installed_devlib_version = None from wa.framework import pluginloader from wa.framework.command import init_argument_parser from wa.framework.configuration import settings from wa.framework.configuration.execution import ConfigManager from wa.framework.host import init_user_directory, init_config -from wa.framework.exception import ConfigError -from wa.framework.version import get_wa_version_with_commit +from wa.framework.exception import ConfigError, HostError +from wa.framework.version import (get_wa_version_with_commit, format_version, + required_devlib_version) from wa.utils import log from wa.utils.doc import format_body @@ -64,6 +69,13 @@ def split_joined_options(argv): return output +# Instead of presenting an obscure error due to a version mismatch explicitly warn the user. +def check_devlib_version(): + if not installed_devlib_version or installed_devlib_version < required_devlib_version: + msg = 'WA requires Devlib version >={}. Please update the currently installed version {}' + raise HostError(msg.format(format_version(required_devlib_version), devlib.__version__)) + + def main(): if not os.path.exists(settings.user_directory): init_user_directory() @@ -102,6 +114,7 @@ def main(): logger.debug('Version: {}'.format(get_wa_version_with_commit())) logger.debug('devlib version: {}'.format(devlib.__full_version__)) logger.debug('Command Line: {}'.format(' '.join(sys.argv))) + check_devlib_version() # each command will add its own subparser subparsers = parser.add_subparsers(dest='command') diff --git a/external/workload-automation/wa/framework/output.py b/external/workload-automation/wa/framework/output.py index 3cf1f5ee000023a2b559186b1c9b5988873e0dd6..59f7451c9336817c574837b4bee38143a6d5e223 100644 --- a/external/workload-automation/wa/framework/output.py +++ b/external/workload-automation/wa/framework/output.py @@ -346,6 +346,13 @@ class JobOutput(Output): self.spec = None self.reload() + @property + def augmentations(self): + job_augs = set([]) + for aug in self.spec.augmentations: + job_augs.add(aug) + return list(job_augs) + class Result(Podable): @@ -1003,6 +1010,7 @@ class RunDatabaseOutput(DatabaseOutput, RunOutputCommon): jobs = self._read_db(columns, tables, conditions) for job in jobs: + job['augmentations'] = self._get_job_augmentations(job['oid']) job['workload_parameters'] = workload_params.pop(job['oid'], {}) job['runtime_parameters'] = runtime_params.pop(job['oid'], {}) job.pop('oid') @@ -1166,6 +1174,15 @@ class RunDatabaseOutput(DatabaseOutput, RunOutputCommon): logger.debug('Failed to deserialize job_oid:{}-"{}":"{}"'.format(job_oid, k, v)) return parm_dict + def _get_job_augmentations(self, job_oid): + columns = ['jobs_augs.augmentation_oid', 'augmentations.name', + 'augmentations.oid', 'jobs_augs.job_oid'] + tables = ['jobs_augs', 'augmentations'] + conditions = ['jobs_augs.job_oid = \'{}\''.format(job_oid), + 'jobs_augs.augmentation_oid = augmentations.oid'] + augmentations = self._read_db(columns, tables, conditions) + return [aug['name'] for aug in augmentations] + def _list_runs(self): columns = ['runs.run_uuid', 'runs.run_name', 'runs.project', 'runs.project_stage', 'runs.status', 'runs.start_time', 'runs.end_time'] @@ -1217,3 +1234,11 @@ class JobDatabaseOutput(DatabaseOutput): def __str__(self): return '{}-{}-{}'.format(self.id, self.label, self.iteration) + + @property + def augmentations(self): + job_augs = set([]) + if self.spec: + for aug in self.spec.augmentations: + job_augs.add(aug) + return list(job_augs) diff --git a/external/workload-automation/wa/framework/resource.py b/external/workload-automation/wa/framework/resource.py index aa1e04c24b47395ad2c456398eb929e3e443be7c..a4dd70761910ca7a3e0db3274fc874e68284cc82 100644 --- a/external/workload-automation/wa/framework/resource.py +++ b/external/workload-automation/wa/framework/resource.py @@ -273,10 +273,14 @@ class ResourceResolver(object): def apk_version_matches(path, version): + version = list_or_string(version) info = ApkInfo(path) - if info.version_name == version or info.version_code == version: - return True - return loose_version_matching(version, info.version_name) + for v in version: + if info.version_name == v or info.version_code == v: + return True + if loose_version_matching(v, info.version_name): + return True + return False def loose_version_matching(config_version, apk_version): diff --git a/external/workload-automation/wa/framework/target/info.py b/external/workload-automation/wa/framework/target/info.py index 52b214c837a6bd6a37405b3e1c01612625809d74..4baab132c853c0e21f82ade5ea194713e60ccf4f 100644 --- a/external/workload-automation/wa/framework/target/info.py +++ b/external/workload-automation/wa/framework/target/info.py @@ -313,7 +313,7 @@ def cache_target_info(target_info, overwrite=False): class TargetInfo(Podable): - _pod_serialization_version = 3 + _pod_serialization_version = 4 @staticmethod def from_pod(pod): @@ -409,3 +409,7 @@ class TargetInfo(Podable): config[key.upper()] = value pod['kernel_config'] = config return pod + + @staticmethod + def _pod_upgrade_v4(pod): + return TargetInfo._pod_upgrade_v3(pod) diff --git a/external/workload-automation/wa/framework/version.py b/external/workload-automation/wa/framework/version.py index 44f9aee62b762fcc4ef113189a35cc0b88289bcf..227a496a479d377a04eaeab8a714661788821164 100644 --- a/external/workload-automation/wa/framework/version.py +++ b/external/workload-automation/wa/framework/version.py @@ -21,17 +21,23 @@ from subprocess import Popen, PIPE VersionTuple = namedtuple('Version', ['major', 'minor', 'revision', 'dev']) -version = VersionTuple(3, 1, 1, 'dev1') +version = VersionTuple(3, 1, 3, 'dev1') +required_devlib_version = VersionTuple(1, 1, 1, 'dev1') -def get_wa_version(): + +def format_version(v): version_string = '{}.{}.{}'.format( - version.major, version.minor, version.revision) - if version.dev: - version_string += '.{}'.format(version.dev) + v.major, v.minor, v.revision) + if v.dev: + version_string += '.{}'.format(v.dev) return version_string +def get_wa_version(): + return format_version(version) + + def get_wa_version_with_commit(): version_string = get_wa_version() commit = get_commit() diff --git a/external/workload-automation/wa/framework/workload.py b/external/workload-automation/wa/framework/workload.py index 62f980ce1a86605d33436b77e224cb22c8bf4ee1..e740832190a96c6e7840e8e9cb7e6eb9f4a96d2d 100644 --- a/external/workload-automation/wa/framework/workload.py +++ b/external/workload-automation/wa/framework/workload.py @@ -22,7 +22,7 @@ from wa.framework.plugin import TargetedPlugin, Parameter from wa.framework.resource import (ApkFile, ReventFile, File, loose_version_matching) from wa.framework.exception import WorkloadError, ConfigError -from wa.utils.types import ParameterDict +from wa.utils.types import ParameterDict, list_or_string from wa.utils.revent import ReventRecorder from wa.utils.exec_control import once_per_instance @@ -174,6 +174,7 @@ class ApkWorkload(Workload): # Times are in seconds loading_time = 10 package_names = [] + supported_versions = [] view = None clear_data_on_reset = True @@ -259,7 +260,7 @@ class ApkWorkload(Workload): package_name=self.package_name, variant=self.variant, strict=self.strict, - version=self.version, + version=self.version or self.supported_versions, force_install=self.force_install, install_timeout=self.install_timeout, uninstall=self.uninstall, @@ -271,6 +272,9 @@ class ApkWorkload(Workload): def initialize(self, context): super(ApkWorkload, self).initialize(context) self.apk.initialize(context) + # pylint: disable=access-member-before-definition, attribute-defined-outside-init + if self.version is None: + self.version = self.apk.apk_info.version_name if self.view is None: self.view = 'SurfaceView - {}/{}'.format(self.apk.package, self.apk.activity) @@ -755,8 +759,9 @@ class PackageHandler(object): matching_packages = [] for package in installed_versions: package_version = self.target.get_package_version(package) - if loose_version_matching(self.version, package_version): - matching_packages.append(package) + for v in list_or_string(self.version): + if loose_version_matching(v, package_version): + matching_packages.append(package) if len(matching_packages) == 1: self.package_name = matching_packages[0] elif len(matching_packages) > 1: diff --git a/external/workload-automation/wa/output_processors/postgresql.py b/external/workload-automation/wa/output_processors/postgresql.py index ba1ef37990c94b1f274416ab818bc59332a78dba..d9892bbcb2cbb900cab8909538e65d69f3669d6f 100644 --- a/external/workload-automation/wa/output_processors/postgresql.py +++ b/external/workload-automation/wa/output_processors/postgresql.py @@ -206,7 +206,7 @@ class PostgresqlResultProcessor(OutputProcessor): target_pod['sched_features'], target_pod['page_size_kb'], # Android Specific - list(target_pod.get('screen_resolution')), + list(target_pod.get('screen_resolution', [])), target_pod.get('prop'), target_pod.get('android_id'), target_pod.get('pod_version'), diff --git a/external/workload-automation/wa/utils/misc.py b/external/workload-automation/wa/utils/misc.py index eed4792b4e22695abed4cf5608e42c8d44f68f65..9f8586045195a7c5b1f90932972bea144f842abd 100644 --- a/external/workload-automation/wa/utils/misc.py +++ b/external/workload-automation/wa/utils/misc.py @@ -41,7 +41,6 @@ else: from itertools import chain, cycle from distutils.spawn import find_executable # pylint: disable=no-name-in-module, import-error -import yaml from dateutil import tz # pylint: disable=wrong-import-order @@ -325,6 +324,11 @@ def load_struct_from_python(filepath=None, text=None): def load_struct_from_yaml(filepath=None, text=None): """Parses a config structure from a .yaml file. The structure should be composed of basic Python types (strings, ints, lists, dicts, etc.).""" + + # Import here to avoid circular imports + # pylint: disable=wrong-import-position,cyclic-import + from wa.utils.serializer import yaml + if not (filepath or text) or (filepath and text): raise ValueError('Exactly one of filepath or text must be specified.') try: diff --git a/external/workload-automation/wa/utils/serializer.py b/external/workload-automation/wa/utils/serializer.py index 4e0a79b5082b30508473c23f0eeb9f4edeae2b7e..2895a57f8a9d9642e43e2e134faad283901f1556 100644 --- a/external/workload-automation/wa/utils/serializer.py +++ b/external/workload-automation/wa/utils/serializer.py @@ -63,6 +63,11 @@ from collections import OrderedDict from datetime import datetime import dateutil.parser import yaml as _yaml # pylint: disable=wrong-import-order +try: + from yaml import FullLoader as _yaml_loader +except ImportError: + from yaml import Loader as _yaml_loader + # pylint: disable=redefined-builtin from past.builtins import basestring # pylint: disable=wrong-import-order @@ -234,10 +239,10 @@ _yaml.add_representer(OrderedDict, _wa_dict_representer) _yaml.add_representer(regex_type, _wa_regex_representer) _yaml.add_representer(level, _wa_level_representer) _yaml.add_representer(cpu_mask, _wa_cpu_mask_representer) -_yaml.add_constructor(_mapping_tag, _wa_dict_constructor) -_yaml.add_constructor(_regex_tag, _wa_regex_constructor) -_yaml.add_constructor(_level_tag, _wa_level_constructor) -_yaml.add_constructor(_cpu_mask_tag, _wa_cpu_mask_constructor) +_yaml.add_constructor(_regex_tag, _wa_regex_constructor, Loader=_yaml_loader) +_yaml.add_constructor(_level_tag, _wa_level_constructor, Loader=_yaml_loader) +_yaml.add_constructor(_cpu_mask_tag, _wa_cpu_mask_constructor, Loader=_yaml_loader) +_yaml.add_constructor(_mapping_tag, _wa_dict_constructor, Loader=_yaml_loader) class yaml(object): @@ -249,7 +254,7 @@ class yaml(object): @staticmethod def load(fh, *args, **kwargs): try: - return _yaml.load(fh, *args, **kwargs) + return _yaml.load(fh, *args, Loader=_yaml_loader, **kwargs) except _yaml.YAMLError as e: lineno = None if hasattr(e, 'problem_mark'): diff --git a/external/workload-automation/wa/workloads/chrome/com.arm.wa.uiauto.chrome.apk b/external/workload-automation/wa/workloads/chrome/com.arm.wa.uiauto.chrome.apk index cb3918332de048f305a5d3044dc22718e8a19b38..692e2a9359e2177b013305c43b07c2df483bd319 100644 Binary files a/external/workload-automation/wa/workloads/chrome/com.arm.wa.uiauto.chrome.apk and b/external/workload-automation/wa/workloads/chrome/com.arm.wa.uiauto.chrome.apk differ diff --git a/external/workload-automation/wa/workloads/chrome/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java b/external/workload-automation/wa/workloads/chrome/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java index 3d7c5e2a0f124a1ad6d84437ea15533957ecb239..c643ff26ca20a32e2ff7be553e2a90e8c7dd3ebc 100644 --- a/external/workload-automation/wa/workloads/chrome/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java +++ b/external/workload-automation/wa/workloads/chrome/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java @@ -81,12 +81,22 @@ public class UiAutomation extends BaseUiAutomation implements ApplaunchInterface // Activate the tab switcher tabSwitcher = mDevice.findObject(new UiSelector().resourceId(packageID + "tab_switcher_button") .className("android.widget.ImageButton")); - tabSwitcher.clickAndWaitForNewWindow(uiAutoTimeout); - - // Click the New Tab button - newTab = mDevice.findObject(new UiSelector().resourceId(packageID + "new_tab_button") - .className("android.widget.Button")); - newTab.clickAndWaitForNewWindow(uiAutoTimeout); + if (tabSwitcher.exists()){ + tabSwitcher.clickAndWaitForNewWindow(uiAutoTimeout); + // Click the New Tab button + newTab = mDevice.findObject(new UiSelector().resourceId(packageID + "new_tab_button") + .className("android.widget.Button")); + newTab.clickAndWaitForNewWindow(uiAutoTimeout); + } + // Support Tablet devices which do not have tab switcher + else { + UiObject menu_button = mDevice.findObject(new UiSelector().resourceId(packageID + "menu_button") + .className("android.widget.ImageButton")); + menu_button.click(); + newTab = mDevice.findObject(new UiSelector().resourceId(packageID + "menu_item_text") + .textContains("New tab")); + newTab.click(); + } } public void followTextLink(String text) throws Exception { diff --git a/external/workload-automation/wa/workloads/exoplayer/__init__.py b/external/workload-automation/wa/workloads/exoplayer/__init__.py index 64064b5ccbeda89cadca5a420e6f6a0ba8944c67..f4293b650926b0241822cea79640407721b5c368 100644 --- a/external/workload-automation/wa/workloads/exoplayer/__init__.py +++ b/external/workload-automation/wa/workloads/exoplayer/__init__.py @@ -77,13 +77,13 @@ class ExoPlayer(ApkWorkload): video_directory = os.path.join(settings.dependencies_directory, name) package_names = ['com.google.android.exoplayer2.demo'] - versions = ['2.4', '2.5', '2.6'] + supported_versions = ['2.4', '2.5', '2.6'] action = 'com.google.android.exoplayer.demo.action.VIEW' default_format = 'mov_720p' view = 'SurfaceView - com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity' parameters = [ - Parameter('version', allowed_values=versions, default=versions[-1], override=True), + Parameter('version', allowed_values=supported_versions, override=True), Parameter('duration', kind=int, default=20, description=""" Playback duration of the video file. This becomes the duration of the workload. diff --git a/external/workload-automation/wa/workloads/geekbench/__init__.py b/external/workload-automation/wa/workloads/geekbench/__init__.py index 724c6074c01d6c3992c5cdd0272dcc23f0142c5a..ef7ff6642809949f3a3ef7ced2d4f43682fe745a 100644 --- a/external/workload-automation/wa/workloads/geekbench/__init__.py +++ b/external/workload-automation/wa/workloads/geekbench/__init__.py @@ -78,12 +78,13 @@ class Geekbench(ApkUiautoWorkload): 'activity': '.HomeActivity', }, } + supported_versions = sorted(versions.keys()) begin_regex = re.compile(r'^\s*D/WebViewClassic.loadDataWithBaseURL\(\s*\d+\s*\)' r'\s*:\s*(?P\<.*)\s*$') replace_regex = re.compile(r'<[^>]*>') parameters = [ - Parameter('version', default=sorted(versions.keys())[-1], allowed_values=sorted(versions.keys()), + Parameter('version', allowed_values=supported_versions, description='Specifies which version of the workload should be run.', override=True), Parameter('loops', kind=int, default=1, aliases=['times'], @@ -109,23 +110,16 @@ class Geekbench(ApkUiautoWorkload): def activity(self): return self.versions[self.version]['activity'] - @property - def package(self): - return self.versions[self.version]['package'] - @property def package_names(self): - return [self.package] + return set(self.versions[v]['package'] for v in self.versions) - def __init__(self, *args, **kwargs): - super(Geekbench, self).__init__(*args, **kwargs) + def initialize(self, context): + super(Geekbench, self).initialize(context) self.gui.uiauto_params['version'] = self.version self.gui.uiauto_params['loops'] = self.loops self.gui.uiauto_params['is_corporate'] = self.is_corporate self.gui.timeout = self.timeout - - def initialize(self, context): - super(Geekbench, self).initialize(context) if not self.disable_update_result and not self.target.is_rooted: raise WorkloadError( 'Geekbench workload requires root to collect results. ' @@ -135,7 +129,6 @@ class Geekbench(ApkUiautoWorkload): def setup(self, context): super(Geekbench, self).setup(context) self.run_timeout = self.timeout * self.loops - self.exact_apk_version = self.version def update_output(self, context): super(Geekbench, self).update_output(context) @@ -154,7 +147,7 @@ class Geekbench(ApkUiautoWorkload): score_calculator.update_results(context) def update_result_3(self, context): - outfile_glob = self.target.path.join(self.target.package_data_directory, self.package, 'files', '*gb3') + outfile_glob = self.target.path.join(self.target.package_data_directory, self.apk.package, 'files', '*gb3') on_target_output_files = [f.strip() for f in self.target.execute('ls {}'.format(outfile_glob), as_root=True).split('\n') if f] for i, on_target_output_file in enumerate(on_target_output_files): @@ -176,7 +169,7 @@ class Geekbench(ApkUiautoWorkload): section['multicore_score']) def update_result_4(self, context): - outfile_glob = self.target.path.join(self.target.package_data_directory, self.package, 'files', '*gb*') + outfile_glob = self.target.path.join(self.target.package_data_directory, self.apk.package, 'files', '*gb*') on_target_output_files = [f.strip() for f in self.target.execute('ls {}'.format(outfile_glob), as_root=True).split('\n') if f] for i, on_target_output_file in enumerate(on_target_output_files): @@ -395,16 +388,12 @@ class GeekbenchCorproate(Geekbench): # pylint: disable=too-many-ancestors name = "geekbench-corporate" is_corporate = True requires_network = False - - versions = ['4.1.0', '5.0.0'] - + supported_versions = ['4.1.0', '5.0.0'] + package_names = ['com.primatelabs.geekbench4.corporate'] activity = 'com.primatelabs.geekbench.HomeActivity' - package = 'com.primatelabs.geekbench4.corporate' parameters = [ - Parameter('version', - default=sorted(versions)[-1], allowed_values=versions, - override=True) + Parameter('version', allowed_values=supported_versions, override=True) ] diff --git a/external/workload-automation/wa/workloads/glbenchmark/__init__.py b/external/workload-automation/wa/workloads/glbenchmark/__init__.py index dd38d95bef498ee876ebf67691e87d2029c0dafc..bf4d0489e8dbfbd88c2aadf3bb5639683bed06fc 100644 --- a/external/workload-automation/wa/workloads/glbenchmark/__init__.py +++ b/external/workload-automation/wa/workloads/glbenchmark/__init__.py @@ -56,10 +56,8 @@ class Glb(ApkUiautoWorkload): view = 'com.glbenchmark.glbenchmark27/com.glbenchmark.activities.GLBRender' package_names = ['com.glbenchmark.glbenchmark27', 'com.glbenchmark.glbenchmark25'] - packages = { - '2.7': 'com.glbenchmark.glbenchmark27', - '2.5': 'com.glbenchmark.glbenchmark25', - } + supported_versions = ['2.7', '2.5'] + # If usecase is not specified the default usecase is the first supported usecase alias # for the specified version. supported_usecase_aliases = { @@ -74,7 +72,7 @@ class Glb(ApkUiautoWorkload): regex = re.compile(r'GLBenchmark (metric|FPS): (.*)') parameters = [ - Parameter('version', default='2.7', allowed_values=['2.7', '2.5'], override=True, + Parameter('version', allowed_values=supported_versions, override=True, description=('Specifies which version of the benchmark to run (different versions ' 'support different use cases).')), Parameter('use_case', default=None, @@ -107,10 +105,9 @@ class Glb(ApkUiautoWorkload): Alias('t-rex_offscreen', use_case='t-rex', type='offscreen'), ] - def __init__(self, target, **kwargs): - super(Glb, self).__init__(target, **kwargs) + def initialize(self, context): + super(Glb, self).initialize(context) self.gui.uiauto_params['version'] = self.version - if self.use_case is None: self.use_case = self.supported_usecase_aliases[self.version][0] if self.use_case.lower() in USE_CASE_MAP: @@ -124,7 +121,6 @@ class Glb(ApkUiautoWorkload): self.gui.uiauto_params['usecase_type'] = self.type.replace(' ', '_') self.gui.uiauto_params['timeout'] = self.run_timeout - self.package_names = [self.packages[self.version]] def update_output(self, context): super(Glb, self).update_output(context) diff --git a/external/workload-automation/wa/workloads/stress_ng/__init__.py b/external/workload-automation/wa/workloads/stress_ng/__init__.py index 21a8db29494d90261eaee259af4b644fa78e6e67..c4e0df6116d890d61acf87fa37fbbd41d5bc51c5 100644 --- a/external/workload-automation/wa/workloads/stress_ng/__init__.py +++ b/external/workload-automation/wa/workloads/stress_ng/__init__.py @@ -15,11 +15,11 @@ # pylint: disable=attribute-defined-outside-init import os -import yaml from wa import Workload, Parameter, ConfigError, Executable from wa.framework.exception import WorkloadError from wa.utils.exec_control import once +from wa.utils.serializer import yaml class StressNg(Workload): diff --git a/external/workload-automation/wa/workloads/vellamo/__init__.py b/external/workload-automation/wa/workloads/vellamo/__init__.py index c8a4b76e186721cc980c088d5cdf28b77c69e6c0..29529b43e8ad849c0da9b2d6a66bbb428f3b3b6f 100644 --- a/external/workload-automation/wa/workloads/vellamo/__init__.py +++ b/external/workload-automation/wa/workloads/vellamo/__init__.py @@ -48,11 +48,11 @@ class Vellamo(ApkUiautoWorkload): '3.0': ['Browser', 'Metal', 'Multi'], '3.2.4': ['Browser', 'Metal', 'Multi'], } - valid_versions = list(benchmark_types.keys()) + supported_versions = list(benchmark_types.keys()) summary_metrics = None parameters = [ - Parameter('version', kind=str, allowed_values=valid_versions, default=sorted(benchmark_types, reverse=True)[0], override=True, + Parameter('version', kind=str, allowed_values=supported_versions, override=True, description=('Specify the version of Vellamo to be run. ' 'If not specified, the latest available version will be used.')), Parameter('benchmarks', kind=list_of_strs, allowed_values=benchmark_types['3.0'], default=benchmark_types['3.0'], @@ -66,15 +66,15 @@ class Vellamo(ApkUiautoWorkload): ] def setup(self, context): + super(Vellamo, self).setup(context) self.gui.uiauto_params['version'] = self.version self.gui.uiauto_params['browserToUse'] = self.browser self.gui.uiauto_params['metal'] = 'Metal' in self.benchmarks self.gui.uiauto_params['browser'] = 'Browser' in self.benchmarks self.gui.uiauto_params['multicore'] = 'Multi' in self.benchmarks - super(Vellamo, self).setup(context) - def validate(self): - super(Vellamo, self).validate() + def initialize(self, context): + super(Vellamo, self).initialize(context) if self.version == '2.0.3' or not self.benchmarks: # pylint: disable=access-member-before-definition self.benchmarks = self.benchmark_types[self.version] # pylint: disable=attribute-defined-outside-init else: