executor_test.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. #include <kunit/test.h>
  9. #include <kunit/attributes.h>
  10. static void free_suite_set_at_end(struct kunit *test, const void *to_free);
  11. static struct kunit_suite *alloc_fake_suite(struct kunit *test,
  12. const char *suite_name,
  13. struct kunit_case *test_cases);
  14. static void dummy_test(struct kunit *test) {}
  15. static struct kunit_case dummy_test_cases[] = {
  16. /* .run_case is not important, just needs to be non-NULL */
  17. { .name = "test1", .run_case = dummy_test },
  18. { .name = "test2", .run_case = dummy_test },
  19. {},
  20. };
  21. static void parse_filter_test(struct kunit *test)
  22. {
  23. struct kunit_glob_filter filter = {NULL, NULL};
  24. kunit_parse_glob_filter(&filter, "suite");
  25. KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
  26. KUNIT_EXPECT_FALSE(test, filter.test_glob);
  27. kfree(filter.suite_glob);
  28. kfree(filter.test_glob);
  29. kunit_parse_glob_filter(&filter, "suite.test");
  30. KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
  31. KUNIT_EXPECT_STREQ(test, filter.test_glob, "test");
  32. kfree(filter.suite_glob);
  33. kfree(filter.test_glob);
  34. }
  35. static void filter_suites_test(struct kunit *test)
  36. {
  37. struct kunit_suite *subsuite[3] = {NULL, NULL};
  38. struct kunit_suite_set suite_set = {
  39. .start = subsuite, .end = &subsuite[2],
  40. };
  41. struct kunit_suite_set got;
  42. int err = 0;
  43. subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
  44. subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
  45. /* Want: suite1, suite2, NULL -> suite2, NULL */
  46. got = kunit_filter_suites(&suite_set, "suite2", NULL, NULL, &err);
  47. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  48. KUNIT_ASSERT_EQ(test, err, 0);
  49. free_suite_set_at_end(test, &got);
  50. /* Validate we just have suite2 */
  51. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
  52. KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
  53. /* Contains one element (end is 1 past end) */
  54. KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
  55. }
  56. static void filter_suites_test_glob_test(struct kunit *test)
  57. {
  58. struct kunit_suite *subsuite[3] = {NULL, NULL};
  59. struct kunit_suite_set suite_set = {
  60. .start = subsuite, .end = &subsuite[2],
  61. };
  62. struct kunit_suite_set got;
  63. int err = 0;
  64. subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
  65. subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
  66. /* Want: suite1, suite2, NULL -> suite2 (just test1), NULL */
  67. got = kunit_filter_suites(&suite_set, "suite2.test2", NULL, NULL, &err);
  68. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  69. KUNIT_ASSERT_EQ(test, err, 0);
  70. free_suite_set_at_end(test, &got);
  71. /* Validate we just have suite2 */
  72. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
  73. KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
  74. KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
  75. /* Now validate we just have test2 */
  76. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
  77. KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->test_cases[0].name, "test2");
  78. KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].name);
  79. }
  80. static void filter_suites_to_empty_test(struct kunit *test)
  81. {
  82. struct kunit_suite *subsuite[3] = {NULL, NULL};
  83. struct kunit_suite_set suite_set = {
  84. .start = subsuite, .end = &subsuite[2],
  85. };
  86. struct kunit_suite_set got;
  87. int err = 0;
  88. subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
  89. subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
  90. got = kunit_filter_suites(&suite_set, "not_found", NULL, NULL, &err);
  91. KUNIT_ASSERT_EQ(test, err, 0);
  92. free_suite_set_at_end(test, &got); /* just in case */
  93. KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
  94. "should be empty to indicate no match");
  95. }
  96. static void parse_filter_attr_test(struct kunit *test)
  97. {
  98. int j, filter_count;
  99. struct kunit_attr_filter *parsed_filters;
  100. char filters[] = "speed>slow, module!=example", *filter = filters;
  101. int err = 0;
  102. filter_count = kunit_get_filter_count(filters);
  103. KUNIT_EXPECT_EQ(test, filter_count, 2);
  104. parsed_filters = kunit_kcalloc(test, filter_count, sizeof(*parsed_filters),
  105. GFP_KERNEL);
  106. for (j = 0; j < filter_count; j++) {
  107. parsed_filters[j] = kunit_next_attr_filter(&filter, &err);
  108. KUNIT_ASSERT_EQ_MSG(test, err, 0, "failed to parse filter from '%s'", filters);
  109. }
  110. KUNIT_EXPECT_STREQ(test, kunit_attr_filter_name(parsed_filters[0]), "speed");
  111. KUNIT_EXPECT_STREQ(test, parsed_filters[0].input, ">slow");
  112. KUNIT_EXPECT_STREQ(test, kunit_attr_filter_name(parsed_filters[1]), "module");
  113. KUNIT_EXPECT_STREQ(test, parsed_filters[1].input, "!=example");
  114. }
  115. static struct kunit_case dummy_attr_test_cases[] = {
  116. /* .run_case is not important, just needs to be non-NULL */
  117. { .name = "slow", .run_case = dummy_test, .module_name = "dummy",
  118. .attr.speed = KUNIT_SPEED_SLOW },
  119. { .name = "normal", .run_case = dummy_test, .module_name = "dummy" },
  120. {},
  121. };
  122. static void filter_attr_test(struct kunit *test)
  123. {
  124. struct kunit_suite *subsuite[3] = {NULL, NULL};
  125. struct kunit_suite_set suite_set = {
  126. .start = subsuite, .end = &subsuite[2],
  127. };
  128. struct kunit_suite_set got;
  129. char filter[] = "speed>slow";
  130. int err = 0;
  131. subsuite[0] = alloc_fake_suite(test, "normal_suite", dummy_attr_test_cases);
  132. subsuite[1] = alloc_fake_suite(test, "slow_suite", dummy_attr_test_cases);
  133. subsuite[1]->attr.speed = KUNIT_SPEED_SLOW; // Set suite attribute
  134. /*
  135. * Want: normal_suite(slow, normal), slow_suite(slow, normal),
  136. * NULL -> normal_suite(normal), NULL
  137. *
  138. * The normal test in slow_suite is filtered out because the speed
  139. * attribute is unset and thus, the filtering is based on the parent attribute
  140. * of slow.
  141. */
  142. got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
  143. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  144. KUNIT_ASSERT_EQ(test, err, 0);
  145. free_suite_set_at_end(test, &got);
  146. /* Validate we just have normal_suite */
  147. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
  148. KUNIT_EXPECT_STREQ(test, got.start[0]->name, "normal_suite");
  149. KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
  150. /* Now validate we just have normal test case */
  151. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
  152. KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[0].name, "normal");
  153. KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].name);
  154. }
  155. static void filter_attr_empty_test(struct kunit *test)
  156. {
  157. struct kunit_suite *subsuite[3] = {NULL, NULL};
  158. struct kunit_suite_set suite_set = {
  159. .start = subsuite, .end = &subsuite[2],
  160. };
  161. struct kunit_suite_set got;
  162. char filter[] = "module!=dummy";
  163. int err = 0;
  164. subsuite[0] = alloc_fake_suite(test, "suite1", dummy_attr_test_cases);
  165. subsuite[1] = alloc_fake_suite(test, "suite2", dummy_attr_test_cases);
  166. got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
  167. KUNIT_ASSERT_EQ(test, err, 0);
  168. free_suite_set_at_end(test, &got); /* just in case */
  169. KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
  170. "should be empty to indicate no match");
  171. }
  172. static void filter_attr_skip_test(struct kunit *test)
  173. {
  174. struct kunit_suite *subsuite[2] = {NULL};
  175. struct kunit_suite_set suite_set = {
  176. .start = subsuite, .end = &subsuite[1],
  177. };
  178. struct kunit_suite_set got;
  179. char filter[] = "speed>slow";
  180. int err = 0;
  181. subsuite[0] = alloc_fake_suite(test, "suite", dummy_attr_test_cases);
  182. /* Want: suite(slow, normal), NULL -> suite(slow with SKIP, normal), NULL */
  183. got = kunit_filter_suites(&suite_set, NULL, filter, "skip", &err);
  184. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  185. KUNIT_ASSERT_EQ(test, err, 0);
  186. free_suite_set_at_end(test, &got);
  187. /* Validate we have both the slow and normal test */
  188. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
  189. KUNIT_ASSERT_EQ(test, kunit_suite_num_test_cases(got.start[0]), 2);
  190. KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[0].name, "slow");
  191. KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[1].name, "normal");
  192. /* Now ensure slow is skipped and normal is not */
  193. KUNIT_EXPECT_EQ(test, got.start[0]->test_cases[0].status, KUNIT_SKIPPED);
  194. KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].status);
  195. }
  196. static struct kunit_case executor_test_cases[] = {
  197. KUNIT_CASE(parse_filter_test),
  198. KUNIT_CASE(filter_suites_test),
  199. KUNIT_CASE(filter_suites_test_glob_test),
  200. KUNIT_CASE(filter_suites_to_empty_test),
  201. KUNIT_CASE(parse_filter_attr_test),
  202. KUNIT_CASE(filter_attr_test),
  203. KUNIT_CASE(filter_attr_empty_test),
  204. KUNIT_CASE(filter_attr_skip_test),
  205. {}
  206. };
  207. static struct kunit_suite executor_test_suite = {
  208. .name = "kunit_executor_test",
  209. .test_cases = executor_test_cases,
  210. };
  211. kunit_test_suites(&executor_test_suite);
  212. /* Test helpers */
  213. static void free_suite_set(void *suite_set)
  214. {
  215. kunit_free_suite_set(*(struct kunit_suite_set *)suite_set);
  216. kfree(suite_set);
  217. }
  218. /* Use the resource API to register a call to free_suite_set.
  219. * Since we never actually use the resource, it's safe to use on const data.
  220. */
  221. static void free_suite_set_at_end(struct kunit *test, const void *to_free)
  222. {
  223. struct kunit_suite_set *free;
  224. if (!((struct kunit_suite_set *)to_free)->start)
  225. return;
  226. free = kzalloc_obj(struct kunit_suite_set);
  227. *free = *(struct kunit_suite_set *)to_free;
  228. kunit_add_action(test, free_suite_set, (void *)free);
  229. }
  230. static struct kunit_suite *alloc_fake_suite(struct kunit *test,
  231. const char *suite_name,
  232. struct kunit_case *test_cases)
  233. {
  234. struct kunit_suite *suite;
  235. /* We normally never expect to allocate suites, hence the non-const cast. */
  236. suite = kunit_kzalloc(test, sizeof(*suite), GFP_KERNEL);
  237. strscpy((char *)suite->name, suite_name, sizeof(suite->name));
  238. suite->test_cases = test_cases;
  239. return suite;
  240. }