builtin-test.c 9.9 KB

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