1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-06 19:01:15 +01:00

file_poller: added error checking and reporting

- Updated poller binary to propery check for errors (e.g. on attempting
  to open a file) and report them to stderr
- Updated the file_poller instrument to collect poller stderr output
  into a log file and to check the log for errors or warnings on
  completion of an iteration.
This commit is contained in:
Sergei Trofimov 2016-07-11 13:20:50 +01:00
parent 5a780e8211
commit 1fe037486f
4 changed files with 63 additions and 25 deletions

View File

@ -12,9 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=access-member-before-definition,attribute-defined-outside-init,unused-argument
import os
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
@ -27,8 +28,8 @@ class FilePoller(Instrument):
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.
This instrument can poll any file whos contents do not contain a new line since this
breaks the CSV formatting.
This instrument will strip any commas or new lines for the files' values
before writing them.
"""
parameters = [
@ -56,7 +57,7 @@ class FilePoller(Instrument):
raise ConfigError('The device is not rooted, cannot run poller as root.')
host_poller = context.resolver.get(Executable(self, self.device.abi,
"poller"))
target_poller = self.device.install_if_needed(host_poller)
target_poller = self.device.install(host_poller)
expanded_paths = []
for path in self.files:
@ -70,11 +71,13 @@ class FilePoller(Instrument):
self.labels = self._generate_labels()
self.target_output_path = self.device.path.join(self.device.working_directory, 'poller.csv')
self.command = '{} -t {} -l {} {} > {}'.format(target_poller,
self.sample_interval * 1000,
','.join(self.labels),
' '.join(self.files),
self.target_output_path)
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,
','.join(self.labels),
' '.join(self.files),
self.target_output_path,
self.target_log_path)
def start(self, context):
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)
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):
self.device.delete_file(self.target_output_path)
self.device.delete_file(self.target_log_path)
def _generate_labels(self):
# Split paths into their parts

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

Binary file not shown.

View File

@ -14,7 +14,6 @@ void term(int signum)
done = 1;
}
// From: http://stackoverflow.com/questions/1515195/how-to-remove-n-or-t-from-a-given-string-in-c
void strip(char *s) {
char *stripped_s = s;
while(*s != '\0') {
@ -27,6 +26,11 @@ void strip(char *s) {
*stripped_s = '\0';
}
typedef struct {
int fd;
char *path;
} poll_source_t;
int main(int argc, char ** argv) {
extern char *optarg;
@ -38,9 +42,9 @@ int main(int argc, char ** argv) {
memset(buf, 0, sizeof(buf));
struct timeval current_time;
double time_float;
int files_to_poll[argc-optind];
char *labels;
int labelCount = 0;
static char usage[] = "usage: %s [-h] [-t INTERVAL] FILE [FILE ...]\n"
"polls FILE(s) every INTERVAL microseconds and outputs\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) {
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]);
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],
labelCount,
argc-optind);
fprintf(stderr, "ERROR: %s: %d labels specified but %d files specified\n",
argv[0], labelCount, num_files);
fprintf(stderr, usage, argv[0]);
exit(1);
}
@ -100,9 +106,16 @@ int main(int argc, char ** argv) {
printf(",%s", labels);
}
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) {
printf(",%s", argv[optind + i]);
}
@ -115,15 +128,24 @@ int main(int argc, char ** argv) {
action.sa_handler = term;
sigaction(SIGTERM, &action, NULL);
//Poll files
//Poll files
int bytes_read = 0;
while (!done) {
gettimeofday(&current_time, NULL);
time_float = (double)current_time.tv_sec;
time_float += ((double)current_time.tv_usec)/1000/1000;
printf("%f", time_float);
for (i = 0; i < (argc - optind); i++) {
read(files_to_poll[i], buf, 1024);
lseek(files_to_poll[i], 0, SEEK_SET);
for (i = 0; i < num_files; i++) {
lseek(files_to_poll[i].fd, 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);
printf(",%s", buf);
buf[0] = '\0'; // "Empty" buffer
@ -133,9 +155,9 @@ int main(int argc, char ** argv) {
}
//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);
}