mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-03-27 21:18:59 +00:00
[framework] Create new Jank testing classes
Create two new classes to deal with workloads for which we want to collect frame metrics/jank percentages. ApkUiautoJankTestWorkload inherits from ApkUiautoWorkload and instantiates a UiAutomatorJankTestGUI gui member. UiAutomatorJankTestGUI (inherits from UiAutomatorGUI) handles most of the new logic for jank tests, including using a regular expression to parse the final output.
This commit is contained in:
parent
aa41d4d77d
commit
7b53b9875d
@ -32,8 +32,10 @@ from wa.framework.resource import (NO_ONE, JarFile, ApkFile, ReventFile, File,
|
|||||||
from wa.framework.target.descriptor import (TargetDescriptor, TargetDescription,
|
from wa.framework.target.descriptor import (TargetDescriptor, TargetDescription,
|
||||||
create_target_description, add_description_for_target)
|
create_target_description, add_description_for_target)
|
||||||
from wa.framework.workload import (Workload, ApkWorkload, ApkUiautoWorkload,
|
from wa.framework.workload import (Workload, ApkWorkload, ApkUiautoWorkload,
|
||||||
|
ApkUiautoJankTestWorkload,
|
||||||
ApkReventWorkload, UIWorkload, UiautoWorkload,
|
ApkReventWorkload, UIWorkload, UiautoWorkload,
|
||||||
PackageHandler, ReventWorkload, TestPackageHandler)
|
PackageHandler, ReventWorkload, UiAutomatorGUI,
|
||||||
|
UiAutomatorJankTestGUI, TestPackageHandler)
|
||||||
|
|
||||||
|
|
||||||
from wa.framework.version import get_wa_version, get_wa_version_with_commit
|
from wa.framework.version import get_wa_version, get_wa_version_with_commit
|
||||||
|
@ -16,6 +16,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from shlex import quote
|
from shlex import quote
|
||||||
@ -395,6 +396,13 @@ class ApkUiautoWorkload(ApkUIWorkload):
|
|||||||
super(ApkUiautoWorkload, self).setup(context)
|
super(ApkUiautoWorkload, self).setup(context)
|
||||||
|
|
||||||
|
|
||||||
|
class ApkUiautoJankTestWorkload(ApkUiautoWorkload):
|
||||||
|
|
||||||
|
def __init__(self, target, **kwargs):
|
||||||
|
super(ApkUiautoWorkload, self).__init__(target, **kwargs)
|
||||||
|
self.gui = UiAutomatorJankTestGUI(self)
|
||||||
|
|
||||||
|
|
||||||
class ApkReventWorkload(ApkUIWorkload):
|
class ApkReventWorkload(ApkUIWorkload):
|
||||||
|
|
||||||
# May be optionally overwritten by subclasses
|
# May be optionally overwritten by subclasses
|
||||||
@ -580,6 +588,85 @@ class UiAutomatorGUI(object):
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
|
class UiAutomatorJankTestGUI(UiAutomatorGUI):
|
||||||
|
|
||||||
|
# The list of jank tests, within the testing class, that should
|
||||||
|
# be invoked.
|
||||||
|
jank_tests = []
|
||||||
|
# The default class for jank testing.
|
||||||
|
uiauto_jank_class = 'UiAutomationJankTests'
|
||||||
|
# The default runner for the jank tests, using androidx.
|
||||||
|
uiauto_runner = 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
|
# Output of each of the executed tests.
|
||||||
|
output = {}
|
||||||
|
|
||||||
|
# A couple regular expressions used to parse frame metrics output by the
|
||||||
|
# android jank tests.
|
||||||
|
_OUTPUT_SECTION_REGEX = re.compile(
|
||||||
|
r'(\s*INSTRUMENTATION_STATUS: gfx-[\w-]+=[-+\d.]+\n)+'
|
||||||
|
r'\s*INSTRUMENTATION_STATUS_CODE: (?P<code>[-+\d]+)\n?', re.M)
|
||||||
|
_OUTPUT_GFXINFO_REGEX = re.compile(
|
||||||
|
r'INSTRUMENTATION_STATUS: (?P<name>[\w-]+)=(?P<value>[-+\d.]+)')
|
||||||
|
|
||||||
|
def __init__(self, owner, package=None, klass='UiAutomation', timeout=600):
|
||||||
|
super(UiAutomatorJankTestGUI, self).__init__(owner, package, klass, timeout)
|
||||||
|
|
||||||
|
def init_commands(self):
|
||||||
|
# Let UiAutomatorGUI handle the initialization of instrumented test
|
||||||
|
# commands.
|
||||||
|
super(UiAutomatorJankTestGUI, self).init_commands()
|
||||||
|
|
||||||
|
# Now initialize the jank test commands.
|
||||||
|
if not self.jank_tests:
|
||||||
|
raise RuntimeError('List of jank tests is empty')
|
||||||
|
|
||||||
|
params_dict = self.uiauto_params
|
||||||
|
params_dict['workdir'] = self.target.working_directory
|
||||||
|
params = ''
|
||||||
|
for k, v in params_dict.iter_encoded_items():
|
||||||
|
params += ' -e {} {}'.format(k, v)
|
||||||
|
|
||||||
|
for test in self.jank_tests:
|
||||||
|
class_string = '{}.{}#{}'.format(self.uiauto_package,
|
||||||
|
self.uiauto_jank_class,
|
||||||
|
test)
|
||||||
|
instrumentation_string = '{}/{}'.format(self.uiauto_package,
|
||||||
|
self.uiauto_runner)
|
||||||
|
cmd_template = 'am instrument -w -r{} -e class {} {}'
|
||||||
|
self.commands[test] = cmd_template.format(params, class_string,
|
||||||
|
instrumentation_string)
|
||||||
|
|
||||||
|
def run(self, timeout=None):
|
||||||
|
if not self.commands:
|
||||||
|
raise RuntimeError('Commands have not been initialized')
|
||||||
|
|
||||||
|
# Validate that each test has been initialized with their own set of commands.
|
||||||
|
for test in self.jank_tests:
|
||||||
|
if not self.commands[test]:
|
||||||
|
raise RuntimeError('Commands for test "{}" not initialized'.format(test))
|
||||||
|
|
||||||
|
# Run the jank tests and capture output for each one of them.
|
||||||
|
for test in self.jank_tests:
|
||||||
|
self.output[test] = self.target.execute(self.commands[test], self.timeout)
|
||||||
|
|
||||||
|
if 'FAILURE' in self.output[test]:
|
||||||
|
raise WorkloadError(self.output[test])
|
||||||
|
else:
|
||||||
|
self.logger.debug(self.output[test])
|
||||||
|
|
||||||
|
def parse_metrics(self, context):
|
||||||
|
# Parse the test results and filter out the metrics so we can output
|
||||||
|
# a meaningful results file.
|
||||||
|
for test, test_output in self.output.items():
|
||||||
|
for section in self._OUTPUT_SECTION_REGEX.finditer(test_output):
|
||||||
|
if int(section.group('code')) != -1:
|
||||||
|
msg = 'Run failed (INSTRUMENTATION_STATUS_CODE: {}). See log.'
|
||||||
|
raise RuntimeError(msg.format(section.group('code')))
|
||||||
|
for metric in self._OUTPUT_GFXINFO_REGEX.finditer(section.group()):
|
||||||
|
context.add_metric(metric.group('name'), metric.group('value'),
|
||||||
|
classifiers={'test_name': test})
|
||||||
|
|
||||||
|
|
||||||
class ReventGUI(object):
|
class ReventGUI(object):
|
||||||
|
|
||||||
def __init__(self, workload, target, setup_timeout, run_timeout,
|
def __init__(self, workload, target, setup_timeout, run_timeout,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user