mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-01-19 12:24:32 +00:00
166 lines
7.5 KiB
Python
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)
|