#define workloads__for_each(workload) \
for (unsigned i = 0; i < ARRAY_SIZE(workloads) && ({ workload = workloads[i]; 1; }); i++)
-static int num_subtests(const struct test_suite *t)
+#define test_suite__for_each_test_case(suite, idx) \
+ for (idx = 0; (suite)->test_cases && (suite)->test_cases[idx].name != NULL; idx++)
+
+static int test_suite__num_test_cases(const struct test_suite *t)
{
int num;
- if (!t->test_cases)
- return 0;
-
- num = 0;
- while (t->test_cases[num].name)
- num++;
+ test_suite__for_each_test_case(t, num);
return num;
}
-static bool has_subtests(const struct test_suite *t)
-{
- return num_subtests(t) > 1;
-}
-
-static const char *skip_reason(const struct test_suite *t, int subtest)
+static const char *skip_reason(const struct test_suite *t, int test_case)
{
if (!t->test_cases)
return NULL;
- return t->test_cases[subtest >= 0 ? subtest : 0].skip_reason;
+ return t->test_cases[test_case >= 0 ? test_case : 0].skip_reason;
}
-static const char *test_description(const struct test_suite *t, int subtest)
+static const char *test_description(const struct test_suite *t, int test_case)
{
- if (t->test_cases && subtest >= 0)
- return t->test_cases[subtest].desc;
+ if (t->test_cases && test_case >= 0)
+ return t->test_cases[test_case].desc;
return t->desc;
}
-static test_fnptr test_function(const struct test_suite *t, int subtest)
+static test_fnptr test_function(const struct test_suite *t, int test_case)
{
- if (subtest <= 0)
+ if (test_case <= 0)
return t->test_cases[0].run_case;
- return t->test_cases[subtest].run_case;
+ return t->test_cases[test_case].run_case;
}
-static bool test_exclusive(const struct test_suite *t, int subtest)
+static bool test_exclusive(const struct test_suite *t, int test_case)
{
- if (subtest <= 0)
+ if (test_case <= 0)
return t->test_cases[0].exclusive;
- return t->test_cases[subtest].exclusive;
+ return t->test_cases[test_case].exclusive;
}
-static bool perf_test__matches(const char *desc, int curr, int argc, const char *argv[])
+static bool perf_test__matches(const char *desc, int suite_num, int argc, const char *argv[])
{
int i;
long nr = strtoul(argv[i], &end, 10);
if (*end == '\0') {
- if (nr == curr + 1)
+ if (nr == suite_num + 1)
return true;
continue;
}
struct child_test {
struct child_process process;
struct test_suite *test;
- int test_num;
- int subtest;
+ int suite_num;
+ int test_case_num;
};
static jmp_buf run_test_jmp_buf;
pr_debug("--- start ---\n");
pr_debug("test child forked, pid %d\n", getpid());
- err = test_function(child->test, child->subtest)(child->test, child->subtest);
+ err = test_function(child->test, child->test_case_num)(child->test, child->test_case_num);
pr_debug("---- end(%d) ----\n", err);
err_out:
#define TEST_RUNNING -3
-static int print_test_result(struct test_suite *t, int i, int subtest, int result, int width,
- int running)
+static int print_test_result(struct test_suite *t, int curr_suite, int curr_test_case,
+ int result, int width, int running)
{
- if (has_subtests(t)) {
+ if (test_suite__num_test_cases(t) > 1) {
int subw = width > 2 ? width - 2 : width;
- pr_info("%3d.%1d: %-*s:", i + 1, subtest + 1, subw, test_description(t, subtest));
+ pr_info("%3d.%1d: %-*s:", curr_suite + 1, curr_test_case + 1, subw,
+ test_description(t, curr_test_case));
} else
- pr_info("%3d: %-*s:", i + 1, width, test_description(t, subtest));
+ pr_info("%3d: %-*s:", curr_suite + 1, width, test_description(t, curr_test_case));
switch (result) {
case TEST_RUNNING:
pr_info(" Ok\n");
break;
case TEST_SKIP: {
- const char *reason = skip_reason(t, subtest);
+ const char *reason = skip_reason(t, curr_test_case);
if (reason)
color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason);
{
struct child_test *child_test = child_tests[running_test];
struct test_suite *t;
- int i, subi, err;
+ int curr_suite, curr_test_case, err;
bool err_done = false;
struct strbuf err_output = STRBUF_INIT;
int last_running = -1;
return;
}
t = child_test->test;
- i = child_test->test_num;
- subi = child_test->subtest;
+ curr_suite = child_test->suite_num;
+ curr_test_case = child_test->test_case_num;
err = child_test->process.err;
/*
* For test suites with subtests, display the suite name ahead of the
* sub test names.
*/
- if (has_subtests(t) && subi == 0)
- pr_info("%3d: %-*s:\n", i + 1, width, test_description(t, -1));
+ if (test_suite__num_test_cases(t) > 1 && curr_test_case == 0)
+ pr_info("%3d: %-*s:\n", curr_suite + 1, width, test_description(t, -1));
/*
* Busy loop reading from the child's stdout/stderr that are set to be
if (err > 0)
fcntl(err, F_SETFL, O_NONBLOCK);
if (verbose > 1) {
- if (has_subtests(t))
- pr_info("%3d.%1d: %s:\n", i + 1, subi + 1, test_description(t, subi));
+ if (test_suite__num_test_cases(t) > 1)
+ pr_info("%3d.%1d: %s:\n", curr_suite + 1, curr_test_case + 1,
+ test_description(t, curr_test_case));
else
- pr_info("%3d: %s:\n", i + 1, test_description(t, -1));
+ pr_info("%3d: %s:\n", curr_suite + 1, test_description(t, -1));
}
while (!err_done) {
struct pollfd pfds[1] = {
*/
fprintf(debug_file(), PERF_COLOR_DELETE_LINE);
}
- print_test_result(t, i, subi, TEST_RUNNING, width, running);
+ print_test_result(t, curr_suite, curr_test_case, TEST_RUNNING,
+ width, running);
last_running = running;
}
}
fprintf(stderr, "%s", err_output.buf);
strbuf_release(&err_output);
- print_test_result(t, i, subi, ret, width, /*running=*/0);
+ print_test_result(t, curr_suite, curr_test_case, ret, width, /*running=*/0);
if (err > 0)
close(err);
zfree(&child_tests[running_test]);
}
-static int start_test(struct test_suite *test, int i, int subi, struct child_test **child,
- int width, int pass)
+static int start_test(struct test_suite *test, int curr_suite, int curr_test_case,
+ struct child_test **child, int width, int pass)
{
int err;
if (dont_fork) {
if (pass == 1) {
pr_debug("--- start ---\n");
- err = test_function(test, subi)(test, subi);
+ err = test_function(test, curr_test_case)(test, curr_test_case);
pr_debug("---- end ----\n");
- print_test_result(test, i, subi, err, width, /*running=*/0);
+ print_test_result(test, curr_suite, curr_test_case, err, width,
+ /*running=*/0);
}
return 0;
}
- if (pass == 1 && !sequential && test_exclusive(test, subi)) {
+ if (pass == 1 && !sequential && test_exclusive(test, curr_test_case)) {
/* When parallel, skip exclusive tests on the first pass. */
return 0;
}
- if (pass != 1 && (sequential || !test_exclusive(test, subi))) {
+ if (pass != 1 && (sequential || !test_exclusive(test, curr_test_case))) {
/* Sequential and non-exclusive tests were run on the first pass. */
return 0;
}
return -ENOMEM;
(*child)->test = test;
- (*child)->test_num = i;
- (*child)->subtest = subi;
+ (*child)->suite_num = curr_suite;
+ (*child)->test_case_num = curr_test_case;
(*child)->process.pid = -1;
(*child)->process.no_stdin = 1;
if (verbose <= 0) {
int err = 0;
for (struct test_suite **t = suites; *t; t++) {
- int len = strlen(test_description(*t, -1));
+ int i, len = strlen(test_description(*t, -1));
if (width < len)
width = len;
- if (has_subtests(*t)) {
- for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) {
- len = strlen(test_description(*t, subi));
- if (width < len)
- width = len;
- num_tests++;
- }
- } else {
+ test_suite__for_each_test_case(*t, i) {
+ len = strlen(test_description(*t, i));
+ if (width < len)
+ width = len;
num_tests++;
}
}
continue;
pr_debug3("Killing %d pid %d\n",
- child_test->test_num + 1,
+ child_test->suite_num + 1,
child_test->process.pid);
kill(child_test->process.pid, err);
}
*/
for (int pass = 1; pass <= 2; pass++) {
int child_test_num = 0;
- int i = 0;
+ int curr_suite = 0;
- for (struct test_suite **t = suites; *t; t++) {
- int curr = i++;
+ for (struct test_suite **t = suites; *t; t++, curr_suite++) {
+ int curr_test_case;
- if (!perf_test__matches(test_description(*t, -1), curr, argc, argv)) {
+ if (!perf_test__matches(test_description(*t, -1), curr_suite, argc, argv)) {
/*
* Test suite shouldn't be run based on
- * description. See if subtest should.
+ * description. See if any test case should.
*/
bool skip = true;
- for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) {
- if (perf_test__matches(test_description(*t, subi),
- curr, argc, argv))
+ test_suite__for_each_test_case(*t, curr_test_case) {
+ if (perf_test__matches(test_description(*t, curr_test_case),
+ curr_suite, argc, argv)) {
skip = false;
+ break;
+ }
}
-
if (skip)
continue;
}
- if (intlist__find(skiplist, i)) {
- pr_info("%3d: %-*s:", curr + 1, width, test_description(*t, -1));
+ if (intlist__find(skiplist, curr_suite + 1)) {
+ pr_info("%3d: %-*s:", curr_suite + 1, width,
+ test_description(*t, -1));
color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
continue;
}
- if (!has_subtests(*t)) {
- err = start_test(*t, curr, -1, &child_tests[child_test_num++],
- width, pass);
- if (err)
- goto err_out;
- continue;
- }
- for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) {
- if (!perf_test__matches(test_description(*t, subi),
- curr, argc, argv))
+ test_suite__for_each_test_case(*t, curr_test_case) {
+ if (!perf_test__matches(test_description(*t, curr_test_case),
+ curr_suite, argc, argv))
continue;
- err = start_test(*t, curr, subi, &child_tests[child_test_num++],
+ err = start_test(*t, curr_suite, curr_test_case,
+ &child_tests[child_test_num++],
width, pass);
if (err)
goto err_out;
static int perf_test__list(struct test_suite **suites, int argc, const char **argv)
{
- int i = 0;
+ int curr_suite = 0;
- for (struct test_suite **t = suites; *t; t++) {
- int curr = i++;
+ for (struct test_suite **t = suites; *t; t++, curr_suite++) {
+ int curr_test_case;
- if (!perf_test__matches(test_description(*t, -1), curr, argc, argv))
+ if (!perf_test__matches(test_description(*t, -1), curr_suite, argc, argv))
continue;
- pr_info("%3d: %s\n", i, test_description(*t, -1));
+ pr_info("%3d: %s\n", curr_suite + 1, test_description(*t, -1));
- if (has_subtests(*t)) {
- int subn = num_subtests(*t);
- int subi;
+ if (test_suite__num_test_cases(*t) <= 1)
+ continue;
- for (subi = 0; subi < subn; subi++)
- pr_info("%3d:%1d: %s\n", i, subi + 1,
- test_description(*t, subi));
+ test_suite__for_each_test_case(*t, curr_test_case) {
+ pr_info("%3d:%1d: %s\n", curr_suite + 1, curr_test_case + 1,
+ test_description(*t, curr_test_case));
}
}
return 0;
if (suites[2] == NULL)
suites[2] = create_script_test_suites();
-#define for_each_test(t) \
+#define for_each_suite(suite) \
for (size_t i = 0, j = 0; i < ARRAY_SIZE(suites); i++, j = 0) \
- while ((t = suites[i][j++]) != NULL)
+ while ((suite = suites[i][j++]) != NULL)
- for_each_test(t)
+ for_each_suite(t)
num_suites++;
result = calloc(num_suites + 1, sizeof(struct test_suite *));
for (int pass = 1; pass <= 2; pass++) {
- for_each_test(t) {
+ for_each_suite(t) {
bool exclusive = false;
+ int curr_test_case;
- if (!has_subtests(t)) {
- exclusive = test_exclusive(t, -1);
- } else {
- for (int subi = 0, subn = num_subtests(t); subi < subn; subi++) {
- if (test_exclusive(t, subi)) {
- exclusive = true;
- break;
- }
+ test_suite__for_each_test_case(t, curr_test_case) {
+ if (test_exclusive(t, curr_test_case)) {
+ exclusive = true;
+ break;
}
}
if ((!exclusive && pass == 1) || (exclusive && pass == 2))
}
}
return result;
-#undef for_each_test
+#undef for_each_suite
}
int cmd_test(int argc, const char **argv)