builtin-test.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  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. .is_supported = test__bp_signal_is_supported,
  98. },
  99. {
  100. .desc = "Breakpoint overflow sampling",
  101. .func = test__bp_signal_overflow,
  102. .is_supported = test__bp_signal_is_supported,
  103. },
  104. {
  105. .desc = "Number of exit events of a simple workload",
  106. .func = test__task_exit,
  107. },
  108. {
  109. .desc = "Software clock events period values",
  110. .func = test__sw_clock_freq,
  111. },
  112. {
  113. .desc = "Object code reading",
  114. .func = test__code_reading,
  115. },
  116. {
  117. .desc = "Sample parsing",
  118. .func = test__sample_parsing,
  119. },
  120. {
  121. .desc = "Use a dummy software event to keep tracking",
  122. .func = test__keep_tracking,
  123. },
  124. {
  125. .desc = "Parse with no sample_id_all bit set",
  126. .func = test__parse_no_sample_id_all,
  127. },
  128. {
  129. .desc = "Filter hist entries",
  130. .func = test__hists_filter,
  131. },
  132. {
  133. .desc = "Lookup mmap thread",
  134. .func = test__mmap_thread_lookup,
  135. },
  136. {
  137. .desc = "Share thread mg",
  138. .func = test__thread_mg_share,
  139. },
  140. {
  141. .desc = "Sort output of hist entries",
  142. .func = test__hists_output,
  143. },
  144. {
  145. .desc = "Cumulate child hist entries",
  146. .func = test__hists_cumulate,
  147. },
  148. {
  149. .desc = "Track with sched_switch",
  150. .func = test__switch_tracking,
  151. },
  152. {
  153. .desc = "Filter fds with revents mask in a fdarray",
  154. .func = test__fdarray__filter,
  155. },
  156. {
  157. .desc = "Add fd to a fdarray, making it autogrow",
  158. .func = test__fdarray__add,
  159. },
  160. {
  161. .desc = "kmod_path__parse",
  162. .func = test__kmod_path__parse,
  163. },
  164. {
  165. .desc = "Thread map",
  166. .func = test__thread_map,
  167. },
  168. {
  169. .desc = "LLVM search and compile",
  170. .func = test__llvm,
  171. .subtest = {
  172. .skip_if_fail = true,
  173. .get_nr = test__llvm_subtest_get_nr,
  174. .get_desc = test__llvm_subtest_get_desc,
  175. },
  176. },
  177. {
  178. .desc = "Session topology",
  179. .func = test_session_topology,
  180. },
  181. {
  182. .desc = "BPF filter",
  183. .func = test__bpf,
  184. .subtest = {
  185. .skip_if_fail = true,
  186. .get_nr = test__bpf_subtest_get_nr,
  187. .get_desc = test__bpf_subtest_get_desc,
  188. },
  189. },
  190. {
  191. .desc = "Synthesize thread map",
  192. .func = test__thread_map_synthesize,
  193. },
  194. {
  195. .desc = "Remove thread map",
  196. .func = test__thread_map_remove,
  197. },
  198. {
  199. .desc = "Synthesize cpu map",
  200. .func = test__cpu_map_synthesize,
  201. },
  202. {
  203. .desc = "Synthesize stat config",
  204. .func = test__synthesize_stat_config,
  205. },
  206. {
  207. .desc = "Synthesize stat",
  208. .func = test__synthesize_stat,
  209. },
  210. {
  211. .desc = "Synthesize stat round",
  212. .func = test__synthesize_stat_round,
  213. },
  214. {
  215. .desc = "Synthesize attr update",
  216. .func = test__event_update,
  217. },
  218. {
  219. .desc = "Event times",
  220. .func = test__event_times,
  221. },
  222. {
  223. .desc = "Read backward ring buffer",
  224. .func = test__backward_ring_buffer,
  225. },
  226. {
  227. .desc = "Print cpu map",
  228. .func = test__cpu_map_print,
  229. },
  230. {
  231. .desc = "Probe SDT events",
  232. .func = test__sdt_event,
  233. },
  234. {
  235. .desc = "is_printable_array",
  236. .func = test__is_printable_array,
  237. },
  238. {
  239. .desc = "Print bitmap",
  240. .func = test__bitmap_print,
  241. },
  242. {
  243. .desc = "perf hooks",
  244. .func = test__perf_hooks,
  245. },
  246. {
  247. .desc = "builtin clang support",
  248. .func = test__clang,
  249. .subtest = {
  250. .skip_if_fail = true,
  251. .get_nr = test__clang_subtest_get_nr,
  252. .get_desc = test__clang_subtest_get_desc,
  253. }
  254. },
  255. {
  256. .desc = "unit_number__scnprintf",
  257. .func = test__unit_number__scnprint,
  258. },
  259. {
  260. .func = NULL,
  261. },
  262. };
  263. static struct test *tests[] = {
  264. generic_tests,
  265. arch_tests,
  266. };
  267. static bool perf_test__matches(struct test *test, int curr, int argc, const char *argv[])
  268. {
  269. int i;
  270. if (argc == 0)
  271. return true;
  272. for (i = 0; i < argc; ++i) {
  273. char *end;
  274. long nr = strtoul(argv[i], &end, 10);
  275. if (*end == '\0') {
  276. if (nr == curr + 1)
  277. return true;
  278. continue;
  279. }
  280. if (strcasestr(test->desc, argv[i]))
  281. return true;
  282. }
  283. return false;
  284. }
  285. static int run_test(struct test *test, int subtest)
  286. {
  287. int status, err = -1, child = dont_fork ? 0 : fork();
  288. char sbuf[STRERR_BUFSIZE];
  289. if (child < 0) {
  290. pr_err("failed to fork test: %s\n",
  291. str_error_r(errno, sbuf, sizeof(sbuf)));
  292. return -1;
  293. }
  294. if (!child) {
  295. if (!dont_fork) {
  296. pr_debug("test child forked, pid %d\n", getpid());
  297. if (verbose <= 0) {
  298. int nullfd = open("/dev/null", O_WRONLY);
  299. if (nullfd >= 0) {
  300. close(STDERR_FILENO);
  301. close(STDOUT_FILENO);
  302. dup2(nullfd, STDOUT_FILENO);
  303. dup2(STDOUT_FILENO, STDERR_FILENO);
  304. close(nullfd);
  305. }
  306. } else {
  307. signal(SIGSEGV, sighandler_dump_stack);
  308. signal(SIGFPE, sighandler_dump_stack);
  309. }
  310. }
  311. err = test->func(subtest);
  312. if (!dont_fork)
  313. exit(err);
  314. }
  315. if (!dont_fork) {
  316. wait(&status);
  317. if (WIFEXITED(status)) {
  318. err = (signed char)WEXITSTATUS(status);
  319. pr_debug("test child finished with %d\n", err);
  320. } else if (WIFSIGNALED(status)) {
  321. err = -1;
  322. pr_debug("test child interrupted\n");
  323. }
  324. }
  325. return err;
  326. }
  327. #define for_each_test(j, t) \
  328. for (j = 0; j < ARRAY_SIZE(tests); j++) \
  329. for (t = &tests[j][0]; t->func; t++)
  330. static int test_and_print(struct test *t, bool force_skip, int subtest)
  331. {
  332. int err;
  333. if (!force_skip) {
  334. pr_debug("\n--- start ---\n");
  335. err = run_test(t, subtest);
  336. pr_debug("---- end ----\n");
  337. } else {
  338. pr_debug("\n--- force skipped ---\n");
  339. err = TEST_SKIP;
  340. }
  341. if (!t->subtest.get_nr)
  342. pr_debug("%s:", t->desc);
  343. else
  344. pr_debug("%s subtest %d:", t->desc, subtest);
  345. switch (err) {
  346. case TEST_OK:
  347. pr_info(" Ok\n");
  348. break;
  349. case TEST_SKIP:
  350. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
  351. break;
  352. case TEST_FAIL:
  353. default:
  354. color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
  355. break;
  356. }
  357. return err;
  358. }
  359. static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
  360. {
  361. struct test *t;
  362. unsigned int j;
  363. int i = 0;
  364. int width = 0;
  365. for_each_test(j, t) {
  366. int len = strlen(t->desc);
  367. if (width < len)
  368. width = len;
  369. }
  370. for_each_test(j, t) {
  371. int curr = i++, err;
  372. if (!perf_test__matches(t, curr, argc, argv))
  373. continue;
  374. if (t->is_supported && !t->is_supported()) {
  375. pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
  376. continue;
  377. }
  378. pr_info("%2d: %-*s:", i, width, t->desc);
  379. if (intlist__find(skiplist, i)) {
  380. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
  381. continue;
  382. }
  383. if (!t->subtest.get_nr) {
  384. test_and_print(t, false, -1);
  385. } else {
  386. int subn = t->subtest.get_nr();
  387. /*
  388. * minus 2 to align with normal testcases.
  389. * For subtest we print additional '.x' in number.
  390. * for example:
  391. *
  392. * 35: Test LLVM searching and compiling :
  393. * 35.1: Basic BPF llvm compiling test : Ok
  394. */
  395. int subw = width > 2 ? width - 2 : width;
  396. bool skip = false;
  397. int subi;
  398. if (subn <= 0) {
  399. color_fprintf(stderr, PERF_COLOR_YELLOW,
  400. " Skip (not compiled in)\n");
  401. continue;
  402. }
  403. pr_info("\n");
  404. for (subi = 0; subi < subn; subi++) {
  405. int len = strlen(t->subtest.get_desc(subi));
  406. if (subw < len)
  407. subw = len;
  408. }
  409. for (subi = 0; subi < subn; subi++) {
  410. pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
  411. t->subtest.get_desc(subi));
  412. err = test_and_print(t, skip, subi);
  413. if (err != TEST_OK && t->subtest.skip_if_fail)
  414. skip = true;
  415. }
  416. }
  417. }
  418. return 0;
  419. }
  420. static int perf_test__list(int argc, const char **argv)
  421. {
  422. unsigned int j;
  423. struct test *t;
  424. int i = 0;
  425. for_each_test(j, t) {
  426. if (argc > 1 && !strstr(t->desc, argv[1]))
  427. continue;
  428. pr_info("%2d: %s\n", ++i, t->desc);
  429. }
  430. return 0;
  431. }
  432. int cmd_test(int argc, const char **argv)
  433. {
  434. const char *test_usage[] = {
  435. "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
  436. NULL,
  437. };
  438. const char *skip = NULL;
  439. const struct option test_options[] = {
  440. OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
  441. OPT_INCR('v', "verbose", &verbose,
  442. "be more verbose (show symbol address, etc)"),
  443. OPT_BOOLEAN('F', "dont-fork", &dont_fork,
  444. "Do not fork for testcase"),
  445. OPT_END()
  446. };
  447. const char * const test_subcommands[] = { "list", NULL };
  448. struct intlist *skiplist = NULL;
  449. int ret = hists__init();
  450. if (ret < 0)
  451. return ret;
  452. argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
  453. if (argc >= 1 && !strcmp(argv[0], "list"))
  454. return perf_test__list(argc, argv);
  455. symbol_conf.priv_size = sizeof(int);
  456. symbol_conf.sort_by_name = true;
  457. symbol_conf.try_vmlinux_path = true;
  458. if (symbol__init(NULL) < 0)
  459. return -1;
  460. if (skip != NULL)
  461. skiplist = intlist__new(skip);
  462. return __cmd_test(argc, argv, skiplist);
  463. }