summaryrefslogtreecommitdiff
path: root/runner/executor.c
diff options
context:
space:
mode:
authorPetri Latvala <petri.latvala@intel.com>2018-10-10 13:41:00 +0300
committerPetri Latvala <petri.latvala@intel.com>2018-10-19 16:04:14 +0300
commit78619fde4008424c472906041edb1d204e014f7c (patch)
tree52d1284b26f4a54bd4798d01c5f6c4b4e72d63db /runner/executor.c
parent6f27fddc6dd79c0486181b64201c6773c5c42a24 (diff)
runner: Add --overall-timeout
With --overall-timeout $foo, the runner will stop executing new tests when $foo seconds have already been used. A resumed run will start over with no time used, using the same timeout. This allows for executing a long list of tests piecemeal, in about $foo length executions. Signed-off-by: Petri Latvala <petri.latvala@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106127 Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com> Cc: Tomi Sarvela <tomi.p.sarvela@intel.com> Cc: Martin Peres <martin.peres@linux.intel.com> Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Diffstat (limited to 'runner/executor.c')
-rw-r--r--runner/executor.c113
1 files changed, 93 insertions, 20 deletions
diff --git a/runner/executor.c b/runner/executor.c
index 8b87a421..fc79f772 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -335,6 +335,7 @@ static bool kill_child(int sig, pid_t child)
static int monitor_output(pid_t child,
int outfd, int errfd, int kmsgfd, int sigfd,
int *outputs,
+ double *time_spent,
struct settings *settings)
{
fd_set set;
@@ -619,6 +620,9 @@ static int monitor_output(pid_t child,
if (settings->sync) {
fdatasync(outputs[_F_JOURNAL]);
}
+
+ if (time_spent)
+ *time_spent = time;
}
close(sigfd);
@@ -698,17 +702,30 @@ static int digits(size_t num)
return ret;
}
+static void print_time_left(struct execute_state *state,
+ struct settings *settings)
+{
+ int width;
+
+ if (settings->overall_timeout <= 0)
+ return;
+
+ width = digits(settings->overall_timeout);
+ printf("(%*.0fs left) ", width, state->time_left);
+}
+
/*
* Returns:
* =0 - Success
* <0 - Failure executing
* >0 - Timeout happened, need to recreate from journal
*/
-static int execute_entry(size_t idx,
- size_t total,
- struct settings *settings,
- struct job_list_entry *entry,
- int testdirfd, int resdirfd)
+static int execute_next_entry(struct execute_state *state,
+ size_t total,
+ double *time_spent,
+ struct settings *settings,
+ struct job_list_entry *entry,
+ int testdirfd, int resdirfd)
{
int dirfd;
int outputs[_F_LAST];
@@ -720,6 +737,7 @@ static int execute_entry(size_t idx,
char name[32];
pid_t child;
int result;
+ size_t idx = state->next;
snprintf(name, sizeof(name), "%zd", idx);
mkdirat(resdirfd, name, 0777);
@@ -780,7 +798,12 @@ static int execute_entry(size_t idx,
if (settings->log_level >= LOG_LEVEL_NORMAL) {
int width = digits(total);
- printf("[%0*zd/%0*zd] %s", width, idx + 1, width, total, entry->binary);
+ printf("[%0*zd/%0*zd] ", width, idx + 1, width, total);
+
+ print_time_left(state, settings);
+
+ printf("%s", entry->binary);
+
if (entry->subtest_count > 0) {
size_t i;
const char *delim = "";
@@ -792,6 +815,7 @@ static int execute_entry(size_t idx,
}
printf(")");
}
+
printf("\n");
}
@@ -810,7 +834,7 @@ static int execute_entry(size_t idx,
close(errpipe[1]);
result = monitor_output(child, outfd, errfd, kmsgfd, sigfd,
- outputs, settings);
+ outputs, time_spent, settings);
} else {
int outfd = outpipe[1];
int errfd = errpipe[1];
@@ -913,6 +937,15 @@ static double timeofday_double()
return 0.0;
}
+static void init_time_left(struct execute_state *state,
+ struct settings *settings)
+{
+ if (settings->overall_timeout <= 0)
+ state->time_left = -1;
+ else
+ state->time_left = settings->overall_timeout;
+}
+
bool initialize_execute_state_from_resume(int dirfd,
struct execute_state *state,
struct settings *settings,
@@ -931,6 +964,8 @@ bool initialize_execute_state_from_resume(int dirfd,
return false;
}
+ init_time_left(state, settings);
+
for (i = list->size; i >= 0; i--) {
char name[32];
@@ -986,15 +1021,37 @@ bool initialize_execute_state(struct execute_state *state,
!clear_old_results(settings->results_path))
return false;
+ init_time_left(state, settings);
+
return true;
}
+static void reduce_time_left(struct settings *settings,
+ struct execute_state *state,
+ double time_spent)
+{
+ if (state->time_left < 0)
+ return;
+
+ if (time_spent > state->time_left)
+ state->time_left = 0.0;
+ else
+ state->time_left -= time_spent;
+}
+
+static bool overall_timeout_exceeded(struct execute_state *state)
+{
+ return state->time_left == 0.0;
+}
+
bool execute(struct execute_state *state,
struct settings *settings,
struct job_list *job_list)
{
struct utsname unamebuf;
int resdirfd, testdirfd, unamefd, timefd;
+ double time_spent = 0.0;
+ bool status = true;
if ((resdirfd = open(settings->results_path, O_DIRECTORY | O_RDONLY)) < 0) {
/* Initialize state should have done this */
@@ -1045,20 +1102,36 @@ bool execute(struct execute_state *state,
for (; state->next < job_list->size;
state->next++) {
- int result = execute_entry(state->next,
- job_list->size,
- settings,
- &job_list->entries[state->next],
- testdirfd, resdirfd);
- if (result != 0) {
+ int result = execute_next_entry(state,
+ job_list->size,
+ &time_spent,
+ settings,
+ &job_list->entries[state->next],
+ testdirfd, resdirfd);
+
+ if (result < 0) {
+ status = false;
+ break;
+ }
+
+ reduce_time_left(settings, state, time_spent);
+
+ if (overall_timeout_exceeded(state)) {
+ if (settings->log_level >= LOG_LEVEL_NORMAL) {
+ printf("Overall timeout time exceeded, stopping.\n");
+ }
+
+ break;
+ }
+
+ if (result > 0) {
+ double time_left = state->time_left;
+
close(testdirfd);
close_watchdogs(settings);
- if (result > 0) {
- initialize_execute_state_from_resume(resdirfd, state, settings, job_list);
- return execute(state, settings, job_list);
- }
- close(resdirfd);
- return false;
+ initialize_execute_state_from_resume(resdirfd, state, settings, job_list);
+ state->time_left = time_left;
+ return execute(state, settings, job_list);
}
}
@@ -1070,5 +1143,5 @@ bool execute(struct execute_state *state,
close(testdirfd);
close(resdirfd);
close_watchdogs(settings);
- return true;
+ return status;
}