1 // SPDX-License-Identifier: GPL-2.0
3 * KUnit test for the KUnit executor.
5 * Copyright (C) 2021, Google LLC.
6 * Author: Daniel Latypov <dlatypov@google.com>
9 #include <kunit/test.h>
10 #include <kunit/attributes.h>
12 static void free_suite_set_at_end(struct kunit
*test
, const void *to_free
);
13 static struct kunit_suite
*alloc_fake_suite(struct kunit
*test
,
14 const char *suite_name
,
15 struct kunit_case
*test_cases
);
17 static void dummy_test(struct kunit
*test
) {}
19 static struct kunit_case dummy_test_cases
[] = {
20 /* .run_case is not important, just needs to be non-NULL */
21 { .name
= "test1", .run_case
= dummy_test
},
22 { .name
= "test2", .run_case
= dummy_test
},
26 static void parse_filter_test(struct kunit
*test
)
28 struct kunit_glob_filter filter
= {NULL
, NULL
};
30 kunit_parse_glob_filter(&filter
, "suite");
31 KUNIT_EXPECT_STREQ(test
, filter
.suite_glob
, "suite");
32 KUNIT_EXPECT_FALSE(test
, filter
.test_glob
);
33 kfree(filter
.suite_glob
);
34 kfree(filter
.test_glob
);
36 kunit_parse_glob_filter(&filter
, "suite.test");
37 KUNIT_EXPECT_STREQ(test
, filter
.suite_glob
, "suite");
38 KUNIT_EXPECT_STREQ(test
, filter
.test_glob
, "test");
39 kfree(filter
.suite_glob
);
40 kfree(filter
.test_glob
);
43 static void filter_suites_test(struct kunit
*test
)
45 struct kunit_suite
*subsuite
[3] = {NULL
, NULL
};
46 struct kunit_suite_set suite_set
= {
47 .start
= subsuite
, .end
= &subsuite
[2],
49 struct kunit_suite_set got
;
52 subsuite
[0] = alloc_fake_suite(test
, "suite1", dummy_test_cases
);
53 subsuite
[1] = alloc_fake_suite(test
, "suite2", dummy_test_cases
);
55 /* Want: suite1, suite2, NULL -> suite2, NULL */
56 got
= kunit_filter_suites(&suite_set
, "suite2", NULL
, NULL
, &err
);
57 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
);
58 KUNIT_ASSERT_EQ(test
, err
, 0);
59 free_suite_set_at_end(test
, &got
);
61 /* Validate we just have suite2 */
62 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]);
63 KUNIT_EXPECT_STREQ(test
, (const char *)got
.start
[0]->name
, "suite2");
65 /* Contains one element (end is 1 past end) */
66 KUNIT_ASSERT_EQ(test
, got
.end
- got
.start
, 1);
69 static void filter_suites_test_glob_test(struct kunit
*test
)
71 struct kunit_suite
*subsuite
[3] = {NULL
, NULL
};
72 struct kunit_suite_set suite_set
= {
73 .start
= subsuite
, .end
= &subsuite
[2],
75 struct kunit_suite_set got
;
78 subsuite
[0] = alloc_fake_suite(test
, "suite1", dummy_test_cases
);
79 subsuite
[1] = alloc_fake_suite(test
, "suite2", dummy_test_cases
);
81 /* Want: suite1, suite2, NULL -> suite2 (just test1), NULL */
82 got
= kunit_filter_suites(&suite_set
, "suite2.test2", NULL
, NULL
, &err
);
83 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
);
84 KUNIT_ASSERT_EQ(test
, err
, 0);
85 free_suite_set_at_end(test
, &got
);
87 /* Validate we just have suite2 */
88 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]);
89 KUNIT_EXPECT_STREQ(test
, (const char *)got
.start
[0]->name
, "suite2");
90 KUNIT_ASSERT_EQ(test
, got
.end
- got
.start
, 1);
92 /* Now validate we just have test2 */
93 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]->test_cases
);
94 KUNIT_EXPECT_STREQ(test
, (const char *)got
.start
[0]->test_cases
[0].name
, "test2");
95 KUNIT_EXPECT_FALSE(test
, got
.start
[0]->test_cases
[1].name
);
98 static void filter_suites_to_empty_test(struct kunit
*test
)
100 struct kunit_suite
*subsuite
[3] = {NULL
, NULL
};
101 struct kunit_suite_set suite_set
= {
102 .start
= subsuite
, .end
= &subsuite
[2],
104 struct kunit_suite_set got
;
107 subsuite
[0] = alloc_fake_suite(test
, "suite1", dummy_test_cases
);
108 subsuite
[1] = alloc_fake_suite(test
, "suite2", dummy_test_cases
);
110 got
= kunit_filter_suites(&suite_set
, "not_found", NULL
, NULL
, &err
);
111 KUNIT_ASSERT_EQ(test
, err
, 0);
112 free_suite_set_at_end(test
, &got
); /* just in case */
114 KUNIT_EXPECT_PTR_EQ_MSG(test
, got
.start
, got
.end
,
115 "should be empty to indicate no match");
118 static void parse_filter_attr_test(struct kunit
*test
)
121 struct kunit_attr_filter
*parsed_filters
;
122 char filters
[] = "speed>slow, module!=example", *filter
= filters
;
125 filter_count
= kunit_get_filter_count(filters
);
126 KUNIT_EXPECT_EQ(test
, filter_count
, 2);
128 parsed_filters
= kunit_kcalloc(test
, filter_count
, sizeof(*parsed_filters
),
130 for (j
= 0; j
< filter_count
; j
++) {
131 parsed_filters
[j
] = kunit_next_attr_filter(&filter
, &err
);
132 KUNIT_ASSERT_EQ_MSG(test
, err
, 0, "failed to parse filter from '%s'", filters
);
135 KUNIT_EXPECT_STREQ(test
, kunit_attr_filter_name(parsed_filters
[0]), "speed");
136 KUNIT_EXPECT_STREQ(test
, parsed_filters
[0].input
, ">slow");
138 KUNIT_EXPECT_STREQ(test
, kunit_attr_filter_name(parsed_filters
[1]), "module");
139 KUNIT_EXPECT_STREQ(test
, parsed_filters
[1].input
, "!=example");
142 static struct kunit_case dummy_attr_test_cases
[] = {
143 /* .run_case is not important, just needs to be non-NULL */
144 { .name
= "slow", .run_case
= dummy_test
, .module_name
= "dummy",
145 .attr
.speed
= KUNIT_SPEED_SLOW
},
146 { .name
= "normal", .run_case
= dummy_test
, .module_name
= "dummy" },
150 static void filter_attr_test(struct kunit
*test
)
152 struct kunit_suite
*subsuite
[3] = {NULL
, NULL
};
153 struct kunit_suite_set suite_set
= {
154 .start
= subsuite
, .end
= &subsuite
[2],
156 struct kunit_suite_set got
;
157 char filter
[] = "speed>slow";
160 subsuite
[0] = alloc_fake_suite(test
, "normal_suite", dummy_attr_test_cases
);
161 subsuite
[1] = alloc_fake_suite(test
, "slow_suite", dummy_attr_test_cases
);
162 subsuite
[1]->attr
.speed
= KUNIT_SPEED_SLOW
; // Set suite attribute
165 * Want: normal_suite(slow, normal), slow_suite(slow, normal),
166 * NULL -> normal_suite(normal), NULL
168 * The normal test in slow_suite is filtered out because the speed
169 * attribute is unset and thus, the filtering is based on the parent attribute
172 got
= kunit_filter_suites(&suite_set
, NULL
, filter
, NULL
, &err
);
173 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
);
174 KUNIT_ASSERT_EQ(test
, err
, 0);
175 free_suite_set_at_end(test
, &got
);
177 /* Validate we just have normal_suite */
178 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]);
179 KUNIT_EXPECT_STREQ(test
, got
.start
[0]->name
, "normal_suite");
180 KUNIT_ASSERT_EQ(test
, got
.end
- got
.start
, 1);
182 /* Now validate we just have normal test case */
183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]->test_cases
);
184 KUNIT_EXPECT_STREQ(test
, got
.start
[0]->test_cases
[0].name
, "normal");
185 KUNIT_EXPECT_FALSE(test
, got
.start
[0]->test_cases
[1].name
);
188 static void filter_attr_empty_test(struct kunit
*test
)
190 struct kunit_suite
*subsuite
[3] = {NULL
, NULL
};
191 struct kunit_suite_set suite_set
= {
192 .start
= subsuite
, .end
= &subsuite
[2],
194 struct kunit_suite_set got
;
195 char filter
[] = "module!=dummy";
198 subsuite
[0] = alloc_fake_suite(test
, "suite1", dummy_attr_test_cases
);
199 subsuite
[1] = alloc_fake_suite(test
, "suite2", dummy_attr_test_cases
);
201 got
= kunit_filter_suites(&suite_set
, NULL
, filter
, NULL
, &err
);
202 KUNIT_ASSERT_EQ(test
, err
, 0);
203 free_suite_set_at_end(test
, &got
); /* just in case */
205 KUNIT_EXPECT_PTR_EQ_MSG(test
, got
.start
, got
.end
,
206 "should be empty to indicate no match");
209 static void filter_attr_skip_test(struct kunit
*test
)
211 struct kunit_suite
*subsuite
[2] = {NULL
};
212 struct kunit_suite_set suite_set
= {
213 .start
= subsuite
, .end
= &subsuite
[1],
215 struct kunit_suite_set got
;
216 char filter
[] = "speed>slow";
219 subsuite
[0] = alloc_fake_suite(test
, "suite", dummy_attr_test_cases
);
221 /* Want: suite(slow, normal), NULL -> suite(slow with SKIP, normal), NULL */
222 got
= kunit_filter_suites(&suite_set
, NULL
, filter
, "skip", &err
);
223 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
);
224 KUNIT_ASSERT_EQ(test
, err
, 0);
225 free_suite_set_at_end(test
, &got
);
227 /* Validate we have both the slow and normal test */
228 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, got
.start
[0]->test_cases
);
229 KUNIT_ASSERT_EQ(test
, kunit_suite_num_test_cases(got
.start
[0]), 2);
230 KUNIT_EXPECT_STREQ(test
, got
.start
[0]->test_cases
[0].name
, "slow");
231 KUNIT_EXPECT_STREQ(test
, got
.start
[0]->test_cases
[1].name
, "normal");
233 /* Now ensure slow is skipped and normal is not */
234 KUNIT_EXPECT_EQ(test
, got
.start
[0]->test_cases
[0].status
, KUNIT_SKIPPED
);
235 KUNIT_EXPECT_FALSE(test
, got
.start
[0]->test_cases
[1].status
);
238 static struct kunit_case executor_test_cases
[] = {
239 KUNIT_CASE(parse_filter_test
),
240 KUNIT_CASE(filter_suites_test
),
241 KUNIT_CASE(filter_suites_test_glob_test
),
242 KUNIT_CASE(filter_suites_to_empty_test
),
243 KUNIT_CASE(parse_filter_attr_test
),
244 KUNIT_CASE(filter_attr_test
),
245 KUNIT_CASE(filter_attr_empty_test
),
246 KUNIT_CASE(filter_attr_skip_test
),
250 static struct kunit_suite executor_test_suite
= {
251 .name
= "kunit_executor_test",
252 .test_cases
= executor_test_cases
,
255 kunit_test_suites(&executor_test_suite
);
259 static void free_suite_set(void *suite_set
)
261 kunit_free_suite_set(*(struct kunit_suite_set
*)suite_set
);
265 /* Use the resource API to register a call to free_suite_set.
266 * Since we never actually use the resource, it's safe to use on const data.
268 static void free_suite_set_at_end(struct kunit
*test
, const void *to_free
)
270 struct kunit_suite_set
*free
;
272 if (!((struct kunit_suite_set
*)to_free
)->start
)
275 free
= kzalloc(sizeof(struct kunit_suite_set
), GFP_KERNEL
);
276 *free
= *(struct kunit_suite_set
*)to_free
;
278 kunit_add_action(test
, free_suite_set
, (void *)free
);
281 static struct kunit_suite
*alloc_fake_suite(struct kunit
*test
,
282 const char *suite_name
,
283 struct kunit_case
*test_cases
)
285 struct kunit_suite
*suite
;
287 /* We normally never expect to allocate suites, hence the non-const cast. */
288 suite
= kunit_kzalloc(test
, sizeof(*suite
), GFP_KERNEL
);
289 strscpy((char *)suite
->name
, suite_name
, sizeof(suite
->name
));
290 suite
->test_cases
= test_cases
;