mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-01-19 12:24:32 +00:00
commit
246416d4d2
@ -598,6 +598,7 @@ class LinuxDevice(BaseLinuxDevice):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def is_rooted(self):
|
def is_rooted(self):
|
||||||
|
self._check_ready()
|
||||||
if self._is_rooted is None:
|
if self._is_rooted is None:
|
||||||
# First check if the user is root
|
# First check if the user is root
|
||||||
try:
|
try:
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
# pylint: disable=access-member-before-definition,attribute-defined-outside-init,unused-argument
|
# pylint: disable=access-member-before-definition,attribute-defined-outside-init,unused-argument
|
||||||
|
import os
|
||||||
|
|
||||||
from wlauto import Instrument, Parameter, Executable
|
from wlauto import Instrument, Parameter, Executable
|
||||||
from wlauto.exceptions import ConfigError
|
from wlauto.exceptions import ConfigError, InstrumentError
|
||||||
from wlauto.utils.types import list_or_string
|
from wlauto.utils.types import list_or_string
|
||||||
|
|
||||||
|
|
||||||
@ -27,8 +28,8 @@ class FilePoller(Instrument):
|
|||||||
This file will contain a timestamp column which will be in uS, the rest of the columns
|
This file will contain a timestamp column which will be in uS, the rest of the columns
|
||||||
will be the contents of the polled files at that time.
|
will be the contents of the polled files at that time.
|
||||||
|
|
||||||
This instrument can poll any file whos contents do not contain a new line since this
|
This instrument will strip any commas or new lines for the files' values
|
||||||
breaks the CSV formatting.
|
before writing them.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
parameters = [
|
parameters = [
|
||||||
@ -48,15 +49,15 @@ class FilePoller(Instrument):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.device.is_rooted and self.as_root:
|
|
||||||
raise ConfigError('The device is not rooted, cannot run poller as root.')
|
|
||||||
if self.labels and any(['*' in f for f in self.files]):
|
if self.labels and any(['*' in f for f in self.files]):
|
||||||
raise ConfigError('You cannot used manual labels with `*` wildcards')
|
raise ConfigError('You cannot used manual labels with `*` wildcards')
|
||||||
|
|
||||||
def initialize(self, context):
|
def initialize(self, context):
|
||||||
|
if not self.device.is_rooted and self.as_root:
|
||||||
|
raise ConfigError('The device is not rooted, cannot run poller as root.')
|
||||||
host_poller = context.resolver.get(Executable(self, self.device.abi,
|
host_poller = context.resolver.get(Executable(self, self.device.abi,
|
||||||
"poller"))
|
"poller"))
|
||||||
target_poller = self.device.install_if_needed(host_poller)
|
target_poller = self.device.install(host_poller)
|
||||||
|
|
||||||
expanded_paths = []
|
expanded_paths = []
|
||||||
for path in self.files:
|
for path in self.files:
|
||||||
@ -70,11 +71,13 @@ class FilePoller(Instrument):
|
|||||||
self.labels = self._generate_labels()
|
self.labels = self._generate_labels()
|
||||||
|
|
||||||
self.target_output_path = self.device.path.join(self.device.working_directory, 'poller.csv')
|
self.target_output_path = self.device.path.join(self.device.working_directory, 'poller.csv')
|
||||||
self.command = '{} -t {} -l {} {} > {}'.format(target_poller,
|
self.target_log_path = self.device.path.join(self.device.working_directory, 'poller.log')
|
||||||
|
self.command = '{} -t {} -l {} {} > {} 2>{}'.format(target_poller,
|
||||||
self.sample_interval * 1000,
|
self.sample_interval * 1000,
|
||||||
','.join(self.labels),
|
','.join(self.labels),
|
||||||
' '.join(self.files),
|
' '.join(self.files),
|
||||||
self.target_output_path)
|
self.target_output_path,
|
||||||
|
self.target_log_path)
|
||||||
|
|
||||||
def start(self, context):
|
def start(self, context):
|
||||||
self.device.kick_off(self.command, as_root=self.as_root)
|
self.device.kick_off(self.command, as_root=self.as_root)
|
||||||
@ -83,10 +86,23 @@ class FilePoller(Instrument):
|
|||||||
self.device.killall('poller', signal='TERM', as_root=self.as_root)
|
self.device.killall('poller', signal='TERM', as_root=self.as_root)
|
||||||
|
|
||||||
def update_result(self, context):
|
def update_result(self, context):
|
||||||
self.device.pull_file(self.target_output_path, context.output_directory)
|
host_output_file = os.path.join(context.output_directory, 'poller.csv')
|
||||||
|
self.device.pull_file(self.target_output_path, host_output_file)
|
||||||
|
context.add_artifact('poller_output', host_output_file, kind='data')
|
||||||
|
host_log_file = os.path.join(context.output_directory, 'poller.log')
|
||||||
|
self.device.pull_file(self.target_log_path, host_log_file)
|
||||||
|
context.add_artifact('poller_log', host_log_file, kind='log')
|
||||||
|
|
||||||
|
with open(host_log_file) as fh:
|
||||||
|
for line in fh:
|
||||||
|
if 'ERROR' in line:
|
||||||
|
raise InstrumentError(line.strip())
|
||||||
|
if 'WARNING' in line:
|
||||||
|
self.logger.warning(line.strip())
|
||||||
|
|
||||||
def teardown(self, context):
|
def teardown(self, context):
|
||||||
self.device.delete_file(self.target_output_path)
|
self.device.delete_file(self.target_output_path)
|
||||||
|
self.device.delete_file(self.target_log_path)
|
||||||
|
|
||||||
def _generate_labels(self):
|
def _generate_labels(self):
|
||||||
# Split paths into their parts
|
# Split paths into their parts
|
||||||
|
BIN
wlauto/instrumentation/poller/bin/arm64/poller
Normal file → Executable file
BIN
wlauto/instrumentation/poller/bin/arm64/poller
Normal file → Executable file
Binary file not shown.
BIN
wlauto/instrumentation/poller/bin/armeabi/poller
Normal file → Executable file
BIN
wlauto/instrumentation/poller/bin/armeabi/poller
Normal file → Executable file
Binary file not shown.
@ -14,7 +14,6 @@ void term(int signum)
|
|||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From: http://stackoverflow.com/questions/1515195/how-to-remove-n-or-t-from-a-given-string-in-c
|
|
||||||
void strip(char *s) {
|
void strip(char *s) {
|
||||||
char *stripped_s = s;
|
char *stripped_s = s;
|
||||||
while(*s != '\0') {
|
while(*s != '\0') {
|
||||||
@ -27,6 +26,11 @@ void strip(char *s) {
|
|||||||
*stripped_s = '\0';
|
*stripped_s = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int fd;
|
||||||
|
char *path;
|
||||||
|
} poll_source_t;
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
@ -38,9 +42,9 @@ int main(int argc, char ** argv) {
|
|||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
struct timeval current_time;
|
struct timeval current_time;
|
||||||
double time_float;
|
double time_float;
|
||||||
int files_to_poll[argc-optind];
|
|
||||||
char *labels;
|
char *labels;
|
||||||
int labelCount = 0;
|
int labelCount = 0;
|
||||||
|
|
||||||
static char usage[] = "usage: %s [-h] [-t INTERVAL] FILE [FILE ...]\n"
|
static char usage[] = "usage: %s [-h] [-t INTERVAL] FILE [FILE ...]\n"
|
||||||
"polls FILE(s) every INTERVAL microseconds and outputs\n"
|
"polls FILE(s) every INTERVAL microseconds and outputs\n"
|
||||||
"the results in CSV format including a timestamp to STDOUT\n"
|
"the results in CSV format including a timestamp to STDOUT\n"
|
||||||
@ -79,16 +83,18 @@ int main(int argc, char ** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (optind >= argc) {
|
if (optind >= argc) {
|
||||||
fprintf(stderr, "%s: missiing file path(s)\n", argv[0]);
|
fprintf(stderr, "ERROR: %s: missing file path(s)\n", argv[0]);
|
||||||
fprintf(stderr, usage, argv[0]);
|
fprintf(stderr, usage, argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labelCount && labelCount != argc-optind)
|
int num_files = argc - optind;
|
||||||
|
poll_source_t files_to_poll[num_files];
|
||||||
|
|
||||||
|
if (labelCount && labelCount != num_files)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: %d labels specified but %d files specified\n", argv[0],
|
fprintf(stderr, "ERROR: %s: %d labels specified but %d files specified\n",
|
||||||
labelCount,
|
argv[0], labelCount, num_files);
|
||||||
argc-optind);
|
|
||||||
fprintf(stderr, usage, argv[0]);
|
fprintf(stderr, usage, argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -100,9 +106,16 @@ int main(int argc, char ** argv) {
|
|||||||
printf(",%s", labels);
|
printf(",%s", labels);
|
||||||
}
|
}
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < (argc - optind); i++)
|
for (i = 0; i < num_files; i++)
|
||||||
{
|
{
|
||||||
files_to_poll[i] = open(argv[optind + i], O_RDONLY);
|
files_to_poll[i].path = argv[optind + i];
|
||||||
|
files_to_poll[i].fd = open(files_to_poll[i].path, O_RDONLY);
|
||||||
|
if (files_to_poll[i].fd == -1) {
|
||||||
|
fprintf(stderr, "ERROR: Could not open \"%s\", got: %s\n",
|
||||||
|
files_to_poll[i].path, strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
if(!labelCount) {
|
if(!labelCount) {
|
||||||
printf(",%s", argv[optind + i]);
|
printf(",%s", argv[optind + i]);
|
||||||
}
|
}
|
||||||
@ -116,14 +129,23 @@ int main(int argc, char ** argv) {
|
|||||||
sigaction(SIGTERM, &action, NULL);
|
sigaction(SIGTERM, &action, NULL);
|
||||||
|
|
||||||
//Poll files
|
//Poll files
|
||||||
|
int bytes_read = 0;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
gettimeofday(¤t_time, NULL);
|
gettimeofday(¤t_time, NULL);
|
||||||
time_float = (double)current_time.tv_sec;
|
time_float = (double)current_time.tv_sec;
|
||||||
time_float += ((double)current_time.tv_usec)/1000/1000;
|
time_float += ((double)current_time.tv_usec)/1000/1000;
|
||||||
printf("%f", time_float);
|
printf("%f", time_float);
|
||||||
for (i = 0; i < (argc - optind); i++) {
|
for (i = 0; i < num_files; i++) {
|
||||||
read(files_to_poll[i], buf, 1024);
|
lseek(files_to_poll[i].fd, 0, SEEK_SET);
|
||||||
lseek(files_to_poll[i], 0, SEEK_SET);
|
bytes_read = read(files_to_poll[i].fd, buf, 1024);
|
||||||
|
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
fprintf(stderr, "WARNING: Read nothing from \"%s\"\n",
|
||||||
|
files_to_poll[i].path);
|
||||||
|
printf(",");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
strip(buf);
|
strip(buf);
|
||||||
printf(",%s", buf);
|
printf(",%s", buf);
|
||||||
buf[0] = '\0'; // "Empty" buffer
|
buf[0] = '\0'; // "Empty" buffer
|
||||||
@ -133,9 +155,9 @@ int main(int argc, char ** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Close files
|
//Close files
|
||||||
for (i = 0; i < (argc - optind); i++)
|
for (i = 0; i < num_files; i++)
|
||||||
{
|
{
|
||||||
files_to_poll[i] = open(argv[optind + i], O_RDONLY);
|
close(files_to_poll[i].fd);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user