xref: /linux/tools/testing/selftests/bpf/prog_tests/prog_tests_framework.c (revision cb9f145f638d7afa633632a9290d6ad06caeb8ee)
1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2 
3 #include "test_progs.h"
4 #include "testing_helpers.h"
5 
6 static void clear_test_state(struct test_state *state)
7 {
8 	state->error_cnt = 0;
9 	state->sub_succ_cnt = 0;
10 	state->skip_cnt = 0;
11 }
12 
13 void test_prog_tests_framework(void)
14 {
15 	struct test_state *state = env.test_state;
16 
17 	/* in all the ASSERT calls below we need to return on the first
18 	 * error due to the fact that we are cleaning the test state after
19 	 * each dummy subtest
20 	 */
21 
22 	/* test we properly count skipped tests with subtests */
23 	if (test__start_subtest("test_good_subtest"))
24 		test__end_subtest();
25 	if (!ASSERT_EQ(state->skip_cnt, 0, "skip_cnt_check"))
26 		return;
27 	if (!ASSERT_EQ(state->error_cnt, 0, "error_cnt_check"))
28 		return;
29 	if (!ASSERT_EQ(state->subtest_num, 1, "subtest_num_check"))
30 		return;
31 	clear_test_state(state);
32 
33 	if (test__start_subtest("test_skip_subtest")) {
34 		test__skip();
35 		test__end_subtest();
36 	}
37 	if (test__start_subtest("test_skip_subtest")) {
38 		test__skip();
39 		test__end_subtest();
40 	}
41 	if (!ASSERT_EQ(state->skip_cnt, 2, "skip_cnt_check"))
42 		return;
43 	if (!ASSERT_EQ(state->subtest_num, 3, "subtest_num_check"))
44 		return;
45 	clear_test_state(state);
46 
47 	if (test__start_subtest("test_fail_subtest")) {
48 		test__fail();
49 		test__end_subtest();
50 	}
51 	if (!ASSERT_EQ(state->error_cnt, 1, "error_cnt_check"))
52 		return;
53 	if (!ASSERT_EQ(state->subtest_num, 4, "subtest_num_check"))
54 		return;
55 	clear_test_state(state);
56 }
57 
58 static void dummy_emit(const char *buf, bool force) {}
59 
60 void test_prog_tests_framework_expected_msgs(void)
61 {
62 	struct expected_msgs msgs;
63 	int i, j, error_cnt;
64 	const struct {
65 		const char *name;
66 		const char *log;
67 		const char *expected;
68 		struct expect_msg *pats;
69 	} cases[] = {
70 		{
71 			.name = "simple-ok",
72 			.log = "aaabbbccc",
73 			.pats = (struct expect_msg[]) {
74 				{ .substr = "aaa" },
75 				{ .substr = "ccc" },
76 				{}
77 			}
78 		},
79 		{
80 			.name = "simple-fail",
81 			.log = "aaabbbddd",
82 			.expected = "MATCHED    SUBSTR: 'aaa'\n"
83 				    "EXPECTED   SUBSTR: 'ccc'\n",
84 			.pats = (struct expect_msg[]) {
85 				{ .substr = "aaa" },
86 				{ .substr = "ccc" },
87 				{}
88 			}
89 		},
90 		{
91 			.name = "negative-ok-mid",
92 			.log = "aaabbbccc",
93 			.pats = (struct expect_msg[]) {
94 				{ .substr = "aaa" },
95 				{ .substr = "foo", .negative = true },
96 				{ .substr = "bar", .negative = true },
97 				{ .substr = "ccc" },
98 				{}
99 			}
100 		},
101 		{
102 			.name = "negative-ok-tail",
103 			.log = "aaabbbccc",
104 			.pats = (struct expect_msg[]) {
105 				{ .substr = "aaa" },
106 				{ .substr = "foo", .negative = true },
107 				{}
108 			}
109 		},
110 		{
111 			.name = "negative-ok-head",
112 			.log = "aaabbbccc",
113 			.pats = (struct expect_msg[]) {
114 				{ .substr = "foo", .negative = true },
115 				{ .substr = "ccc" },
116 				{}
117 			}
118 		},
119 		{
120 			.name = "negative-fail-head",
121 			.log = "aaabbbccc",
122 			.expected = "UNEXPECTED SUBSTR: 'aaa'\n",
123 			.pats = (struct expect_msg[]) {
124 				{ .substr = "aaa", .negative = true },
125 				{ .substr = "bbb" },
126 				{}
127 			}
128 		},
129 		{
130 			.name = "negative-fail-tail",
131 			.log = "aaabbbccc",
132 			.expected = "UNEXPECTED SUBSTR: 'ccc'\n",
133 			.pats = (struct expect_msg[]) {
134 				{ .substr = "bbb" },
135 				{ .substr = "ccc", .negative = true },
136 				{}
137 			}
138 		},
139 		{
140 			.name = "negative-fail-mid-1",
141 			.log = "aaabbbccc",
142 			.expected = "UNEXPECTED SUBSTR: 'bbb'\n",
143 			.pats = (struct expect_msg[]) {
144 				{ .substr = "aaa" },
145 				{ .substr = "bbb", .negative = true },
146 				{ .substr = "ccc" },
147 				{}
148 			}
149 		},
150 		{
151 			.name = "negative-fail-mid-2",
152 			.log = "aaabbb222ccc",
153 			.expected = "UNEXPECTED SUBSTR: '222'\n",
154 			.pats = (struct expect_msg[]) {
155 				{ .substr = "aaa" },
156 				{ .substr = "222", .negative = true },
157 				{ .substr = "bbb", .negative = true },
158 				{ .substr = "ccc" },
159 				{}
160 			}
161 		}
162 	};
163 
164 	for (i = 0; i < ARRAY_SIZE(cases); i++) {
165 		if (test__start_subtest(cases[i].name)) {
166 			error_cnt = env.subtest_state->error_cnt;
167 			msgs.patterns = cases[i].pats;
168 			msgs.cnt = 0;
169 			for (j = 0; cases[i].pats[j].substr; j++)
170 				msgs.cnt++;
171 			validate_msgs(cases[i].log, &msgs, dummy_emit);
172 			fflush(stderr);
173 			env.subtest_state->error_cnt = error_cnt;
174 			if (cases[i].expected)
175 				ASSERT_HAS_SUBSTR(env.subtest_state->log_buf, cases[i].expected, "expected output");
176 			else
177 				ASSERT_STREQ(env.subtest_state->log_buf, "", "expected no output");
178 			test__end_subtest();
179 		}
180 	}
181 }
182