diff options
author | Petri Latvala <petri.latvala@intel.com> | 2018-11-09 13:13:03 +0200 |
---|---|---|
committer | Petri Latvala <petri.latvala@intel.com> | 2018-11-15 10:35:23 +0200 |
commit | 111593c49d812a4f4ff9ab0ef053a3ab88a6f73f (patch) | |
tree | 7f8a34859645b3972bc587af663c7530abdec24a /runner/settings.c | |
parent | cab148ca3ec904a94d0cd43476cf7e1f8663f906 (diff) |
runner: Implement --abort-on-monitored-error
Deviating a bit from the piglit command line flag, igt_runner takes an
optional comma-separated list as an argument to
--abort-on-monitored-error for the list of conditions to abort
on. Without a list all possible conditions will be checked.
Two conditions implemented:
- "taint" checks the kernel taint level for TAINT_PAGE, TAINT_DIE and
TAINT_OOPS
- "lockdep" checks the kernel lockdep status
Checking is done after every test binary execution, and if an abort
condition is met, the reason is printed to stderr (unless log level is
quiet) and the runner doesn't execute any further tests. Aborting
between subtests (when running in --multiple-mode) is not done.
v2:
- Remember to fclose
- Taints are unsigned long (Chris)
- Use getline instead of fgets (Chris)
v3:
- Fix brainfart with lockdep
v4:
- Rebase
- Refactor the abort condition checking to pass down strings
- Present the abort result in results.json as a pseudo test result
- Unit tests for the pseudo result
v5:
- Refactors (Chris)
- Don't claim lockdep was triggered if debug_locks is not on
anymore. Just say it's not active.
- Dump lockdep_stats when aborting due to lockdep (Chris)
- Use igt@runner@aborted instead for the pseudo result (Martin)
v6:
- If aborting after a test, generate results.json. Like was already
done for aborting at startup.
- Print the test that would be executed next as well when aborting,
as requested by Tomi.
v7:
- Remove the resolved TODO item from commit message
Signed-off-by: Petri Latvala <petri.latvala@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Tomi Sarvela <tomi.p.sarvela@intel.com>
Cc: Martin Peres <martin.peres@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Diffstat (limited to 'runner/settings.c')
-rw-r--r-- | runner/settings.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/runner/settings.c b/runner/settings.c index e2401455..e64244e6 100644 --- a/runner/settings.c +++ b/runner/settings.c @@ -41,6 +41,16 @@ static struct { { 0, 0 }, }; +static struct { + int value; + const char *name; +} abort_conditions[] = { + { ABORT_TAINT, "taint" }, + { ABORT_LOCKDEP, "lockdep" }, + { ABORT_ALL, "all" }, + { 0, 0 }, +}; + static bool set_log_level(struct settings* settings, const char *level) { typeof(*log_levels) *it; @@ -55,6 +65,56 @@ static bool set_log_level(struct settings* settings, const char *level) return false; } +static bool set_abort_condition(struct settings* settings, const char *cond) +{ + typeof(*abort_conditions) *it; + + if (!cond) { + settings->abort_mask = ABORT_ALL; + return true; + } + + if (strlen(cond) == 0) { + settings->abort_mask = 0; + return true; + } + + for (it = abort_conditions; it->name; it++) { + if (!strcmp(cond, it->name)) { + settings->abort_mask |= it->value; + return true; + } + } + + return false; +} + +static bool parse_abort_conditions(struct settings *settings, const char *optarg) +{ + char *dup, *origdup, *p; + if (!optarg) + return set_abort_condition(settings, NULL); + + origdup = dup = strdup(optarg); + while (dup) { + if ((p = strchr(dup, ',')) != NULL) { + *p = '\0'; + p++; + } + + if (!set_abort_condition(settings, dup)) { + free(origdup); + return false; + } + + dup = p; + } + + free(origdup); + + return true; +} + static const char *usage_str = "usage: runner [options] [test_root] results-path\n\n" "Options:\n" @@ -67,9 +127,15 @@ static const char *usage_str = " Run only matching tests (can be used more than once)\n" " -x <regex>, --exclude-tests <regex>\n" " Exclude matching tests (can be used more than once)\n" - " --abort-on-monitored-error\n" + " --abort-on-monitored-error[=list]\n" " Abort execution when a fatal condition is detected.\n" - " <TODO>\n" + " A comma-separated list of conditions to check can be\n" + " given. If not given, all conditions are checked. An\n" + " empty string as a condition disables aborting\n" + " Possible conditions:\n" + " lockdep - abort when kernel lockdep has been angered.\n" + " taint - abort when kernel becomes fatally tainted.\n" + " all - abort for all of the above.\n" " -s, --sync Sync results to disk after every test\n" " -l {quiet,verbose,dummy}, --log-level {quiet,verbose,dummy}\n" " Set the logger verbosity level\n" @@ -193,7 +259,7 @@ bool parse_options(int argc, char **argv, {"dry-run", no_argument, NULL, OPT_DRY_RUN}, {"include-tests", required_argument, NULL, OPT_INCLUDE}, {"exclude-tests", required_argument, NULL, OPT_EXCLUDE}, - {"abort-on-monitored-error", no_argument, NULL, OPT_ABORT_ON_ERROR}, + {"abort-on-monitored-error", optional_argument, NULL, OPT_ABORT_ON_ERROR}, {"sync", no_argument, NULL, OPT_SYNC}, {"log-level", required_argument, NULL, OPT_LOG_LEVEL}, {"test-list", required_argument, NULL, OPT_TEST_LIST}, @@ -231,7 +297,8 @@ bool parse_options(int argc, char **argv, goto error; break; case OPT_ABORT_ON_ERROR: - settings->abort_on_error = true; + if (!parse_abort_conditions(settings, optarg)) + goto error; break; case OPT_SYNC: settings->sync = true; @@ -444,7 +511,7 @@ bool serialize_settings(struct settings *settings) return false; } - SERIALIZE_LINE(f, settings, abort_on_error, "%d"); + SERIALIZE_LINE(f, settings, abort_mask, "%d"); if (settings->test_list) SERIALIZE_LINE(f, settings, test_list, "%s"); if (settings->name) @@ -501,7 +568,7 @@ bool read_settings(struct settings *settings, int dirfd) while (fscanf(f, "%ms : %ms", &name, &val) == 2) { int numval = atoi(val); - PARSE_LINE(settings, name, val, abort_on_error, numval); + PARSE_LINE(settings, name, val, abort_mask, numval); PARSE_LINE(settings, name, val, test_list, val ? strdup(val) : NULL); PARSE_LINE(settings, name, val, name, val ? strdup(val) : NULL); PARSE_LINE(settings, name, val, dry_run, numval); |