diff options
Diffstat (limited to 'runner')
-rw-r--r-- | runner/job_list.c | 38 | ||||
-rw-r--r-- | runner/job_list.h | 1 | ||||
-rw-r--r-- | runner/meson.build | 16 | ||||
-rw-r--r-- | runner/resultgen.c | 21 | ||||
-rw-r--r-- | runner/runner.c | 5 | ||||
-rw-r--r-- | runner/runner_tests.c | 628 | ||||
-rw-r--r-- | runner/settings.c | 147 | ||||
-rw-r--r-- | runner/settings.h | 5 | ||||
-rw-r--r-- | runner/testdata/meson.build | 5 | ||||
-rw-r--r-- | runner/testdata/test-blacklist.txt | 2 | ||||
-rw-r--r-- | runner/testdata/test-blacklist2.txt | 2 |
11 files changed, 536 insertions, 334 deletions
diff --git a/runner/job_list.c b/runner/job_list.c index 941e2ee0..5283fd72 100644 --- a/runner/job_list.c +++ b/runner/job_list.c @@ -17,10 +17,8 @@ static bool matches_any(const char *str, struct regex_list *list) size_t i; for (i = 0; i < list->size; i++) { - if (regexec(list->regexes[i], str, - (size_t)0, NULL, 0) == 0) { + if (g_regex_match(list->regexes[i], str, 0, NULL)) return true; - } } return false; @@ -113,11 +111,17 @@ static void add_subtests(struct job_list *job_list, struct settings *settings, fprintf(stderr, "popen error when executing %s: %s\n", binary, strerror(errno)); } else if (WIFEXITED(s)) { if (WEXITSTATUS(s) == IGT_EXIT_INVALID) { + char piglitname[256]; + + generate_piglit_name(binary, NULL, + piglitname, sizeof(piglitname)); /* No subtests on this one */ - if (exclude && exclude->size && matches_any(binary, exclude)) { + if (exclude && exclude->size && + matches_any(piglitname, exclude)) { return; } - if (!include || !include->size || matches_any(binary, include)) { + if (!include || !include->size || + matches_any(piglitname, include)) { add_job_list_entry(job_list, strdup(binary), NULL, 0); return; } @@ -293,6 +297,30 @@ static bool job_list_from_test_list(struct job_list *job_list, return any; } +void list_all_tests(struct job_list *lst) +{ + char piglit_name[256]; + + for (size_t test_idx = 0; test_idx < lst->size; ++test_idx) { + struct job_list_entry *current_entry = lst->entries + test_idx; + char *binary = current_entry->binary; + + if (current_entry->subtest_count == 0) { + generate_piglit_name(binary, NULL, + piglit_name, sizeof(piglit_name)); + printf("%s\n", piglit_name); + continue; + } + for (size_t subtest_idx = 0; + subtest_idx < current_entry->subtest_count; + ++subtest_idx) { + generate_piglit_name(binary, current_entry->subtests[subtest_idx], + piglit_name, sizeof(piglit_name)); + printf("%s\n", piglit_name); + } + } +} + static char *lowercase(const char *str) { char *ret = malloc(strlen(str) + 1); diff --git a/runner/job_list.h b/runner/job_list.h index f8bbbddc..39c9b863 100644 --- a/runner/job_list.h +++ b/runner/job_list.h @@ -36,5 +36,6 @@ bool create_job_list(struct job_list *job_list, struct settings *settings); bool serialize_job_list(struct job_list *job_list, struct settings *settings); bool read_job_list(struct job_list *job_list, int dirfd); +void list_all_tests(struct job_list *lst); #endif diff --git a/runner/meson.build b/runner/meson.build index de6e6f1c..4eff193a 100644 --- a/runner/meson.build +++ b/runner/meson.build @@ -1,4 +1,4 @@ -jsonc = dependency('json-c', required: _runner_required) +build_runner = get_option('build_runner') runnerlib_sources = [ 'settings.c', 'job_list.c', @@ -12,12 +12,18 @@ results_sources = [ 'results.c' ] runner_test_sources = [ 'runner_tests.c' ] runner_json_test_sources = [ 'runner_json_tests.c' ] -if _build_runner and jsonc.found() +jsonc = dependency('json-c', required: build_runner) + +if not build_tests and jsonc.found() + error('Building test runner requires building tests') +endif + +if jsonc.found() subdir('testdata') runnerlib = static_library('igt_runner', runnerlib_sources, include_directories : inc, - dependencies : jsonc) + dependencies : [jsonc, glib]) runner = executable('igt_runner', runner_sources, link_with : runnerlib, @@ -54,7 +60,7 @@ if _build_runner and jsonc.found() dependencies : [igt_deps, jsonc]) test('runner_json', runner_json_test) - build_info += 'Build test runner: Yes' + build_info += 'Build test runner: true' else - build_info += 'Build test runner: No' + build_info += 'Build test runner: false' endif diff --git a/runner/resultgen.c b/runner/resultgen.c index d9702a19..7b4cd519 100644 --- a/runner/resultgen.c +++ b/runner/resultgen.c @@ -499,14 +499,17 @@ static const char igt_dmesg_whitelist[] = static const char igt_piglit_style_dmesg_blacklist[] = "(\\[drm:|drm_|intel_|i915_)"; -static bool init_regex_whitelist(struct settings* settings, regex_t* re) +static bool init_regex_whitelist(struct settings* settings, GRegex **re) { + GError *err = NULL; const char *regex = settings->piglit_style_dmesg ? igt_piglit_style_dmesg_blacklist : igt_dmesg_whitelist; - if (regcomp(re, regex, REG_EXTENDED | REG_NOSUB) != 0) { + *re = g_regex_new(regex, G_REGEX_OPTIMIZE, 0, &err); + if (err) { fprintf(stderr, "Cannot compile dmesg regexp\n"); + g_error_free(err); return false; } @@ -630,7 +633,7 @@ static bool fill_from_dmesg(int fd, char piglit_name[256]; ssize_t read; size_t i; - regex_t re; + GRegex *re; if (!f) { return false; @@ -671,12 +674,12 @@ static bool fill_from_dmesg(int fd, if (settings->piglit_style_dmesg) { if ((flags & 0x07) <= settings->dmesg_warn_level && continuation != 'c' && - regexec(&re, message, (size_t)0, NULL, 0) != REG_NOMATCH) { + g_regex_match(re, message, 0, NULL)) { append_line(&warnings, &warningslen, formatted); } } else { if ((flags & 0x07) <= settings->dmesg_warn_level && continuation != 'c' && - regexec(&re, message, (size_t)0, NULL, 0) == REG_NOMATCH) { + !g_regex_match(re, message, 0, NULL)) { append_line(&warnings, &warningslen, formatted); } } @@ -715,7 +718,7 @@ static bool fill_from_dmesg(int fd, free(dmesg); free(warnings); - regfree(&re); + g_regex_unref(re); fclose(f); return true; } @@ -739,6 +742,7 @@ static const char *result_from_exitcode(int exitcode) static void add_subtest(struct subtests *subtests, char *subtest) { size_t len = strlen(subtest); + size_t i; if (len == 0) return; @@ -746,6 +750,11 @@ static void add_subtest(struct subtests *subtests, char *subtest) if (subtest[len - 1] == '\n') subtest[len - 1] = '\0'; + /* Don't add if we already have this subtest */ + for (i = 0; i < subtests->size; i++) + if (!strcmp(subtest, subtests->names[i])) + return; + subtests->size++; subtests->names = realloc(subtests->names, sizeof(*subtests->names) * subtests->size); subtests->names[subtests->size - 1] = subtest; diff --git a/runner/runner.c b/runner/runner.c index e1a6ccba..4855ad64 100644 --- a/runner/runner.c +++ b/runner/runner.c @@ -24,6 +24,11 @@ int main(int argc, char **argv) return 1; } + if (settings.list_all) { + list_all_tests(&job_list); + return 0; + } + if (!initialize_execute_state(&state, &settings, &job_list)) { return 1; } diff --git a/runner/runner_tests.c b/runner/runner_tests.c index ade78b18..39d4a078 100644 --- a/runner/runner_tests.c +++ b/runner/runner_tests.c @@ -10,7 +10,15 @@ #include "job_list.h" #include "executor.h" -static char testdatadir[] = TESTDATA_DIRECTORY; +/* + * NOTE: this test is using a lot of variables that are changed in igt_fixture, + * igt_subtest_group and igt_subtests blocks but defined outside of them. + * + * Such variables have to be either non-local or volatile, otherwise their + * contents is undefined due to longjmps the framework performs. + */ + +static const char testdatadir[] = TESTDATA_DIRECTORY; static void igt_assert_eqstr(const char *one, const char *two) { @@ -65,10 +73,10 @@ static void job_list_filter_test(const char *name, const char *filterarg1, const size_t expected_normal, size_t expected_multiple) { int multiple; - struct settings settings; + struct settings *settings = malloc(sizeof(*settings)); igt_fixture - init_settings(&settings); + init_settings(settings); for (multiple = 0; multiple < 2; multiple++) { igt_subtest_f("job-list-filters-%s-%s", name, multiple ? "multiple" : "normal") { @@ -84,9 +92,9 @@ static void job_list_filter_test(const char *name, const char *filterarg1, const size_t size; init_job_list(&list); - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - success = create_job_list(&list, &settings); + success = create_job_list(&list, settings); size = list.size; if (success) @@ -99,8 +107,10 @@ static void job_list_filter_test(const char *name, const char *filterarg1, const } } - igt_fixture - free_settings(&settings); + igt_fixture { + free_settings(settings); + free(settings); + } } static void clear_directory_fd(int dirfd) @@ -196,10 +206,29 @@ static void assert_execution_results_exist(int dirfd) igt_main { - struct settings settings; + struct settings *settings = malloc(sizeof(*settings)); - igt_fixture - init_settings(&settings); + igt_fixture { + int i; + + /* + * Let's close all the non-standard fds ahead of executing + * anything, so we can test for descriptor leakage caused by + * any of the igt_runner code-paths exercised here. + * + * See file-descriptor-leakage subtest at the end. + * + * Some libraries (looking at you, GnuTLS) may leave fds opened + * after the implicitly called library constructor. We don't + * have full control over them as they may be dependencies of + * our dependencies and may get pulled in if the user's and + * distribution's compile/configure/USE are just right. + */ + for (i = 3; i < 400; i++) + close(i); + + init_settings(settings); + } igt_subtest("default-settings") { const char *argv[] = { "runner", @@ -207,26 +236,26 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - - igt_assert_eq(settings.abort_mask, 0); - igt_assert(!settings.test_list); - igt_assert_eqstr(settings.name, "path-to-results"); - igt_assert(!settings.dry_run); - igt_assert_eq(settings.include_regexes.size, 0); - igt_assert_eq(settings.exclude_regexes.size, 0); - igt_assert(!settings.sync); - igt_assert_eq(settings.log_level, LOG_LEVEL_NORMAL); - igt_assert(!settings.overwrite); - igt_assert(!settings.multiple_mode); - igt_assert_eq(settings.inactivity_timeout, 0); - igt_assert_eq(settings.overall_timeout, 0); - igt_assert(!settings.use_watchdog); - igt_assert(strstr(settings.test_root, "test-root-dir") != NULL); - igt_assert(strstr(settings.results_path, "path-to-results") != NULL); - - igt_assert(!settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 4); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + + igt_assert_eq(settings->abort_mask, 0); + igt_assert(!settings->test_list); + igt_assert_eqstr(settings->name, "path-to-results"); + igt_assert(!settings->dry_run); + igt_assert_eq(settings->include_regexes.size, 0); + igt_assert_eq(settings->exclude_regexes.size, 0); + igt_assert(!settings->sync); + igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL); + igt_assert(!settings->overwrite); + igt_assert(!settings->multiple_mode); + igt_assert_eq(settings->inactivity_timeout, 0); + igt_assert_eq(settings->overall_timeout, 0); + igt_assert(!settings->use_watchdog); + igt_assert(strstr(settings->test_root, "test-root-dir") != NULL); + igt_assert(strstr(settings->results_path, "path-to-results") != NULL); + + igt_assert(!settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 4); } igt_subtest_group { @@ -262,10 +291,10 @@ igt_main } igt_subtest_group { + const char tmptestlist[] = "tmp.testlist"; char dirname[] = "tmpdirXXXXXX"; - char tmptestlist[] = "tmp.testlist"; char pathtotestlist[64]; - char *path; + volatile char *path; igt_fixture { int dirfd, fd; @@ -290,19 +319,19 @@ igt_main dirname, }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); path = realpath(testdatadir, NULL); igt_assert(path != NULL); - igt_assert_eqstr(settings.test_root, path); - free(path); + igt_assert_eqstr(settings->test_root, (char*)path); + free((void*)path); path = realpath(dirname, NULL); igt_assert(path != NULL); - igt_assert_eqstr(settings.results_path, path); - free(path); + igt_assert_eqstr(settings->results_path, (char*)path); + free((void*)path); path = realpath(pathtotestlist, NULL); igt_assert(path != NULL); - igt_assert_eqstr(settings.test_list, path); + igt_assert_eqstr(settings->test_list, (char*)path); } igt_fixture { @@ -313,7 +342,7 @@ igt_main close(dirfd); rmdir(dirname); - free(path); + free((void*)path); } } @@ -324,24 +353,24 @@ igt_main }; setenv("IGT_TEST_ROOT", testdatadir, 1); - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - - igt_assert_eq(settings.abort_mask, 0); - igt_assert(!settings.test_list); - igt_assert_eqstr(settings.name, "path-to-results"); - igt_assert(!settings.dry_run); - igt_assert_eq(settings.include_regexes.size, 0); - igt_assert_eq(settings.exclude_regexes.size, 0); - igt_assert(!settings.sync); - igt_assert_eq(settings.log_level, LOG_LEVEL_NORMAL); - igt_assert(!settings.overwrite); - igt_assert(!settings.multiple_mode); - igt_assert_eq(settings.inactivity_timeout, 0); - igt_assert_eq(settings.overall_timeout, 0); - igt_assert(!settings.use_watchdog); - igt_assert(strstr(settings.test_root, testdatadir) != NULL); - igt_assert(strstr(settings.results_path, "path-to-results") != NULL); - igt_assert(!settings.piglit_style_dmesg); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + + igt_assert_eq(settings->abort_mask, 0); + igt_assert(!settings->test_list); + igt_assert_eqstr(settings->name, "path-to-results"); + igt_assert(!settings->dry_run); + igt_assert_eq(settings->include_regexes.size, 0); + igt_assert_eq(settings->exclude_regexes.size, 0); + igt_assert(!settings->sync); + igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL); + igt_assert(!settings->overwrite); + igt_assert(!settings->multiple_mode); + igt_assert_eq(settings->inactivity_timeout, 0); + igt_assert_eq(settings->overall_timeout, 0); + igt_assert(!settings->use_watchdog); + igt_assert(strstr(settings->test_root, testdatadir) != NULL); + igt_assert(strstr(settings->results_path, "path-to-results") != NULL); + igt_assert(!settings->piglit_style_dmesg); } igt_fixture { @@ -349,6 +378,7 @@ igt_main } igt_subtest("parse-all-settings") { + char blacklist_name[PATH_MAX], blacklist2_name[PATH_MAX]; const char *argv[] = { "runner", "-n", "foo", "--abort-on-monitored-error=taint,lockdep", @@ -359,6 +389,8 @@ igt_main "-t", "pattern2", "-x", "xpattern1", "-x", "xpattern2", + "-b", blacklist_name, + "--blacklist", blacklist2_name, "-s", "-l", "verbose", "--overwrite", @@ -372,30 +404,43 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - - igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP); - igt_assert(strstr(settings.test_list, "path-to-test-list") != NULL); - igt_assert_eqstr(settings.name, "foo"); - igt_assert(settings.dry_run); - igt_assert_eq(settings.include_regexes.size, 2); - igt_assert_eqstr(settings.include_regexes.regex_strings[0], "pattern1"); - igt_assert_eqstr(settings.include_regexes.regex_strings[1], "pattern2"); - igt_assert_eq(settings.exclude_regexes.size, 2); - igt_assert_eqstr(settings.exclude_regexes.regex_strings[0], "xpattern1"); - igt_assert_eqstr(settings.exclude_regexes.regex_strings[1], "xpattern2"); - igt_assert(settings.sync); - igt_assert_eq(settings.log_level, LOG_LEVEL_VERBOSE); - igt_assert(settings.overwrite); - igt_assert(settings.multiple_mode); - igt_assert_eq(settings.inactivity_timeout, 27); - igt_assert_eq(settings.overall_timeout, 360); - igt_assert(settings.use_watchdog); - igt_assert(strstr(settings.test_root, "test-root-dir") != NULL); - igt_assert(strstr(settings.results_path, "path-to-results") != NULL); - - igt_assert(settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 3); + sprintf(blacklist_name, "%s/test-blacklist.txt", testdatadir); + sprintf(blacklist2_name, "%s/test-blacklist2.txt", testdatadir); + + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + + igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP); + igt_assert(strstr(settings->test_list, "path-to-test-list") != NULL); + igt_assert_eqstr(settings->name, "foo"); + igt_assert(settings->dry_run); + igt_assert_eq(settings->include_regexes.size, 2); + igt_assert_eqstr(settings->include_regexes.regex_strings[0], "pattern1"); + igt_assert_eqstr(settings->include_regexes.regex_strings[1], "pattern2"); + igt_assert_eq(settings->exclude_regexes.size, 4); + igt_assert_eqstr(settings->exclude_regexes.regex_strings[0], "xpattern1"); + igt_assert_eqstr(settings->exclude_regexes.regex_strings[1], "xpattern2"); + igt_assert_eqstr(settings->exclude_regexes.regex_strings[2], "xpattern3"); /* From blacklist */ + igt_assert_eqstr(settings->exclude_regexes.regex_strings[3], "xpattern4"); /* From blacklist2 */ + igt_assert(settings->sync); + igt_assert_eq(settings->log_level, LOG_LEVEL_VERBOSE); + igt_assert(settings->overwrite); + igt_assert(settings->multiple_mode); + igt_assert_eq(settings->inactivity_timeout, 27); + igt_assert_eq(settings->overall_timeout, 360); + igt_assert(settings->use_watchdog); + igt_assert(strstr(settings->test_root, "test-root-dir") != NULL); + igt_assert(strstr(settings->results_path, "path-to-results") != NULL); + + igt_assert(settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 3); + } + igt_subtest("parse-list-all") { + const char *argv[] = { "runner", + "--list-all", + "test-root-dir"}; + + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->list_all, 1); } igt_subtest("dmesg-warn-level-inferred") { @@ -404,10 +449,10 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(!settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 4); + igt_assert(!settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 4); } igt_subtest("dmesg-warn-level-inferred-with-piglit-style") { @@ -417,10 +462,10 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 5); + igt_assert(settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 5); } igt_subtest("dmesg-warn-level-overridable-with-piglit-style") { @@ -431,10 +476,10 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 3); + igt_assert(settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 3); } igt_subtest("invalid-option") { @@ -444,14 +489,14 @@ igt_main "results-path", }; - igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); } igt_subtest("paths-missing") { const char *argv[] = { "runner", "-o", }; - igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); } igt_subtest("log-levels") { @@ -461,16 +506,16 @@ igt_main "results-path", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.log_level, LOG_LEVEL_NORMAL); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL); argv[2] = "quiet"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.log_level, LOG_LEVEL_QUIET); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->log_level, LOG_LEVEL_QUIET); argv[2] = "verbose"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.log_level, LOG_LEVEL_VERBOSE); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->log_level, LOG_LEVEL_VERBOSE); } igt_subtest("abort-conditions") { @@ -480,35 +525,35 @@ igt_main "results-path", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_TAINT); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_TAINT); argv[1] = "--abort-on-monitored-error=lockdep"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_LOCKDEP); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_LOCKDEP); argv[1] = "--abort-on-monitored-error=taint"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_TAINT); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_TAINT); argv[1] = "--abort-on-monitored-error=lockdep,taint"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP); argv[1] = "--abort-on-monitored-error=taint,lockdep"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP); argv[1] = "--abort-on-monitored-error=all"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, ABORT_ALL); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, ABORT_ALL); argv[1] = "--abort-on-monitored-error="; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert_eq(settings.abort_mask, 0); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert_eq(settings->abort_mask, 0); argv[1] = "--abort-on-monitored-error=doesnotexist"; - igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); } @@ -520,29 +565,29 @@ igt_main "results-path", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert_eqstr(settings.name, "foo"); - igt_assert(settings.dry_run); - igt_assert(!settings.test_list); - igt_assert(!settings.sync); + igt_assert_eqstr(settings->name, "foo"); + igt_assert(settings->dry_run); + igt_assert(!settings->test_list); + igt_assert(!settings->sync); argv[1] = "--test-list"; argv[3] = "--sync"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert_eqstr(settings.name, "results-path"); - igt_assert(!settings.dry_run); - igt_assert(strstr(settings.test_list, "foo") != NULL); - igt_assert(settings.sync); + igt_assert_eqstr(settings->name, "results-path"); + igt_assert(!settings->dry_run); + igt_assert(strstr(settings->test_list, "foo") != NULL); + igt_assert(settings->sync); } igt_subtest_group { char filename[] = "tmplistXXXXXX"; - int fd = -1; igt_fixture { + int fd; igt_require((fd = mkstemp(filename)) >= 0); close(fd); } @@ -554,9 +599,9 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(validate_settings(&settings)); + igt_assert(validate_settings(settings)); } igt_fixture { @@ -573,18 +618,18 @@ igt_main }; igt_assert_lt(open(nosuchfile, O_RDONLY), 0); - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(!validate_settings(&settings)); + igt_assert(!validate_settings(settings)); } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; + struct job_list *list = malloc(sizeof(*list)); igt_fixture { igt_require(mkdtemp(dirname) != NULL); - init_job_list(&list); + init_job_list(list); } igt_subtest("job-list-no-test-list-txt") { @@ -593,14 +638,15 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(!create_job_list(&list, &settings)); + igt_assert(!create_job_list(list, settings)); } igt_fixture { rmdir(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } @@ -614,17 +660,18 @@ igt_main igt_subtest_group { char filename[] = "tmplistXXXXXX"; - char testlisttext[] = "igt@successtest@first-subtest\n" + const char testlisttext[] = "igt@successtest@first-subtest\n" "igt@successtest@second-subtest\n" "igt@nosubtests\n"; - int fd = -1, multiple; - struct job_list list; + int multiple; + struct job_list *list = malloc(sizeof(*list)); igt_fixture { + int fd; igt_require((fd = mkstemp(filename)) >= 0); igt_require(write(fd, testlisttext, strlen(testlisttext)) == strlen(testlisttext)); close(fd); - init_job_list(&list); + init_job_list(list); } for (multiple = 0; multiple < 2; multiple++) { @@ -636,21 +683,21 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); - igt_assert_eq(list.size, multiple ? 2 : 3); + igt_assert_eq(list->size, multiple ? 2 : 3); - igt_assert_eqstr(list.entries[0].binary, "successtest"); - if (!multiple) igt_assert_eqstr(list.entries[1].binary, "successtest"); - igt_assert_eqstr(list.entries[multiple ? 1 : 2].binary, "nosubtests"); + igt_assert_eqstr(list->entries[0].binary, "successtest"); + if (!multiple) igt_assert_eqstr(list->entries[1].binary, "successtest"); + igt_assert_eqstr(list->entries[multiple ? 1 : 2].binary, "nosubtests"); - igt_assert_eq(list.entries[0].subtest_count, multiple ? 2 : 1); - igt_assert_eq(list.entries[1].subtest_count, multiple ? 0 : 1); - if (!multiple) igt_assert_eq(list.entries[2].subtest_count, 0); + igt_assert_eq(list->entries[0].subtest_count, multiple ? 2 : 1); + igt_assert_eq(list->entries[1].subtest_count, multiple ? 0 : 1); + if (!multiple) igt_assert_eq(list->entries[2].subtest_count, 0); - igt_assert_eqstr(list.entries[0].subtests[0], "first-subtest"); - igt_assert_eqstr(list.entries[multiple ? 0 : 1].subtests[multiple ? 1 : 0], "second-subtest"); + igt_assert_eqstr(list->entries[0].subtests[0], "first-subtest"); + igt_assert_eqstr(list->entries[multiple ? 0 : 1].subtests[multiple ? 1 : 0], "second-subtest"); } igt_subtest_f("job-list-testlist-filtered-%s", multiple ? "multiple" : "normal") { @@ -663,32 +710,33 @@ igt_main "path-to-results", }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); - igt_assert_eq(list.size, 1); - igt_assert_eqstr(list.entries[0].binary, "successtest"); + igt_assert_eq(list->size, 1); + igt_assert_eqstr(list->entries[0].binary, "successtest"); - igt_assert_eq(list.entries[0].subtest_count, 1); - igt_assert_eqstr(list.entries[0].subtests[0], "second-subtest"); + igt_assert_eq(list->entries[0].subtest_count, 1); + igt_assert_eqstr(list->entries[0].subtests[0], "second-subtest"); } } igt_fixture { unlink(filename); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - int dirfd = -1, fd = -1; - struct settings cmp_settings; + volatile int dirfd = -1, fd = -1; + struct settings *cmp_settings = malloc(sizeof(*cmp_settings)); igt_fixture { igt_require(mkdtemp(dirname) != NULL); rmdir(dirname); - init_settings(&cmp_settings); + init_settings(cmp_settings); } igt_subtest("settings-serialize") { @@ -714,9 +762,9 @@ igt_main dirname, }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); - igt_assert(serialize_settings(&settings)); + igt_assert(serialize_settings(settings)); dirfd = open(dirname, O_DIRECTORY, O_RDONLY); igt_assert_f(dirfd >= 0, "Serialization did not create the results directory\n"); @@ -725,27 +773,31 @@ igt_main "Opening %s/metadata.txt failed\n", dirname); close(fd); - igt_assert_f(read_settings_from_dir(&cmp_settings, dirfd), "Reading settings failed\n"); - assert_settings_equal(&settings, &cmp_settings); + igt_assert_f(read_settings_from_dir(cmp_settings, dirfd), "Reading settings failed\n"); + assert_settings_equal(settings, cmp_settings); } igt_fixture { close(fd); close(dirfd); clear_directory(dirname); - free_settings(&cmp_settings); + free_settings(cmp_settings); + free(cmp_settings); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - int dirfd = -1, fd = -1; - struct job_list list, cmp_list; + volatile int dirfd = -1, fd = -1; + struct job_list *list, *cmp_list; int multiple; + list = malloc(sizeof(*list)); + cmp_list = malloc(sizeof(*cmp_list)); + igt_fixture { - init_job_list(&list); - init_job_list(&cmp_list); + init_job_list(list); + init_job_list(cmp_list); igt_require(mkdtemp(dirname) != NULL); rmdir(dirname); } @@ -759,11 +811,11 @@ igt_main dirname, }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); - igt_assert(serialize_settings(&settings)); - igt_assert(serialize_job_list(&list, &settings)); + igt_assert(serialize_settings(settings)); + igt_assert(serialize_job_list(list, settings)); dirfd = open(dirname, O_DIRECTORY, O_RDONLY); igt_assert_f(dirfd >= 0, "Serialization did not create the results directory\n"); @@ -773,27 +825,32 @@ igt_main close(fd); fd = -1; - igt_assert_f(read_job_list(&cmp_list, dirfd), "Reading job list failed\n"); - assert_job_list_equal(&list, &cmp_list); + igt_assert_f(read_job_list(cmp_list, dirfd), "Reading job list failed\n"); + assert_job_list_equal(list, cmp_list); } igt_fixture { close(fd); close(dirfd); clear_directory(dirname); - free_job_list(&cmp_list); - free_job_list(&list); + free_job_list(cmp_list); + free_job_list(list); } } + + igt_fixture { + free(cmp_list); + free(list); + } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; igt_fixture { - init_job_list(&list); + init_job_list(list); igt_require(mkdtemp(dirname) != NULL); rmdir(dirname); } @@ -806,19 +863,19 @@ igt_main dirname, }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); - igt_assert(initialize_execute_state(&state, &settings, &list)); + igt_assert(initialize_execute_state(&state, settings, list)); igt_assert_eq(state.next, 0); igt_assert(state.dry); - igt_assert_eq(list.size, 5); + igt_assert_eq(list->size, 5); igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0, "Dry run initialization didn't create the results directory.\n"); /* Execute from just initialize_execute_state should fail */ - igt_assert(execute(&state, &settings, &list)); + igt_assert(execute(&state, settings, list)); igt_assert_f(openat(dirfd, "0", O_DIRECTORY | O_RDONLY) < 0, "Dry run executed when it should not have.\n"); igt_assert_f((fd = openat(dirfd, "metadata.txt", O_RDONLY)) >= 0, @@ -830,16 +887,16 @@ igt_main igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) < 0, "Dry run initialization created uname.txt.\n"); - igt_assert(initialize_execute_state_from_resume(dirfd, &state, &settings, &list)); + igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list)); igt_assert_eq(state.next, 0); igt_assert(!state.dry); - igt_assert_eq(list.size, 5); + igt_assert_eq(list->size, 5); /* initialize_execute_state_from_resume() closes the dirfd */ igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0, "Dry run resume somehow deleted the results directory.\n"); /* Execute from resume should work */ - igt_assert(execute(&state, &settings, &list)); + igt_assert(execute(&state, settings, list)); igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) >= 0, "Dry run resume didn't create uname.txt.\n"); close(fd); @@ -854,17 +911,18 @@ igt_main close(dirfd); close(subdirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; - int dirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, fd = -1; igt_fixture { - init_job_list(&list); + init_job_list(list); igt_require(mkdtemp(dirname) != NULL); rmdir(dirname); } @@ -876,13 +934,13 @@ igt_main dirname, }; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); - igt_assert(initialize_execute_state(&state, &settings, &list)); + igt_assert(initialize_execute_state(&state, settings, list)); igt_assert_eq(state.next, 0); - igt_assert_eq(list.size, 5); + igt_assert_eq(list->size, 5); igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0, "Execute state initialization didn't create the results directory.\n"); igt_assert_f((fd = openat(dirfd, "metadata.txt", O_RDONLY)) >= 0, @@ -901,17 +959,18 @@ igt_main close(fd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; igt_fixture { - init_job_list(&list); + init_job_list(list); igt_require(mkdtemp(dirname) != NULL); } @@ -923,16 +982,16 @@ igt_main testdatadir, dirname, }; - char journaltext[] = "first-subtest\n"; - char excludestring[] = "!first-subtest"; + const char journaltext[] = "first-subtest\n"; + const char excludestring[] = "!first-subtest"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); - igt_assert(list.size == 1); - igt_assert(list.entries[0].subtest_count == 0); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); + igt_assert(list->size == 1); + igt_assert(list->entries[0].subtest_count == 0); - igt_assert(serialize_settings(&settings)); - igt_assert(serialize_job_list(&list, &settings)); + igt_assert(serialize_settings(settings)); + igt_assert(serialize_job_list(list, settings)); igt_assert((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0); igt_assert(mkdirat(dirfd, "0", 0770) == 0); @@ -940,15 +999,15 @@ igt_main igt_assert((fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660)) >= 0); igt_assert(write(fd, journaltext, strlen(journaltext)) == strlen(journaltext)); - free_job_list(&list); - free_settings(&settings); - igt_assert(initialize_execute_state_from_resume(dirfd, &state, &settings, &list)); + free_job_list(list); + free_settings(settings); + igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list)); igt_assert_eq(state.next, 0); - igt_assert_eq(list.size, 1); - igt_assert_eq(list.entries[0].subtest_count, 2); - igt_assert_eqstr(list.entries[0].subtests[0], "*"); - igt_assert_eqstr(list.entries[0].subtests[1], excludestring); + igt_assert_eq(list->size, 1); + igt_assert_eq(list->entries[0].subtest_count, 2); + igt_assert_eqstr(list->entries[0].subtests[0], "*"); + igt_assert_eqstr(list->entries[0].subtests[1], excludestring); } igt_fixture { @@ -956,17 +1015,18 @@ igt_main close(subdirfd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; igt_fixture { - init_job_list(&list); + init_job_list(list); igt_require(mkdtemp(dirname) != NULL); } @@ -979,15 +1039,15 @@ igt_main testdatadir, dirname, }; - char journaltext[] = "first-subtest\nsecond-subtest\n"; + const char journaltext[] = "first-subtest\nsecond-subtest\n"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); - igt_assert(list.size == 1); - igt_assert(list.entries[0].subtest_count == 2); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); + igt_assert(list->size == 1); + igt_assert(list->entries[0].subtest_count == 2); - igt_assert(serialize_settings(&settings)); - igt_assert(serialize_job_list(&list, &settings)); + igt_assert(serialize_settings(settings)); + igt_assert(serialize_job_list(list, settings)); igt_assert((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0); igt_assert(mkdirat(dirfd, "0", 0770) == 0); @@ -995,14 +1055,14 @@ igt_main igt_assert((fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660)) >= 0); igt_assert(write(fd, journaltext, strlen(journaltext)) == strlen(journaltext)); - free_job_list(&list); - free_settings(&settings); - igt_assert(initialize_execute_state_from_resume(dirfd, &state, &settings, &list)); + free_job_list(list); + free_settings(settings); + igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list)); /* All subtests are in journal, the entry should be considered completed */ igt_assert_eq(state.next, 1); - igt_assert_eq(list.size, 1); - igt_assert_eq(list.entries[0].subtest_count, 4); + igt_assert_eq(list->size, 1); + igt_assert_eq(list->entries[0].subtest_count, 4); } igt_fixture { @@ -1010,17 +1070,18 @@ igt_main close(subdirfd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { char dirname[] = "tmpdirXXXXXX"; - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; igt_fixture { - init_job_list(&list); + init_job_list(list); igt_require(mkdtemp(dirname) != NULL); } @@ -1031,22 +1092,22 @@ igt_main testdatadir, dirname, }; - char journaltext[] = "first-subtest\nsecond-subtest\nexit:0\n"; + const char journaltext[] = "first-subtest\nsecond-subtest\nexit:0\n"; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); - igt_assert(list.size == 3); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); + igt_assert(list->size == 3); - if (!strcmp(list.entries[0].binary, "no-subtests")) { - struct job_list_entry tmp = list.entries[0]; - list.entries[0] = list.entries[1]; - list.entries[1] = tmp; + if (!strcmp(list->entries[0].binary, "no-subtests")) { + struct job_list_entry tmp = list->entries[0]; + list->entries[0] = list->entries[1]; + list->entries[1] = tmp; } - igt_assert(list.entries[0].subtest_count == 0); + igt_assert(list->entries[0].subtest_count == 0); - igt_assert(serialize_settings(&settings)); - igt_assert(serialize_job_list(&list, &settings)); + igt_assert(serialize_settings(settings)); + igt_assert(serialize_job_list(list, settings)); igt_assert_lte(0, dirfd = open(dirname, O_DIRECTORY | O_RDONLY)); igt_assert_eq(mkdirat(dirfd, "0", 0770), 0); @@ -1054,12 +1115,12 @@ igt_main igt_assert_lte(0, fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660)); igt_assert_eq(write(fd, journaltext, sizeof(journaltext)), sizeof(journaltext)); - free_job_list(&list); - free_settings(&settings); - igt_assert(initialize_execute_state_from_resume(dirfd, &state, &settings, &list)); + free_job_list(list); + free_settings(settings); + igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list)); igt_assert_eq(state.next, 1); - igt_assert_eq(list.size, 3); + igt_assert_eq(list->size, 3); } igt_fixture { @@ -1067,17 +1128,18 @@ igt_main close(subdirfd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); + free(list); } } igt_subtest_group { - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; int multiple; igt_fixture { - init_job_list(&list); + init_job_list(list); } for (multiple = 0; multiple < 2; multiple++) { @@ -1100,11 +1162,11 @@ igt_main size_t expected_tests = multiple ? 2 : 3; size_t i; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); - igt_assert(initialize_execute_state(&state, &settings, &list)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); + igt_assert(initialize_execute_state(&state, settings, list)); - igt_assert(execute(&state, &settings, &list)); + igt_assert(execute(&state, settings, list)); igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0, "Execute didn't create the results directory\n"); @@ -1132,9 +1194,12 @@ igt_main close(subdirfd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); } } + + igt_fixture + free(list); } igt_subtest_group { @@ -1143,10 +1208,10 @@ igt_main FILE *f = fmemopen(metadata, strlen(metadata), "r"); igt_assert(f); - igt_assert(read_settings_from_file(&settings, f)); + igt_assert(read_settings_from_file(settings, f)); - igt_assert(settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 5); + igt_assert(settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 5); fclose(f); } @@ -1156,10 +1221,10 @@ igt_main FILE *f = fmemopen(metadata, strlen(metadata), "r"); igt_assert(f); - igt_assert(read_settings_from_file(&settings, f)); + igt_assert(read_settings_from_file(settings, f)); - igt_assert(settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 3); + igt_assert(settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 3); fclose(f); } @@ -1169,10 +1234,10 @@ igt_main FILE *f = fmemopen(metadata, strlen(metadata), "r"); igt_assert(f); - igt_assert(read_settings_from_file(&settings, f)); + igt_assert(read_settings_from_file(settings, f)); - igt_assert(!settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 4); + igt_assert(!settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 4); fclose(f); } @@ -1182,22 +1247,22 @@ igt_main FILE *f = fmemopen(metadata, strlen(metadata), "r"); igt_assert(f); - igt_assert(read_settings_from_file(&settings, f)); + igt_assert(read_settings_from_file(settings, f)); - igt_assert(!settings.piglit_style_dmesg); - igt_assert_eq(settings.dmesg_warn_level, 3); + igt_assert(!settings->piglit_style_dmesg); + igt_assert_eq(settings->dmesg_warn_level, 3); fclose(f); } } igt_subtest_group { - struct job_list list; - int dirfd = -1, subdirfd = -1, fd = -1; + struct job_list *list = malloc(sizeof(*list)); + volatile int dirfd = -1, subdirfd = -1, fd = -1; int multiple; igt_fixture { - init_job_list(&list); + init_job_list(list); } for (multiple = 0; multiple < 2; multiple++) { @@ -1222,11 +1287,11 @@ igt_main "skip-one\nexit:77 ("; const char *expected_1 = "skip-two\nexit:77 ("; - igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings)); - igt_assert(create_job_list(&list, &settings)); - igt_assert(initialize_execute_state(&state, &settings, &list)); + igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings)); + igt_assert(create_job_list(list, settings)); + igt_assert(initialize_execute_state(&state, settings, list)); - igt_assert(execute(&state, &settings, &list)); + igt_assert(execute(&state, settings, list)); igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0, "Execute didn't create the results directory\n"); @@ -1266,9 +1331,12 @@ igt_main close(subdirfd); close(dirfd); clear_directory(dirname); - free_job_list(&list); + free_job_list(list); } } + + igt_fixture + free(list); } igt_subtest("file-descriptor-leakage") { @@ -1289,6 +1357,8 @@ igt_main } } - igt_fixture - free_settings(&settings); + igt_fixture { + free_settings(settings); + free(settings); + } } diff --git a/runner/settings.c b/runner/settings.c index 25bcf531..9920e1a6 100644 --- a/runner/settings.c +++ b/runner/settings.c @@ -1,5 +1,6 @@ #include "settings.h" +#include <ctype.h> #include <errno.h> #include <fcntl.h> #include <getopt.h> @@ -30,6 +31,8 @@ enum { OPT_MULTIPLE = 'm', OPT_TIMEOUT = 'c', OPT_WATCHDOG = 'g', + OPT_BLACKLIST = 'b', + OPT_LIST_ALL = 'L', }; static struct { @@ -117,7 +120,8 @@ static bool parse_abort_conditions(struct settings *settings, const char *optarg } static const char *usage_str = - "usage: runner [options] [test_root] results-path\n\n" + "usage: runner [options] [test_root] results-path\n" + " or: runner --list-all [options] [test_root]\n\n" "Options:\n" " Piglit compatible:\n" " -h, --help Show this help message and exit\n" @@ -172,6 +176,10 @@ static const char *usage_str = " (longer) filter list means the test result should\n" " change. KERN_NOTICE dmesg level is treated as warn,\n" " unless overridden with --dmesg-warn-level.\n" + " -b, --blacklist FILENAME\n" + " Exclude all test matching to regexes from FILENAME\n" + " (can be used more than once)\n" + " -L, --list-all List all matching subtests instead of running\n" " [test_root] Directory that contains the IGT tests. The environment\n" " variable IGT_TEST_ROOT will be used if set, overriding\n" " this option if given.\n" @@ -187,23 +195,18 @@ static void usage(const char *extra_message, FILE *f) static bool add_regex(struct regex_list *list, char *new) { - regex_t *regex; - size_t buflen; - char *buf; - int s; - - regex = malloc(sizeof(*regex)); - - if ((s = regcomp(regex, new, - REG_EXTENDED | REG_NOSUB)) != 0) { - buflen = regerror(s, regex, NULL, 0); - buf = malloc(buflen); - regerror(s, regex, buf, buflen); + GRegex *regex; + GError *error = NULL; + + regex = g_regex_new(new, G_REGEX_OPTIMIZE, 0, &error); + if (error) { + char *buf = malloc(snprintf(NULL, 0, "Invalid regex '%s': %s", new, error->message) + 1); + + sprintf(buf, "Invalid regex '%s': %s", new, error->message); usage(buf, stderr); free(buf); - regfree(regex); - free(regex); + g_error_free(error); return false; } @@ -218,14 +221,58 @@ static bool add_regex(struct regex_list *list, char *new) return true; } +static bool parse_blacklist(struct regex_list *exclude_regexes, + char *blacklist_filename) +{ + FILE *f; + char *line = NULL; + size_t line_len = 0; + bool status; + + if ((f = fopen(blacklist_filename, "r")) == NULL) { + fprintf(stderr, "Cannot open blacklist file %s\n", blacklist_filename); + return false; + } + while (1) { + size_t str_size = 0, idx = 0; + + if (getline(&line, &line_len, f) == -1) { + if (errno == EINTR) + continue; + else + break; + } + + while (true) { + if (line[idx] == '\n' || + line[idx] == '\0' || + line[idx] == '#') /* # starts a comment */ + break; + if (!isspace(line[idx])) + str_size = idx + 1; + idx++; + } + if (str_size > 0) { + char *test_regex = strndup(line, str_size); + + status = add_regex(exclude_regexes, test_regex); + if (!status) + break; + } + } + + free(line); + fclose(f); + return status; +} + static void free_regexes(struct regex_list *regexes) { size_t i; for (i = 0; i < regexes->size; i++) { free(regexes->regex_strings[i]); - regfree(regexes->regexes[i]); - free(regexes->regexes[i]); + g_regex_unref(regexes->regexes[i]); } free(regexes->regex_strings); free(regexes->regexes); @@ -278,6 +325,8 @@ bool parse_options(int argc, char **argv, {"use-watchdog", no_argument, NULL, OPT_WATCHDOG}, {"piglit-style-dmesg", no_argument, NULL, OPT_PIGLIT_DMESG}, {"dmesg-warn-level", required_argument, NULL, OPT_DMESG_WARN_LEVEL}, + {"blacklist", required_argument, NULL, OPT_BLACKLIST}, + {"list-all", no_argument, NULL, OPT_LIST_ALL}, { 0, 0, 0, 0}, }; @@ -287,7 +336,8 @@ bool parse_options(int argc, char **argv, settings->dmesg_warn_level = -1; - while ((c = getopt_long(argc, argv, "hn:dt:x:sl:om", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hn:dt:x:sl:omb:L", + long_options, NULL)) != -1) { switch (c) { case OPT_HELP: usage(NULL, stdout); @@ -348,6 +398,14 @@ bool parse_options(int argc, char **argv, case OPT_DMESG_WARN_LEVEL: settings->dmesg_warn_level = atoi(optarg); break; + case OPT_BLACKLIST: + if (!parse_blacklist(&settings->exclude_regexes, + absolute_path(optarg))) + goto error; + break; + case OPT_LIST_ALL: + settings->list_all = true; + break; case '?': usage(NULL, stderr); goto error; @@ -360,20 +418,40 @@ bool parse_options(int argc, char **argv, if (settings->dmesg_warn_level < 0) settings->dmesg_warn_level = 4; /* KERN_WARN */ - switch (argc - optind) { - case 2: - settings->test_root = absolute_path(argv[optind]); - ++optind; - /* fallthrough */ - case 1: - settings->results_path = absolute_path(argv[optind]); - break; - case 0: - usage("Results-path missing", stderr); - goto error; - default: - usage("Extra arguments after results-path", stderr); - goto error; + if (settings->list_all) { /* --list-all doesn't require results path */ + switch (argc - optind) { + case 1: + settings->test_root = absolute_path(argv[optind]); + ++optind; + /* fallthrough */ + case 0: + break; + default: + usage("Too many arguments for --list-all", stderr); + goto error; + } + } else { + switch (argc - optind) { + case 2: + settings->test_root = absolute_path(argv[optind]); + ++optind; + /* fallthrough */ + case 1: + settings->results_path = absolute_path(argv[optind]); + break; + case 0: + usage("Results-path missing", stderr); + goto error; + default: + usage("Extra arguments after results-path", stderr); + goto error; + } + if (!settings->name) { + char *name = strdup(settings->results_path); + + settings->name = strdup(basename(name)); + free(name); + } } if ((env_test_root = getenv("IGT_TEST_ROOT")) != NULL) { @@ -386,11 +464,6 @@ bool parse_options(int argc, char **argv, goto error; } - if (!settings->name) { - char *name = strdup(settings->results_path); - settings->name = strdup(basename(name)); - free(name); - } return true; diff --git a/runner/settings.h b/runner/settings.h index 672a3af8..6dcfa8c5 100644 --- a/runner/settings.h +++ b/runner/settings.h @@ -4,8 +4,8 @@ #include <stdbool.h> #include <stddef.h> #include <sys/types.h> -#include <regex.h> #include <stdio.h> +#include <glib.h> enum { LOG_LEVEL_NORMAL = 0, @@ -21,7 +21,7 @@ _Static_assert(ABORT_ALL == (ABORT_TAINT | ABORT_LOCKDEP), "ABORT_ALL must be al struct regex_list { char **regex_strings; - regex_t** regexes; + GRegex **regexes; size_t size; }; @@ -43,6 +43,7 @@ struct settings { char *results_path; bool piglit_style_dmesg; int dmesg_warn_level; + bool list_all; }; /** diff --git a/runner/testdata/meson.build b/runner/testdata/meson.build index 011eff8e..2456f82a 100644 --- a/runner/testdata/meson.build +++ b/runner/testdata/meson.build @@ -12,6 +12,11 @@ foreach prog : testdata_progs install : false) endforeach +configure_file(input : 'test-blacklist.txt', + output : 'test-blacklist.txt', copy : true) +configure_file(input : 'test-blacklist2.txt', + output : 'test-blacklist2.txt', copy : true) + testdata_list = custom_target('testdata_testlist', output : 'test-list.txt', command : [ gen_testlist, '@OUTPUT@', testdata_progs ], diff --git a/runner/testdata/test-blacklist.txt b/runner/testdata/test-blacklist.txt new file mode 100644 index 00000000..6b09ae5c --- /dev/null +++ b/runner/testdata/test-blacklist.txt @@ -0,0 +1,2 @@ +xpattern3 # Comment 1 +# Comment 2 diff --git a/runner/testdata/test-blacklist2.txt b/runner/testdata/test-blacklist2.txt new file mode 100644 index 00000000..d0f6e612 --- /dev/null +++ b/runner/testdata/test-blacklist2.txt @@ -0,0 +1,2 @@ + +xpattern4 |