Commit f5281aac authored by Kui-Feng Lee's avatar Kui-Feng Lee Committed by Martin KaFai Lau
Browse files

selftests/bpf: Add the traffic monitor option to test_progs.



Add option '-m' to test_progs to accept names and patterns of test cases.
This option will be used later to enable traffic monitor that capture
network packets generated by test cases.

Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Signed-off-by: default avatarKui-Feng Lee <thinker.li@gmail.com>
Link: https://lore.kernel.org/r/20240815053254.470944-3-thinker.li@gmail.com


Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent f52403b6
Loading
Loading
Loading
Loading
+62 −24
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ struct prog_test_def {
	void (*run_serial_test)(void);
	bool should_run;
	bool need_cgroup_cleanup;
	bool should_tmon;
};

/* Override C runtime library's usleep() implementation to ensure nanosleep()
@@ -192,39 +193,39 @@ static bool should_run(struct test_selector *sel, int num, const char *name)
	return num < sel->num_set_len && sel->num_set[num];
}

static bool should_run_subtest(struct test_selector *sel,
			       struct test_selector *subtest_sel,
			       int subtest_num,
static bool match_subtest(struct test_filter_set *filter,
			  const char *test_name,
			  const char *subtest_name)
{
	int i, j;

	for (i = 0; i < sel->blacklist.cnt; i++) {
		if (glob_match(test_name, sel->blacklist.tests[i].name)) {
			if (!sel->blacklist.tests[i].subtest_cnt)
				return false;
	for (i = 0; i < filter->cnt; i++) {
		if (glob_match(test_name, filter->tests[i].name)) {
			if (!filter->tests[i].subtest_cnt)
				return true;

			for (j = 0; j < sel->blacklist.tests[i].subtest_cnt; j++) {
			for (j = 0; j < filter->tests[i].subtest_cnt; j++) {
				if (glob_match(subtest_name,
					       sel->blacklist.tests[i].subtests[j]))
					return false;
					       filter->tests[i].subtests[j]))
					return true;
			}
		}
	}

	for (i = 0; i < sel->whitelist.cnt; i++) {
		if (glob_match(test_name, sel->whitelist.tests[i].name)) {
			if (!sel->whitelist.tests[i].subtest_cnt)
				return true;
	return false;
}

			for (j = 0; j < sel->whitelist.tests[i].subtest_cnt; j++) {
				if (glob_match(subtest_name,
					       sel->whitelist.tests[i].subtests[j]))
static bool should_run_subtest(struct test_selector *sel,
			       struct test_selector *subtest_sel,
			       int subtest_num,
			       const char *test_name,
			       const char *subtest_name)
{
	if (match_subtest(&sel->blacklist, test_name, subtest_name))
		return false;

	if (match_subtest(&sel->whitelist, test_name, subtest_name))
		return true;
			}
		}
	}

	if (!sel->whitelist.cnt && !subtest_sel->num_set)
		return true;
@@ -232,6 +233,19 @@ static bool should_run_subtest(struct test_selector *sel,
	return subtest_num < subtest_sel->num_set_len && subtest_sel->num_set[subtest_num];
}

static bool should_tmon(struct test_selector *sel, const char *name)
{
	int i;

	for (i = 0; i < sel->whitelist.cnt; i++) {
		if (glob_match(name, sel->whitelist.tests[i].name) &&
		    !sel->whitelist.tests[i].subtest_cnt)
			return true;
	}

	return false;
}

static char *test_result(bool failed, bool skipped)
{
	return failed ? "FAIL" : (skipped ? "SKIP" : "OK");
@@ -488,6 +502,10 @@ bool test__start_subtest(const char *subtest_name)
		return false;
	}

	subtest_state->should_tmon = match_subtest(&env.tmon_selector.whitelist,
						   test->test_name,
						   subtest_name);

	env.subtest_state = subtest_state;
	stdio_hijack_init(&subtest_state->log_buf, &subtest_state->log_cnt);

@@ -667,7 +685,8 @@ enum ARG_KEYS {
	ARG_TEST_NAME_GLOB_DENYLIST = 'd',
	ARG_NUM_WORKERS = 'j',
	ARG_DEBUG = -1,
	ARG_JSON_SUMMARY = 'J'
	ARG_JSON_SUMMARY = 'J',
	ARG_TRAFFIC_MONITOR = 'm',
};

static const struct argp_option opts[] = {
@@ -694,6 +713,10 @@ static const struct argp_option opts[] = {
	{ "debug", ARG_DEBUG, NULL, 0,
	  "print extra debug information for test_progs." },
	{ "json-summary", ARG_JSON_SUMMARY, "FILE", 0, "Write report in json format to this file."},
#ifdef TRAFFIC_MONITOR
	{ "traffic-monitor", ARG_TRAFFIC_MONITOR, "NAMES", 0,
	  "Monitor network traffic of tests with name matching the pattern (supports '*' wildcard)." },
#endif
	{},
};

@@ -905,6 +928,18 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
		break;
	case ARGP_KEY_END:
		break;
#ifdef TRAFFIC_MONITOR
	case ARG_TRAFFIC_MONITOR:
		if (arg[0] == '@')
			err = parse_test_list_file(arg + 1,
						   &env->tmon_selector.whitelist,
						   true);
		else
			err = parse_test_list(arg,
					      &env->tmon_selector.whitelist,
					      true);
		break;
#endif
	default:
		return ARGP_ERR_UNKNOWN;
	}
@@ -1736,6 +1771,8 @@ int main(int argc, char **argv)
				test->test_num, test->test_name, test->test_name, test->test_name);
			exit(EXIT_ERR_SETUP_INFRA);
		}
		if (test->should_run)
			test->should_tmon = should_tmon(&env.tmon_selector, test->test_name);
	}

	/* ignore workers if we are just listing */
@@ -1820,6 +1857,7 @@ int main(int argc, char **argv)

	free_test_selector(&env.test_selector);
	free_test_selector(&env.subtest_selector);
	free_test_selector(&env.tmon_selector);
	free_test_states();

	if (env.succ_cnt + env.fail_cnt + env.skip_cnt == 0)
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct subtest_state {
	int error_cnt;
	bool skipped;
	bool filtered;
	bool should_tmon;

	FILE *stdout_saved;
};
@@ -98,6 +99,7 @@ struct test_state {
struct test_env {
	struct test_selector test_selector;
	struct test_selector subtest_selector;
	struct test_selector tmon_selector;
	bool verifier_stats;
	bool debug;
	enum verbosity verbosity;