1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-07 13:41:24 +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 import settings, Instrument, Parameter, ResourceGetter, GetterPriority, File
from wlauto.exceptions import InstrumentError, DeviceError, ResourceError 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.types import boolean
from wlauto.utils.log import StreamLogger, LogWriter, LineLogWriter 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"' ' buffer_mode="streaming"'
' sample_rate="none"' ' sample_rate="none"'
' duration="0"' ' duration="0"'
' target_host="127.0.0.1"' ' target_host="{}"'
' target_port="{}"' ' target_port="{}"'
' energy_cmd_line="{}">' ' energy_cmd_line="{}">'
'</session>') '</session>')
VERSION_REGEX = re.compile(r'\(DS-5 v(.*?)\)') VERSION_REGEX = re.compile(r'Streamline (.*?) ')
class StreamlineResourceGetter(ResourceGetter): 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 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 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. "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 = [ parameters = [
Parameter('port', default='8080', Parameter('port', default='8080',
description='Specifies the port on which streamline will connect to gator'), 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', Parameter('report', kind=boolean, default=False, global_alias='streamline_report_csv',
description='Specifies whether a report should be generated from streamline data.'), description='Specifies whether a report should be generated from streamline data.'),
Parameter('report_options', kind=str, default='-format csv', 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' daemon = 'gatord'
@ -147,7 +131,6 @@ class StreamlineInstrument(Instrument):
self.configuration_file = None self.configuration_file = None
self.on_device_config = None self.on_device_config = None
self.daemon_process = None self.daemon_process = None
self.enabled = False
self.resource_getter = None self.resource_getter = None
self.host_daemon_file = None self.host_daemon_file = None
@ -156,26 +139,22 @@ class StreamlineInstrument(Instrument):
self._check_has_valid_display() self._check_has_valid_display()
def on_run_start(self, context): def validate(self):
if subprocess.call('which caiman', stdout=subprocess.PIPE, shell=True): if not which('streamline'):
raise InstrumentError('caiman not in PATH. Cannot enable Streamline tracing.') raise InstrumentError('streamline not in PATH. Cannot enable Streamline tracing.')
p = subprocess.Popen('caiman --version 2>&1', stdout=subprocess.PIPE, shell=True) p = subprocess.Popen('streamline --version 2>&1', stdout=subprocess.PIPE, shell=True)
out, _ = p.communicate() out, _ = p.communicate()
match = VERSION_REGEX.search(out) match = VERSION_REGEX.search(out)
if not match: 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('.'))) version_tuple = tuple(map(int, match.group(1).split('.')))
if version_tuple < (5, 17): if version_tuple < (5, 17):
raise InstrumentError('Need DS-5 v5.17 or greater; found v{}'.format(match.group(1))) 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 = _instantiate(context.resolver)
self.resource_getter.register() self.resource_getter.register()
def on_run_end(self, context):
self.enabled = False
self.resource_getter.unregister()
def on_run_init(self, context):
try: try:
self.host_daemon_file = context.resolver.get(File(self, self.daemon)) self.host_daemon_file = context.resolver.get(File(self, self.daemon))
self.logger.debug('Using daemon from {}.'.format(self.host_daemon_file)) self.logger.debug('Using daemon from {}.'.format(self.host_daemon_file))
@ -203,19 +182,20 @@ class StreamlineInstrument(Instrument):
caiman_path = subprocess.check_output('which caiman', shell=True).strip() # pylint: disable=E1103 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') self.session_file = os.path.join(context.host_working_directory, 'streamline_session.xml')
with open(self.session_file, 'w') as wfh: 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: if self.configuration_file:
self.device.push_file(self.configuration_file, self.on_device_config) self.device.push_file(self.configuration_file, self.on_device_config)
self._initialize_daemon() self._initialize_daemon()
def setup(self, context):
self.capture_file = _f(os.path.join(context.output_directory, 'streamline', 'capture.apc')) 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')) self.report_file = _f(os.path.join(context.output_directory, 'streamline', 'streamline.csv'))
def start(self, context): def start(self, context):
if self.enabled:
command = ['streamline', '-capture', self.session_file, '-output', self.capture_file] command = ['streamline', '-capture', self.session_file, '-output', self.capture_file]
self.streamline = subprocess.Popen(command, self.streamline = subprocess.Popen(command,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -228,12 +208,9 @@ class StreamlineInstrument(Instrument):
errlogger.start() errlogger.start()
def stop(self, context): 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): def update_result(self, context):
if self.enabled:
self._kill_daemon()
if self.report: if self.report:
self.logger.debug('Creating report...') self.logger.debug('Creating report...')
command = ['streamline', '-report', self.capture_file, '-output', self.report_file] command = ['streamline', '-report', self.capture_file, '-output', self.report_file]
@ -242,6 +219,7 @@ class StreamlineInstrument(Instrument):
context.add_artifact('streamlinecsv', self.report_file, 'data') context.add_artifact('streamlinecsv', self.report_file, 'data')
def teardown(self, context): def teardown(self, context):
self._kill_daemon()
self.device.delete_file(self.on_device_config) self.device.delete_file(self.on_device_config)
def _check_has_valid_display(self): # pylint: disable=R0201 def _check_has_valid_display(self): # pylint: disable=R0201
@ -265,6 +243,7 @@ class StreamlineInstrument(Instrument):
raise raise
self.logger.debug('Driver was already installed.') self.logger.debug('Driver was already installed.')
self._start_daemon() self._start_daemon()
if self.device.platform == "android":
port_spec = 'tcp:{}'.format(self.port) port_spec = 'tcp:{}'.format(self.port)
self.device.forward_port(port_spec, port_spec) self.device.forward_port(port_spec, port_spec)
@ -274,7 +253,6 @@ class StreamlineInstrument(Instrument):
if self.configuration_file: if self.configuration_file:
command = '{} -c {}'.format(self.daemon, self.on_device_config) command = '{} -c {}'.format(self.daemon, self.on_device_config)
else: else:
command = '{}'.format(self.daemon) command = '{}'.format(self.daemon)
self.daemon_process = self.device.execute(command, as_root=True, background=True) 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() output, error = streamline.communicate()
LogWriter('streamline').write(output).close() LogWriter('streamline').write(output).close()
LogWriter('streamline').write(error).close() LogWriter('streamline').write(error).close()