fix short copy handling in copy_mc_pipe_to_iter()
[sfrench/cifs-2.6.git] / lib / kunit / executor_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * KUnit test for the KUnit executor.
4  *
5  * Copyright (C) 2021, Google LLC.
6  * Author: Daniel Latypov <dlatypov@google.com>
7  */
8
9 #include <kunit/test.h>
10
11 static void kfree_at_end(struct kunit *test, const void *to_free);
12 static void free_subsuite_at_end(struct kunit *test,
13                                  struct kunit_suite *const *to_free);
14 static struct kunit_suite *alloc_fake_suite(struct kunit *test,
15                                             const char *suite_name,
16                                             struct kunit_case *test_cases);
17
18 static void dummy_test(struct kunit *test) {}
19
20 static struct kunit_case dummy_test_cases[] = {
21         /* .run_case is not important, just needs to be non-NULL */
22         { .name = "test1", .run_case = dummy_test },
23         { .name = "test2", .run_case = dummy_test },
24         {},
25 };
26
27 static void parse_filter_test(struct kunit *test)
28 {
29         struct kunit_test_filter filter = {NULL, NULL};
30
31         kunit_parse_filter_glob(&filter, "suite");
32         KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
33         KUNIT_EXPECT_FALSE(test, filter.test_glob);
34         kfree(filter.suite_glob);
35         kfree(filter.test_glob);
36
37         kunit_parse_filter_glob(&filter, "suite.test");
38         KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
39         KUNIT_EXPECT_STREQ(test, filter.test_glob, "test");
40         kfree(filter.suite_glob);
41         kfree(filter.test_glob);
42 }
43
44 static void filter_subsuite_test(struct kunit *test)
45 {
46         struct kunit_suite *subsuite[3] = {NULL, NULL, NULL};
47         struct kunit_suite * const *filtered;
48         struct kunit_test_filter filter = {
49                 .suite_glob = "suite2",
50                 .test_glob = NULL,
51         };
52
53         subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
54         subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
55
56         /* Want: suite1, suite2, NULL -> suite2, NULL */
57         filtered = kunit_filter_subsuite(subsuite, &filter);
58         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered);
59         free_subsuite_at_end(test, filtered);
60
61         /* Validate we just have suite2 */
62         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered[0]);
63         KUNIT_EXPECT_STREQ(test, (const char *)filtered[0]->name, "suite2");
64         KUNIT_EXPECT_FALSE(test, filtered[1]);
65 }
66
67 static void filter_subsuite_test_glob_test(struct kunit *test)
68 {
69         struct kunit_suite *subsuite[3] = {NULL, NULL, NULL};
70         struct kunit_suite * const *filtered;
71         struct kunit_test_filter filter = {
72                 .suite_glob = "suite2",
73                 .test_glob = "test2",
74         };
75
76         subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
77         subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
78
79         /* Want: suite1, suite2, NULL -> suite2 (just test1), NULL */
80         filtered = kunit_filter_subsuite(subsuite, &filter);
81         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered);
82         free_subsuite_at_end(test, filtered);
83
84         /* Validate we just have suite2 */
85         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered[0]);
86         KUNIT_EXPECT_STREQ(test, (const char *)filtered[0]->name, "suite2");
87         KUNIT_EXPECT_FALSE(test, filtered[1]);
88
89         /* Now validate we just have test2 */
90         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered[0]->test_cases);
91         KUNIT_EXPECT_STREQ(test, (const char *)filtered[0]->test_cases[0].name, "test2");
92         KUNIT_EXPECT_FALSE(test, filtered[0]->test_cases[1].name);
93 }
94
95 static void filter_subsuite_to_empty_test(struct kunit *test)
96 {
97         struct kunit_suite *subsuite[3] = {NULL, NULL, NULL};
98         struct kunit_suite * const *filtered;
99         struct kunit_test_filter filter = {
100                 .suite_glob = "not_found",
101                 .test_glob = NULL,
102         };
103
104         subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
105         subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
106
107         filtered = kunit_filter_subsuite(subsuite, &filter);
108         free_subsuite_at_end(test, filtered); /* just in case */
109
110         KUNIT_EXPECT_FALSE_MSG(test, filtered,
111                                "should be NULL to indicate no match");
112 }
113
114 static void kfree_subsuites_at_end(struct kunit *test, struct suite_set *suite_set)
115 {
116         struct kunit_suite * const * const *suites;
117
118         kfree_at_end(test, suite_set->start);
119         for (suites = suite_set->start; suites < suite_set->end; suites++)
120                 free_subsuite_at_end(test, *suites);
121 }
122
123 static void filter_suites_test(struct kunit *test)
124 {
125         /* Suites per-file are stored as a NULL terminated array */
126         struct kunit_suite *subsuites[2][2] = {
127                 {NULL, NULL},
128                 {NULL, NULL},
129         };
130         /* Match the memory layout of suite_set */
131         struct kunit_suite * const * const suites[2] = {
132                 subsuites[0], subsuites[1],
133         };
134
135         const struct suite_set suite_set = {
136                 .start = suites,
137                 .end = suites + 2,
138         };
139         struct suite_set filtered = {.start = NULL, .end = NULL};
140         int err = 0;
141
142         /* Emulate two files, each having one suite */
143         subsuites[0][0] = alloc_fake_suite(test, "suite0", dummy_test_cases);
144         subsuites[1][0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
145
146         /* Filter out suite1 */
147         filtered = kunit_filter_suites(&suite_set, "suite0", &err);
148         kfree_subsuites_at_end(test, &filtered); /* let us use ASSERTs without leaking */
149         KUNIT_EXPECT_EQ(test, err, 0);
150         KUNIT_ASSERT_EQ(test, filtered.end - filtered.start, (ptrdiff_t)1);
151
152         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered.start);
153         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered.start[0]);
154         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered.start[0][0]);
155         KUNIT_EXPECT_STREQ(test, (const char *)filtered.start[0][0]->name, "suite0");
156 }
157
158 static struct kunit_case executor_test_cases[] = {
159         KUNIT_CASE(parse_filter_test),
160         KUNIT_CASE(filter_subsuite_test),
161         KUNIT_CASE(filter_subsuite_test_glob_test),
162         KUNIT_CASE(filter_subsuite_to_empty_test),
163         KUNIT_CASE(filter_suites_test),
164         {}
165 };
166
167 static struct kunit_suite executor_test_suite = {
168         .name = "kunit_executor_test",
169         .test_cases = executor_test_cases,
170 };
171
172 kunit_test_suites(&executor_test_suite);
173
174 /* Test helpers */
175
176 static void kfree_res_free(struct kunit_resource *res)
177 {
178         kfree(res->data);
179 }
180
181 /* Use the resource API to register a call to kfree(to_free).
182  * Since we never actually use the resource, it's safe to use on const data.
183  */
184 static void kfree_at_end(struct kunit *test, const void *to_free)
185 {
186         /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
187         if (IS_ERR_OR_NULL(to_free))
188                 return;
189         kunit_alloc_resource(test, NULL, kfree_res_free, GFP_KERNEL,
190                              (void *)to_free);
191 }
192
193 static void free_subsuite_res_free(struct kunit_resource *res)
194 {
195         kunit_free_subsuite(res->data);
196 }
197
198 static void free_subsuite_at_end(struct kunit *test,
199                                  struct kunit_suite *const *to_free)
200 {
201         if (IS_ERR_OR_NULL(to_free))
202                 return;
203         kunit_alloc_resource(test, NULL, free_subsuite_res_free,
204                              GFP_KERNEL, (void *)to_free);
205 }
206
207 static struct kunit_suite *alloc_fake_suite(struct kunit *test,
208                                             const char *suite_name,
209                                             struct kunit_case *test_cases)
210 {
211         struct kunit_suite *suite;
212
213         /* We normally never expect to allocate suites, hence the non-const cast. */
214         suite = kunit_kzalloc(test, sizeof(*suite), GFP_KERNEL);
215         strncpy((char *)suite->name, suite_name, sizeof(suite->name) - 1);
216         suite->test_cases = test_cases;
217
218         return suite;
219 }