1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-01-19 04:21:17 +00:00
Waleed El-Geresy 6d9a03ad8f ReventWorkload: Move class to linux and add features
The ReventWorkload class has been moved to the linux directory and
two new features have been added: the option to run an idle workload
and the option to specify a .teardown revent file as well as a .setup file
which runs in the eponymous stage.
2017-08-09 14:18:38 +01:00

166 lines
7.5 KiB
Python

# Copyright 2017 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
from math import ceil
from wlauto.core.extension import Parameter
from wlauto.core.workload import Workload
from wlauto.core.resource import NO_ONE
from wlauto.common.resources import Executable
from wlauto.common.android.resources import ReventFile
from wlauto.exceptions import WorkloadError
from wlauto.utils.revent import ReventRecording
class ReventWorkload(Workload):
# pylint: disable=attribute-defined-outside-init
description = """
A workload for playing back revent recordings. You can supply three
different files:
1. {device_model}.setup.revent
2. {device_model}.run.revent
3. {device_model}.teardown.revent
You may generate these files using the wa record command using the -s flag
to specify the stage (``setup``, ``run``, ``teardown``)
You may also supply an 'idle_time' in seconds in place of the run file.
The ``run`` file may only be omitted if you choose to run this way, but
while running idle may supply ``setup`` and ``teardown`` files.
To use a ``setup`` or ``teardown`` file set the setup_required and/or
teardown_required class attributes to True (default: False).
N.B. This is the default description. You may overwrite this for your
workload to include more specific information.
"""
setup_required = False
teardown_required = False
parameters = [
Parameter(
'idle_time', kind=int, default=None,
description='''
The time you wish the device to remain idle for (if a value is
given then this overrides any .run revent file).
'''),
]
def __init__(self, device, _call_super=True, **kwargs):
if _call_super:
Workload.__init__(self, device, **kwargs)
self.setup_timeout = kwargs.get('setup_timeout', None)
self.run_timeout = kwargs.get('run_timeout', None)
self.teardown_timeout = kwargs.get('teardown_timeout', None)
self.revent_setup_file = None
self.revent_run_file = None
self.revent_teardown_file = None
self.on_device_setup_revent = None
self.on_device_run_revent = None
self.on_device_teardown_revent = None
self.statedefs_dir = None
def initialize(self, context):
devpath = self.device.path
self.on_device_revent_binary = devpath.join(self.device.binaries_directory, 'revent')
def setup(self, context):
devpath = self.device.path
if self.setup_required:
self.revent_setup_file = context.resolver.get(ReventFile(self, 'setup'))
if self.revent_setup_file:
self.on_device_setup_revent = devpath.join(self.device.working_directory,
os.path.split(self.revent_setup_file)[-1])
duration = ReventRecording(self.revent_setup_file).duration
self.default_setup_timeout = ceil(duration) + 30
if not self.idle_time:
self.revent_run_file = context.resolver.get(ReventFile(self, 'run'))
if self.revent_run_file:
self.on_device_run_revent = devpath.join(self.device.working_directory,
os.path.split(self.revent_run_file)[-1])
self.default_run_timeout = ceil(ReventRecording(self.revent_run_file).duration) + 30
if self.teardown_required:
self.revent_teardown_file = context.resolver.get(ReventFile(self, 'teardown'))
if self.revent_teardown_file:
self.on_device_teardown_revent = devpath.join(self.device.working_directory,
os.path.split(self.revent_teardown_file)[-1])
duration = ReventRecording(self.revent_teardown_file).duration
self.default_teardown_timeout = ceil(duration) + 30
self._check_revent_files(context)
Workload.setup(self, context)
if self.revent_setup_file is not None:
self.setup_timeout = self.setup_timeout or self.default_setup_timeout
self.device.killall('revent')
command = '{} replay {}'.format(self.on_device_revent_binary, self.on_device_setup_revent)
self.device.execute(command, timeout=self.setup_timeout)
self.logger.debug('Revent setup completed.')
def run(self, context):
if not self.idle_time:
self.run_timeout = self.run_timeout or self.default_run_timeout
command = '{} replay {}'.format(self.on_device_revent_binary, self.on_device_run_revent)
self.logger.debug('Replaying {}'.format(os.path.basename(self.on_device_run_revent)))
self.device.execute(command, timeout=self.run_timeout)
self.logger.debug('Replay completed.')
else:
self.logger.info('Idling for ' + str(self.idle_time) + ' seconds.')
self.device.sleep(self.idle_time)
self.logger.info('Successfully did nothing for ' + str(self.idle_time) + ' seconds!')
def update_result(self, context):
pass
def teardown(self, context):
if self.revent_teardown_file is not None:
self.teardown_timeout = self.teardown_timeout or self.default_teardown_timeout
command = '{} replay {}'.format(self.on_device_revent_binary,
self.on_device_teardown_revent)
self.device.execute(command, timeout=self.teardown_timeout)
self.logger.debug('Replay completed.')
self.device.killall('revent')
if self.revent_setup_file is not None:
self.device.delete_file(self.on_device_setup_revent)
if not self.idle_time:
self.device.delete_file(self.on_device_run_revent)
if self.revent_teardown_file is not None:
self.device.delete_file(self.on_device_teardown_revent)
def _check_revent_files(self, context):
# check the revent binary
revent_binary = context.resolver.get(Executable(NO_ONE, self.device.abi, 'revent'))
if not os.path.isfile(revent_binary):
message = '{} does not exist. '.format(revent_binary)
message += 'Please build revent for your system and place it in that location'
raise WorkloadError(message)
if not self.revent_run_file and not self.idle_time:
# pylint: disable=too-few-format-args
message = 'It seems a {0}.run.revent file does not exist, '\
'Please provide one for your device: {0}.'
raise WorkloadError(message.format(self.device.name))
self.on_device_revent_binary = self.device.install_executable(revent_binary)
if self.revent_setup_file is not None:
self.device.push_file(self.revent_setup_file, self.on_device_setup_revent)
if not self.idle_time:
self.device.push_file(self.revent_run_file, self.on_device_run_revent)
if self.revent_teardown_file is not None:
self.device.push_file(self.revent_teardown_file, self.on_device_teardown_revent)