1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-01-18 20:11:20 +00:00

streamline: cleaned up and added Linux support

- The streamline instrument can now run on linux clients
  because it no longer relies on adb port forwarding
- Updated description.
- Cleaned up code
- Now check for streamline not caiman
- Gatord is now only run once instead of restarted every
  job
This commit is contained in:
Sebastian Goscik 2015-11-13 10:35:31 +00:00
parent 2510329cdf
commit 2063f48cf0

View File

@ -24,7 +24,7 @@ import re
from wlauto import settings, Instrument, Parameter, ResourceGetter, GetterPriority, File
from wlauto.exceptions import InstrumentError, DeviceError, ResourceError
from wlauto.utils.misc import ensure_file_directory_exists as _f
from wlauto.utils.misc import ensure_file_directory_exists as _f, which
from wlauto.utils.types import boolean
from wlauto.utils.log import StreamLogger, LogWriter, LineLogWriter
@ -39,12 +39,12 @@ SESSION_TEXT_TEMPLATE = ('<?xml version="1.0" encoding="US-ASCII" ?>'
' buffer_mode="streaming"'
' sample_rate="none"'
' duration="0"'
' target_host="127.0.0.1"'
' target_host="{}"'
' target_port="{}"'
' energy_cmd_line="{}">'
'</session>')
VERSION_REGEX = re.compile(r'\(DS-5 v(.*?)\)')
VERSION_REGEX = re.compile(r'Streamline (.*?) ')
class StreamlineResourceGetter(ResourceGetter):
@ -104,23 +104,7 @@ class StreamlineInstrument(Instrument):
configuration.xml for the gator. The easiest way to obtain this file is to export it
from event configuration dialog in DS-5 streamline GUI. The file should be called
"configuration.xml" and it be placed in the same directory as the gator binaries.
With that done, you can enable streamline traces by adding the following entry to
instrumentation list in your ~/.workload_automation/config.py
::
instrumentation = [
# ...
'streamline',
# ...
]
You can also specify the following (optional) configuration in the same config file:
"""
supported_platforms = ['android']
parameters = [
Parameter('port', default='8080',
description='Specifies the port on which streamline will connect to gator'),
@ -130,7 +114,7 @@ class StreamlineInstrument(Instrument):
Parameter('report', kind=boolean, default=False, global_alias='streamline_report_csv',
description='Specifies whether a report should be generated from streamline data.'),
Parameter('report_options', kind=str, default='-format csv',
description='A string with options that will be added to stramline -report command.'),
description='A string with options that will be added to streamline -report command.'),
]
daemon = 'gatord'
@ -147,7 +131,6 @@ class StreamlineInstrument(Instrument):
self.configuration_file = None
self.on_device_config = None
self.daemon_process = None
self.enabled = False
self.resource_getter = None
self.host_daemon_file = None
@ -156,26 +139,22 @@ class StreamlineInstrument(Instrument):
self._check_has_valid_display()
def on_run_start(self, context):
if subprocess.call('which caiman', stdout=subprocess.PIPE, shell=True):
raise InstrumentError('caiman not in PATH. Cannot enable Streamline tracing.')
p = subprocess.Popen('caiman --version 2>&1', stdout=subprocess.PIPE, shell=True)
def validate(self):
if not which('streamline'):
raise InstrumentError('streamline not in PATH. Cannot enable Streamline tracing.')
p = subprocess.Popen('streamline --version 2>&1', stdout=subprocess.PIPE, shell=True)
out, _ = p.communicate()
match = VERSION_REGEX.search(out)
if not match:
raise InstrumentError('caiman not in PATH. Cannot enable Streamline tracing.')
raise InstrumentError('Could not find streamline version.')
version_tuple = tuple(map(int, match.group(1).split('.')))
if version_tuple < (5, 17):
raise InstrumentError('Need DS-5 v5.17 or greater; found v{}'.format(match.group(1)))
self.enabled = True
def initialize(self, context):
self.resource_getter = _instantiate(context.resolver)
self.resource_getter.register()
def on_run_end(self, context):
self.enabled = False
self.resource_getter.unregister()
def on_run_init(self, context):
try:
self.host_daemon_file = context.resolver.get(File(self, self.daemon))
self.logger.debug('Using daemon from {}.'.format(self.host_daemon_file))
@ -203,45 +182,44 @@ class StreamlineInstrument(Instrument):
caiman_path = subprocess.check_output('which caiman', shell=True).strip() # pylint: disable=E1103
self.session_file = os.path.join(context.host_working_directory, 'streamline_session.xml')
with open(self.session_file, 'w') as wfh:
wfh.write(SESSION_TEXT_TEMPLATE.format(self.port, caiman_path))
if self.device.platform == "android":
wfh.write(SESSION_TEXT_TEMPLATE.format('127.0.0.1', self.port, caiman_path))
else:
wfh.write(SESSION_TEXT_TEMPLATE.format(self.device.host, self.port, caiman_path))
def setup(self, context):
# Note: the config file needs to be copies on each iteration's setup
# because gator appears to "consume" it on invocation...
if self.configuration_file:
self.device.push_file(self.configuration_file, self.on_device_config)
self._initialize_daemon()
def setup(self, context):
self.capture_file = _f(os.path.join(context.output_directory, 'streamline', 'capture.apc'))
self.report_file = _f(os.path.join(context.output_directory, 'streamline', 'streamline.csv'))
def start(self, context):
if self.enabled:
command = ['streamline', '-capture', self.session_file, '-output', self.capture_file]
self.streamline = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
preexec_fn=os.setpgrp)
outlogger = StreamLogger('streamline', self.streamline.stdout, klass=LineLogWriter)
errlogger = StreamLogger('streamline', self.streamline.stderr, klass=LineLogWriter)
outlogger.start()
errlogger.start()
command = ['streamline', '-capture', self.session_file, '-output', self.capture_file]
self.streamline = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
preexec_fn=os.setpgrp)
outlogger = StreamLogger('streamline', self.streamline.stdout, klass=LineLogWriter)
errlogger = StreamLogger('streamline', self.streamline.stderr, klass=LineLogWriter)
outlogger.start()
errlogger.start()
def stop(self, context):
if self.enabled:
os.killpg(self.streamline.pid, signal.SIGTERM)
os.killpg(self.streamline.pid, signal.SIGTERM)
def update_result(self, context):
if self.enabled:
self._kill_daemon()
if self.report:
self.logger.debug('Creating report...')
command = ['streamline', '-report', self.capture_file, '-output', self.report_file]
command += self.report_options.split()
_run_streamline_command(command)
context.add_artifact('streamlinecsv', self.report_file, 'data')
if self.report:
self.logger.debug('Creating report...')
command = ['streamline', '-report', self.capture_file, '-output', self.report_file]
command += self.report_options.split()
_run_streamline_command(command)
context.add_artifact('streamlinecsv', self.report_file, 'data')
def teardown(self, context):
self._kill_daemon()
self.device.delete_file(self.on_device_config)
def _check_has_valid_display(self): # pylint: disable=R0201
@ -265,8 +243,9 @@ class StreamlineInstrument(Instrument):
raise
self.logger.debug('Driver was already installed.')
self._start_daemon()
port_spec = 'tcp:{}'.format(self.port)
self.device.forward_port(port_spec, port_spec)
if self.device.platform == "android":
port_spec = 'tcp:{}'.format(self.port)
self.device.forward_port(port_spec, port_spec)
def _start_daemon(self):
self.logger.debug('Starting gatord')
@ -274,7 +253,6 @@ class StreamlineInstrument(Instrument):
if self.configuration_file:
command = '{} -c {}'.format(self.daemon, self.on_device_config)
else:
command = '{}'.format(self.daemon)
self.daemon_process = self.device.execute(command, as_root=True, background=True)
@ -299,4 +277,3 @@ def _run_streamline_command(command):
output, error = streamline.communicate()
LogWriter('streamline').write(output).close()
LogWriter('streamline').write(error).close()