executor.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/reboot.h>
  3. #include <kunit/test.h>
  4. #include <kunit/attributes.h>
  5. #include <linux/glob.h>
  6. #include <linux/moduleparam.h>
  7. /*
  8. * These symbols point to the .kunit_test_suites section and are defined in
  9. * include/asm-generic/vmlinux.lds.h, and consequently must be extern.
  10. */
  11. extern struct kunit_suite * const __kunit_suites_start[];
  12. extern struct kunit_suite * const __kunit_suites_end[];
  13. extern struct kunit_suite * const __kunit_init_suites_start[];
  14. extern struct kunit_suite * const __kunit_init_suites_end[];
  15. static char *action_param;
  16. module_param_named(action, action_param, charp, 0400);
  17. MODULE_PARM_DESC(action,
  18. "Changes KUnit executor behavior, valid values are:\n"
  19. "<none>: run the tests like normal\n"
  20. "'list' to list test names instead of running them.\n"
  21. "'list_attr' to list test names and attributes instead of running them.\n");
  22. const char *kunit_action(void)
  23. {
  24. return action_param;
  25. }
  26. /*
  27. * Run KUnit tests after initialization
  28. */
  29. #ifdef CONFIG_KUNIT_AUTORUN_ENABLED
  30. static bool autorun_param = true;
  31. #else
  32. static bool autorun_param;
  33. #endif
  34. module_param_named(autorun, autorun_param, bool, 0);
  35. MODULE_PARM_DESC(autorun, "Run KUnit tests after initialization");
  36. bool kunit_autorun(void)
  37. {
  38. return autorun_param;
  39. }
  40. #define PARAM_FROM_CONFIG(config) (config[0] ? config : NULL)
  41. static char *filter_glob_param = PARAM_FROM_CONFIG(CONFIG_KUNIT_DEFAULT_FILTER_GLOB);
  42. static char *filter_param = PARAM_FROM_CONFIG(CONFIG_KUNIT_DEFAULT_FILTER);
  43. static char *filter_action_param = PARAM_FROM_CONFIG(CONFIG_KUNIT_DEFAULT_FILTER_ACTION);
  44. module_param_named(filter_glob, filter_glob_param, charp, 0600);
  45. MODULE_PARM_DESC(filter_glob,
  46. "Filter which KUnit test suites/tests run at boot-time, e.g. list* or list*.*del_test");
  47. module_param_named(filter, filter_param, charp, 0600);
  48. MODULE_PARM_DESC(filter,
  49. "Filter which KUnit test suites/tests run at boot-time using attributes, e.g. speed>slow");
  50. module_param_named(filter_action, filter_action_param, charp, 0600);
  51. MODULE_PARM_DESC(filter_action,
  52. "Changes behavior of filtered tests using attributes, valid values are:\n"
  53. "<none>: do not run filtered tests as normal\n"
  54. "'skip': skip all filtered tests instead so tests will appear in output\n");
  55. const char *kunit_filter_glob(void)
  56. {
  57. return filter_glob_param;
  58. }
  59. char *kunit_filter(void)
  60. {
  61. return filter_param;
  62. }
  63. char *kunit_filter_action(void)
  64. {
  65. return filter_action_param;
  66. }
  67. /* glob_match() needs NULL terminated strings, so we need a copy of filter_glob_param. */
  68. struct kunit_glob_filter {
  69. char *suite_glob;
  70. char *test_glob;
  71. };
  72. /* Split "suite_glob.test_glob" into two. Assumes filter_glob is not empty. */
  73. static int kunit_parse_glob_filter(struct kunit_glob_filter *parsed,
  74. const char *filter_glob)
  75. {
  76. const char *period = strchr(filter_glob, '.');
  77. if (!period) {
  78. parsed->suite_glob = kstrdup(filter_glob, GFP_KERNEL);
  79. if (!parsed->suite_glob)
  80. return -ENOMEM;
  81. parsed->test_glob = NULL;
  82. return 0;
  83. }
  84. parsed->suite_glob = kstrndup(filter_glob, period - filter_glob, GFP_KERNEL);
  85. if (!parsed->suite_glob)
  86. return -ENOMEM;
  87. parsed->test_glob = kstrdup(period + 1, GFP_KERNEL);
  88. if (!parsed->test_glob) {
  89. kfree(parsed->suite_glob);
  90. return -ENOMEM;
  91. }
  92. return 0;
  93. }
  94. /* Create a copy of suite with only tests that match test_glob. */
  95. static struct kunit_suite *
  96. kunit_filter_glob_tests(const struct kunit_suite *const suite, const char *test_glob)
  97. {
  98. int n = 0;
  99. struct kunit_case *filtered, *test_case;
  100. struct kunit_suite *copy;
  101. kunit_suite_for_each_test_case(suite, test_case) {
  102. if (!test_glob || glob_match(test_glob, test_case->name))
  103. ++n;
  104. }
  105. if (n == 0)
  106. return NULL;
  107. copy = kmemdup(suite, sizeof(*copy), GFP_KERNEL);
  108. if (!copy)
  109. return ERR_PTR(-ENOMEM);
  110. filtered = kzalloc_objs(*filtered, n + 1);
  111. if (!filtered) {
  112. kfree(copy);
  113. return ERR_PTR(-ENOMEM);
  114. }
  115. n = 0;
  116. kunit_suite_for_each_test_case(suite, test_case) {
  117. if (!test_glob || glob_match(test_glob, test_case->name))
  118. filtered[n++] = *test_case;
  119. }
  120. copy->test_cases = filtered;
  121. return copy;
  122. }
  123. void kunit_free_suite_set(struct kunit_suite_set suite_set)
  124. {
  125. struct kunit_suite * const *suites;
  126. for (suites = suite_set.start; suites < suite_set.end; suites++) {
  127. kfree((*suites)->test_cases);
  128. kfree(*suites);
  129. }
  130. kfree(suite_set.start);
  131. }
  132. /*
  133. * Filter and reallocate test suites. Must return the filtered test suites set
  134. * allocated at a valid virtual address or NULL in case of error.
  135. */
  136. struct kunit_suite_set
  137. kunit_filter_suites(const struct kunit_suite_set *suite_set,
  138. const char *filter_glob,
  139. char *filters,
  140. char *filter_action,
  141. int *err)
  142. {
  143. int i, j, k;
  144. int filter_count = 0;
  145. struct kunit_suite **copy, **copy_start, *filtered_suite, *new_filtered_suite;
  146. struct kunit_suite_set filtered = {NULL, NULL};
  147. struct kunit_glob_filter parsed_glob;
  148. struct kunit_attr_filter *parsed_filters = NULL;
  149. struct kunit_suite * const *suites;
  150. const size_t max = suite_set->end - suite_set->start;
  151. copy = kzalloc_objs(*copy, max);
  152. if (!copy) { /* won't be able to run anything, return an empty set */
  153. return filtered;
  154. }
  155. copy_start = copy;
  156. if (filter_glob) {
  157. *err = kunit_parse_glob_filter(&parsed_glob, filter_glob);
  158. if (*err)
  159. goto free_copy;
  160. }
  161. /* Parse attribute filters */
  162. if (filters) {
  163. filter_count = kunit_get_filter_count(filters);
  164. parsed_filters = kzalloc_objs(*parsed_filters, filter_count);
  165. if (!parsed_filters) {
  166. *err = -ENOMEM;
  167. goto free_parsed_glob;
  168. }
  169. for (j = 0; j < filter_count; j++)
  170. parsed_filters[j] = kunit_next_attr_filter(&filters, err);
  171. if (*err)
  172. goto free_parsed_filters;
  173. }
  174. for (i = 0; &suite_set->start[i] != suite_set->end; i++) {
  175. filtered_suite = suite_set->start[i];
  176. if (filter_glob) {
  177. if (!glob_match(parsed_glob.suite_glob, filtered_suite->name))
  178. continue;
  179. filtered_suite = kunit_filter_glob_tests(filtered_suite,
  180. parsed_glob.test_glob);
  181. if (IS_ERR(filtered_suite)) {
  182. *err = PTR_ERR(filtered_suite);
  183. goto free_filtered_suite;
  184. }
  185. }
  186. if (filter_count > 0 && parsed_filters != NULL) {
  187. for (k = 0; k < filter_count; k++) {
  188. new_filtered_suite = kunit_filter_attr_tests(filtered_suite,
  189. parsed_filters[k], filter_action, err);
  190. /* Free previous copy of suite */
  191. if (k > 0 || filter_glob) {
  192. kfree(filtered_suite->test_cases);
  193. kfree(filtered_suite);
  194. }
  195. filtered_suite = new_filtered_suite;
  196. if (*err)
  197. goto free_filtered_suite;
  198. if (IS_ERR(filtered_suite)) {
  199. *err = PTR_ERR(filtered_suite);
  200. goto free_filtered_suite;
  201. }
  202. if (!filtered_suite)
  203. break;
  204. }
  205. }
  206. if (!filtered_suite)
  207. continue;
  208. *copy++ = filtered_suite;
  209. }
  210. filtered.start = copy_start;
  211. filtered.end = copy;
  212. free_filtered_suite:
  213. if (*err) {
  214. for (suites = copy_start; suites < copy; suites++) {
  215. kfree((*suites)->test_cases);
  216. kfree(*suites);
  217. }
  218. }
  219. free_parsed_filters:
  220. if (filter_count)
  221. kfree(parsed_filters);
  222. free_parsed_glob:
  223. if (filter_glob) {
  224. kfree(parsed_glob.suite_glob);
  225. kfree(parsed_glob.test_glob);
  226. }
  227. free_copy:
  228. if (*err)
  229. kfree(copy_start);
  230. return filtered;
  231. }
  232. void kunit_exec_run_tests(struct kunit_suite_set *suite_set, bool builtin)
  233. {
  234. size_t num_suites = suite_set->end - suite_set->start;
  235. bool autorun = kunit_autorun();
  236. if (autorun && (builtin || num_suites)) {
  237. pr_info("KTAP version 1\n");
  238. pr_info("1..%zu\n", num_suites);
  239. }
  240. __kunit_test_suites_init(suite_set->start, num_suites, autorun);
  241. }
  242. void kunit_exec_list_tests(struct kunit_suite_set *suite_set, bool include_attr)
  243. {
  244. struct kunit_suite * const *suites;
  245. struct kunit_case *test_case;
  246. /* Hack: print a ktap header so kunit.py can find the start of KUnit output. */
  247. pr_info("KTAP version 1\n");
  248. for (suites = suite_set->start; suites < suite_set->end; suites++) {
  249. /* Print suite name and suite attributes */
  250. pr_info("%s\n", (*suites)->name);
  251. if (include_attr)
  252. kunit_print_attr((void *)(*suites), false, 0);
  253. /* Print test case name and attributes in suite */
  254. kunit_suite_for_each_test_case((*suites), test_case) {
  255. pr_info("%s.%s\n", (*suites)->name, test_case->name);
  256. if (include_attr)
  257. kunit_print_attr((void *)test_case, true, 0);
  258. }
  259. }
  260. }
  261. struct kunit_suite_set kunit_merge_suite_sets(struct kunit_suite_set init_suite_set,
  262. struct kunit_suite_set suite_set)
  263. {
  264. struct kunit_suite_set total_suite_set = {NULL, NULL};
  265. struct kunit_suite **total_suite_start = NULL;
  266. size_t init_num_suites, num_suites, suite_size;
  267. int i = 0;
  268. init_num_suites = init_suite_set.end - init_suite_set.start;
  269. num_suites = suite_set.end - suite_set.start;
  270. suite_size = sizeof(suite_set.start);
  271. /* Allocate memory for array of all kunit suites */
  272. total_suite_start = kmalloc_array(init_num_suites + num_suites, suite_size, GFP_KERNEL);
  273. if (!total_suite_start)
  274. return total_suite_set;
  275. /* Append and mark init suites and then append all other kunit suites */
  276. memcpy(total_suite_start, init_suite_set.start, init_num_suites * suite_size);
  277. for (i = 0; i < init_num_suites; i++)
  278. total_suite_start[i]->is_init = true;
  279. memcpy(total_suite_start + init_num_suites, suite_set.start, num_suites * suite_size);
  280. /* Set kunit suite set start and end */
  281. total_suite_set.start = total_suite_start;
  282. total_suite_set.end = total_suite_start + (init_num_suites + num_suites);
  283. return total_suite_set;
  284. }
  285. #if IS_BUILTIN(CONFIG_KUNIT)
  286. static char *kunit_shutdown;
  287. core_param(kunit_shutdown, kunit_shutdown, charp, 0644);
  288. static void kunit_handle_shutdown(void)
  289. {
  290. if (!kunit_shutdown)
  291. return;
  292. if (!strcmp(kunit_shutdown, "poweroff"))
  293. kernel_power_off();
  294. else if (!strcmp(kunit_shutdown, "halt"))
  295. kernel_halt();
  296. else if (!strcmp(kunit_shutdown, "reboot"))
  297. kernel_restart(NULL);
  298. }
  299. int kunit_run_all_tests(void)
  300. {
  301. struct kunit_suite_set suite_set = {NULL, NULL};
  302. struct kunit_suite_set filtered_suite_set = {NULL, NULL};
  303. struct kunit_suite_set init_suite_set = {
  304. __kunit_init_suites_start, __kunit_init_suites_end,
  305. };
  306. struct kunit_suite_set normal_suite_set = {
  307. __kunit_suites_start, __kunit_suites_end,
  308. };
  309. size_t init_num_suites = init_suite_set.end - init_suite_set.start;
  310. int err = 0;
  311. if (init_num_suites > 0) {
  312. suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set);
  313. if (!suite_set.start)
  314. goto out;
  315. } else
  316. suite_set = normal_suite_set;
  317. if (!kunit_enabled()) {
  318. pr_info("kunit: disabled\n");
  319. goto free_out;
  320. }
  321. if (filter_glob_param || filter_param) {
  322. filtered_suite_set = kunit_filter_suites(&suite_set, filter_glob_param,
  323. filter_param, filter_action_param, &err);
  324. /* Free original suite set before using filtered suite set */
  325. if (init_num_suites > 0)
  326. kfree(suite_set.start);
  327. suite_set = filtered_suite_set;
  328. if (err) {
  329. pr_err("kunit executor: error filtering suites: %d\n", err);
  330. goto free_out;
  331. }
  332. }
  333. if (!action_param)
  334. kunit_exec_run_tests(&suite_set, true);
  335. else if (strcmp(action_param, "list") == 0)
  336. kunit_exec_list_tests(&suite_set, false);
  337. else if (strcmp(action_param, "list_attr") == 0)
  338. kunit_exec_list_tests(&suite_set, true);
  339. else
  340. pr_err("kunit executor: unknown action '%s'\n", action_param);
  341. free_out:
  342. if (filter_glob_param || filter_param)
  343. kunit_free_suite_set(suite_set);
  344. else if (init_num_suites > 0)
  345. /* Don't use kunit_free_suite_set because suites aren't individually allocated */
  346. kfree(suite_set.start);
  347. out:
  348. kunit_handle_shutdown();
  349. return err;
  350. }
  351. #if IS_BUILTIN(CONFIG_KUNIT_TEST)
  352. #include "executor_test.c"
  353. #endif
  354. #endif /* IS_BUILTIN(CONFIG_KUNIT) */