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:
parent
2510329cdf
commit
2063f48cf0
@ -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()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user