builtin-test.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * builtin-test.c
  3. *
  4. * Builtin regression testing command: ever growing number of sanity tests
  5. */
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include "builtin.h"
  9. #include "hist.h"
  10. #include "intlist.h"
  11. #include "tests.h"
  12. #include "debug.h"
  13. #include "color.h"
  14. #include <subcmd/parse-options.h>
  15. #include "symbol.h"
  16. struct test __weak arch_tests[] = {
  17. {
  18. .func = NULL,
  19. },
  20. };
  21. static struct test generic_tests[] = {
  22. {
  23. .desc = "vmlinux symtab matches kallsyms",
  24. .func = test__vmlinux_matches_kallsyms,
  25. },
  26. {
  27. .desc = "detect openat syscall event",
  28. .func = test__openat_syscall_event,
  29. },
  30. {
  31. .desc = "detect openat syscall event on all cpus",
  32. .func = test__openat_syscall_event_on_all_cpus,
  33. },
  34. {
  35. .desc = "read samples using the mmap interface",
  36. .func = test__basic_mmap,
  37. },
  38. {
  39. .desc = "parse events tests",
  40. .func = test__parse_events,
  41. },
  42. {
  43. .desc = "Validate PERF_RECORD_* events & perf_sample fields",
  44. .func = test__PERF_RECORD,
  45. },
  46. {
  47. .desc = "Test perf pmu format parsing",
  48. .func = test__pmu,
  49. },
  50. {
  51. .desc = "Test dso data read",
  52. .func = test__dso_data,
  53. },
  54. {
  55. .desc = "Test dso data cache",
  56. .func = test__dso_data_cache,
  57. },
  58. {
  59. .desc = "Test dso data reopen",
  60. .func = test__dso_data_reopen,
  61. },
  62. {
  63. .desc = "roundtrip evsel->name check",
  64. .func = test__perf_evsel__roundtrip_name_test,
  65. },
  66. {
  67. .desc = "Check parsing of sched tracepoints fields",
  68. .func = test__perf_evsel__tp_sched_test,
  69. },
  70. {
  71. .desc = "Generate and check syscalls:sys_enter_openat event fields",
  72. .func = test__syscall_openat_tp_fields,
  73. },
  74. {
  75. .desc = "struct perf_event_attr setup",
  76. .func = test__attr,
  77. },
  78. {
  79. .desc = "Test matching and linking multiple hists",
  80. .func = test__hists_link,
  81. },
  82. {
  83. .desc = "Try 'import perf' in python, checking link problems",
  84. .func = test__python_use,
  85. },
  86. {
  87. .desc = "Test breakpoint overflow signal handler",
  88. .func = test__bp_signal,
  89. },
  90. {
  91. .desc = "Test breakpoint overflow sampling",
  92. .func = test__bp_signal_overflow,
  93. },
  94. {
  95. .desc = "Test number of exit event of a simple workload",
  96. .func = test__task_exit,
  97. },
  98. {
  99. .desc = "Test software clock events have valid period values",
  100. .func = test__sw_clock_freq,
  101. },
  102. {
  103. .desc = "Test object code reading",
  104. .func = test__code_reading,
  105. },
  106. {
  107. .desc = "Test sample parsing",
  108. .func = test__sample_parsing,
  109. },
  110. {
  111. .desc = "Test using a dummy software event to keep tracking",
  112. .func = test__keep_tracking,
  113. },
  114. {
  115. .desc = "Test parsing with no sample_id_all bit set",
  116. .func = test__parse_no_sample_id_all,
  117. },
  118. {
  119. .desc = "Test filtering hist entries",
  120. .func = test__hists_filter,
  121. },
  122. {
  123. .desc = "Test mmap thread lookup",
  124. .func = test__mmap_thread_lookup,
  125. },
  126. {
  127. .desc = "Test thread mg sharing",
  128. .func = test__thread_mg_share,
  129. },
  130. {
  131. .desc = "Test output sorting of hist entries",
  132. .func = test__hists_output,
  133. },
  134. {
  135. .desc = "Test cumulation of child hist entries",
  136. .func = test__hists_cumulate,
  137. },
  138. {
  139. .desc = "Test tracking with sched_switch",
  140. .func = test__switch_tracking,
  141. },
  142. {
  143. .desc = "Filter fds with revents mask in a fdarray",
  144. .func = test__fdarray__filter,
  145. },
  146. {
  147. .desc = "Add fd to a fdarray, making it autogrow",
  148. .func = test__fdarray__add,
  149. },
  150. {
  151. .desc = "Test kmod_path__parse function",
  152. .func = test__kmod_path__parse,
  153. },
  154. {
  155. .desc = "Test thread map",
  156. .func = test__thread_map,
  157. },
  158. {
  159. .desc = "Test LLVM searching and compiling",
  160. .func = test__llvm,
  161. .subtest = {
  162. .skip_if_fail = true,
  163. .get_nr = test__llvm_subtest_get_nr,
  164. .get_desc = test__llvm_subtest_get_desc,
  165. },
  166. },
  167. {
  168. .desc = "Test topology in session",
  169. .func = test_session_topology,
  170. },
  171. {
  172. .desc = "Test BPF filter",
  173. .func = test__bpf,
  174. .subtest = {
  175. .skip_if_fail = true,
  176. .get_nr = test__bpf_subtest_get_nr,
  177. .get_desc = test__bpf_subtest_get_desc,
  178. },
  179. },
  180. {
  181. .desc = "Test thread map synthesize",
  182. .func = test__thread_map_synthesize,
  183. },
  184. {
  185. .desc = "Test cpu map synthesize",
  186. .func = test__cpu_map_synthesize,
  187. },
  188. {
  189. .desc = "Test stat config synthesize",
  190. .func = test__synthesize_stat_config,
  191. },
  192. {
  193. .desc = "Test stat synthesize",
  194. .func = test__synthesize_stat,
  195. },
  196. {
  197. .desc = "Test stat round synthesize",
  198. .func = test__synthesize_stat_round,
  199. },
  200. {
  201. .desc = "Test attr update synthesize",
  202. .func = test__event_update,
  203. },
  204. {
  205. .func = NULL,
  206. },
  207. };
  208. static struct test *tests[] = {
  209. generic_tests,
  210. arch_tests,
  211. };
  212. static bool perf_test__matches(struct test *test, int curr, int argc, const char *argv[])
  213. {
  214. int i;
  215. if (argc == 0)
  216. return true;
  217. for (i = 0; i < argc; ++i) {
  218. char *end;
  219. long nr = strtoul(argv[i], &end, 10);
  220. if (*end == '\0') {
  221. if (nr == curr + 1)
  222. return true;
  223. continue;
  224. }
  225. if (strcasestr(test->desc, argv[i]))
  226. return true;
  227. }
  228. return false;
  229. }
  230. static int run_test(struct test *test, int subtest)
  231. {
  232. int status, err = -1, child = fork();
  233. char sbuf[STRERR_BUFSIZE];
  234. if (child < 0) {
  235. pr_err("failed to fork test: %s\n",
  236. strerror_r(errno, sbuf, sizeof(sbuf)));
  237. return -1;
  238. }
  239. if (!child) {
  240. pr_debug("test child forked, pid %d\n", getpid());
  241. if (!verbose) {
  242. int nullfd = open("/dev/null", O_WRONLY);
  243. if (nullfd >= 0) {
  244. close(STDERR_FILENO);
  245. close(STDOUT_FILENO);
  246. dup2(nullfd, STDOUT_FILENO);
  247. dup2(STDOUT_FILENO, STDERR_FILENO);
  248. close(nullfd);
  249. }
  250. } else {
  251. signal(SIGSEGV, sighandler_dump_stack);
  252. signal(SIGFPE, sighandler_dump_stack);
  253. }
  254. err = test->func(subtest);
  255. exit(err);
  256. }
  257. wait(&status);
  258. if (WIFEXITED(status)) {
  259. err = (signed char)WEXITSTATUS(status);
  260. pr_debug("test child finished with %d\n", err);
  261. } else if (WIFSIGNALED(status)) {
  262. err = -1;
  263. pr_debug("test child interrupted\n");
  264. }
  265. return err;
  266. }
  267. #define for_each_test(j, t) \
  268. for (j = 0; j < ARRAY_SIZE(tests); j++) \
  269. for (t = &tests[j][0]; t->func; t++)
  270. static int test_and_print(struct test *t, bool force_skip, int subtest)
  271. {
  272. int err;
  273. if (!force_skip) {
  274. pr_debug("\n--- start ---\n");
  275. err = run_test(t, subtest);
  276. pr_debug("---- end ----\n");
  277. } else {
  278. pr_debug("\n--- force skipped ---\n");
  279. err = TEST_SKIP;
  280. }
  281. if (!t->subtest.get_nr)
  282. pr_debug("%s:", t->desc);
  283. else
  284. pr_debug("%s subtest %d:", t->desc, subtest);
  285. switch (err) {
  286. case TEST_OK:
  287. pr_info(" Ok\n");
  288. break;
  289. case TEST_SKIP:
  290. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
  291. break;
  292. case TEST_FAIL:
  293. default:
  294. color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
  295. break;
  296. }
  297. return err;
  298. }
  299. static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
  300. {
  301. struct test *t;
  302. unsigned int j;
  303. int i = 0;
  304. int width = 0;
  305. for_each_test(j, t) {
  306. int len = strlen(t->desc);
  307. if (width < len)
  308. width = len;
  309. }
  310. for_each_test(j, t) {
  311. int curr = i++, err;
  312. if (!perf_test__matches(t, curr, argc, argv))
  313. continue;
  314. pr_info("%2d: %-*s:", i, width, t->desc);
  315. if (intlist__find(skiplist, i)) {
  316. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
  317. continue;
  318. }
  319. if (!t->subtest.get_nr) {
  320. test_and_print(t, false, -1);
  321. } else {
  322. int subn = t->subtest.get_nr();
  323. /*
  324. * minus 2 to align with normal testcases.
  325. * For subtest we print additional '.x' in number.
  326. * for example:
  327. *
  328. * 35: Test LLVM searching and compiling :
  329. * 35.1: Basic BPF llvm compiling test : Ok
  330. */
  331. int subw = width > 2 ? width - 2 : width;
  332. bool skip = false;
  333. int subi;
  334. if (subn <= 0) {
  335. color_fprintf(stderr, PERF_COLOR_YELLOW,
  336. " Skip (not compiled in)\n");
  337. continue;
  338. }
  339. pr_info("\n");
  340. for (subi = 0; subi < subn; subi++) {
  341. int len = strlen(t->subtest.get_desc(subi));
  342. if (subw < len)
  343. subw = len;
  344. }
  345. for (subi = 0; subi < subn; subi++) {
  346. pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
  347. t->subtest.get_desc(subi));
  348. err = test_and_print(t, skip, subi);
  349. if (err != TEST_OK && t->subtest.skip_if_fail)
  350. skip = true;
  351. }
  352. }
  353. }
  354. return 0;
  355. }
  356. static int perf_test__list(int argc, const char **argv)
  357. {
  358. unsigned int j;
  359. struct test *t;
  360. int i = 0;
  361. for_each_test(j, t) {
  362. if (argc > 1 && !strstr(t->desc, argv[1]))
  363. continue;
  364. pr_info("%2d: %s\n", ++i, t->desc);
  365. }
  366. return 0;
  367. }
  368. int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
  369. {
  370. const char *test_usage[] = {
  371. "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
  372. NULL,
  373. };
  374. const char *skip = NULL;
  375. const struct option test_options[] = {
  376. OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
  377. OPT_INCR('v', "verbose", &verbose,
  378. "be more verbose (show symbol address, etc)"),
  379. OPT_END()
  380. };
  381. const char * const test_subcommands[] = { "list", NULL };
  382. struct intlist *skiplist = NULL;
  383. int ret = hists__init();
  384. if (ret < 0)
  385. return ret;
  386. argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
  387. if (argc >= 1 && !strcmp(argv[0], "list"))
  388. return perf_test__list(argc, argv);
  389. symbol_conf.priv_size = sizeof(int);
  390. symbol_conf.sort_by_name = true;
  391. symbol_conf.try_vmlinux_path = true;
  392. if (symbol__init(NULL) < 0)
  393. return -1;
  394. if (skip != NULL)
  395. skiplist = intlist__new(skip);
  396. return __cmd_test(argc, argv, skiplist);
  397. }