builtin-test.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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 "intlist.h"
  10. #include "tests.h"
  11. #include "debug.h"
  12. #include "color.h"
  13. #include "parse-options.h"
  14. #include "symbol.h"
  15. static struct test {
  16. const char *desc;
  17. int (*func)(void);
  18. } tests[] = {
  19. {
  20. .desc = "vmlinux symtab matches kallsyms",
  21. .func = test__vmlinux_matches_kallsyms,
  22. },
  23. {
  24. .desc = "detect open syscall event",
  25. .func = test__open_syscall_event,
  26. },
  27. {
  28. .desc = "detect open syscall event on all cpus",
  29. .func = test__open_syscall_event_on_all_cpus,
  30. },
  31. {
  32. .desc = "read samples using the mmap interface",
  33. .func = test__basic_mmap,
  34. },
  35. {
  36. .desc = "parse events tests",
  37. .func = test__parse_events,
  38. },
  39. #if defined(__x86_64__) || defined(__i386__)
  40. {
  41. .desc = "x86 rdpmc test",
  42. .func = test__rdpmc,
  43. },
  44. #endif
  45. {
  46. .desc = "Validate PERF_RECORD_* events & perf_sample fields",
  47. .func = test__PERF_RECORD,
  48. },
  49. {
  50. .desc = "Test perf pmu format parsing",
  51. .func = test__pmu,
  52. },
  53. {
  54. .desc = "Test dso data read",
  55. .func = test__dso_data,
  56. },
  57. {
  58. .desc = "Test dso data cache",
  59. .func = test__dso_data_cache,
  60. },
  61. {
  62. .desc = "Test dso data reopen",
  63. .func = test__dso_data_reopen,
  64. },
  65. {
  66. .desc = "roundtrip evsel->name check",
  67. .func = test__perf_evsel__roundtrip_name_test,
  68. },
  69. {
  70. .desc = "Check parsing of sched tracepoints fields",
  71. .func = test__perf_evsel__tp_sched_test,
  72. },
  73. {
  74. .desc = "Generate and check syscalls:sys_enter_open event fields",
  75. .func = test__syscall_open_tp_fields,
  76. },
  77. {
  78. .desc = "struct perf_event_attr setup",
  79. .func = test__attr,
  80. },
  81. {
  82. .desc = "Test matching and linking multiple hists",
  83. .func = test__hists_link,
  84. },
  85. {
  86. .desc = "Try 'use perf' in python, checking link problems",
  87. .func = test__python_use,
  88. },
  89. {
  90. .desc = "Test breakpoint overflow signal handler",
  91. .func = test__bp_signal,
  92. },
  93. {
  94. .desc = "Test breakpoint overflow sampling",
  95. .func = test__bp_signal_overflow,
  96. },
  97. {
  98. .desc = "Test number of exit event of a simple workload",
  99. .func = test__task_exit,
  100. },
  101. {
  102. .desc = "Test software clock events have valid period values",
  103. .func = test__sw_clock_freq,
  104. },
  105. #if defined(__x86_64__) || defined(__i386__)
  106. {
  107. .desc = "Test converting perf time to TSC",
  108. .func = test__perf_time_to_tsc,
  109. },
  110. #endif
  111. {
  112. .desc = "Test object code reading",
  113. .func = test__code_reading,
  114. },
  115. {
  116. .desc = "Test sample parsing",
  117. .func = test__sample_parsing,
  118. },
  119. {
  120. .desc = "Test using a dummy software event to keep tracking",
  121. .func = test__keep_tracking,
  122. },
  123. {
  124. .desc = "Test parsing with no sample_id_all bit set",
  125. .func = test__parse_no_sample_id_all,
  126. },
  127. #if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
  128. #ifdef HAVE_DWARF_UNWIND_SUPPORT
  129. {
  130. .desc = "Test dwarf unwind",
  131. .func = test__dwarf_unwind,
  132. },
  133. #endif
  134. #endif
  135. {
  136. .desc = "Test filtering hist entries",
  137. .func = test__hists_filter,
  138. },
  139. {
  140. .desc = "Test mmap thread lookup",
  141. .func = test__mmap_thread_lookup,
  142. },
  143. {
  144. .desc = "Test thread mg sharing",
  145. .func = test__thread_mg_share,
  146. },
  147. {
  148. .desc = "Test output sorting of hist entries",
  149. .func = test__hists_output,
  150. },
  151. {
  152. .desc = "Test cumulation of child hist entries",
  153. .func = test__hists_cumulate,
  154. },
  155. {
  156. .func = NULL,
  157. },
  158. };
  159. static bool perf_test__matches(int curr, int argc, const char *argv[])
  160. {
  161. int i;
  162. if (argc == 0)
  163. return true;
  164. for (i = 0; i < argc; ++i) {
  165. char *end;
  166. long nr = strtoul(argv[i], &end, 10);
  167. if (*end == '\0') {
  168. if (nr == curr + 1)
  169. return true;
  170. continue;
  171. }
  172. if (strstr(tests[curr].desc, argv[i]))
  173. return true;
  174. }
  175. return false;
  176. }
  177. static int run_test(struct test *test)
  178. {
  179. int status, err = -1, child = fork();
  180. if (child < 0) {
  181. pr_err("failed to fork test: %s\n", strerror(errno));
  182. return -1;
  183. }
  184. if (!child) {
  185. pr_debug("test child forked, pid %d\n", getpid());
  186. err = test->func();
  187. exit(err);
  188. }
  189. wait(&status);
  190. if (WIFEXITED(status)) {
  191. err = WEXITSTATUS(status);
  192. pr_debug("test child finished with %d\n", err);
  193. } else if (WIFSIGNALED(status)) {
  194. err = -1;
  195. pr_debug("test child interrupted\n");
  196. }
  197. return err;
  198. }
  199. static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
  200. {
  201. int i = 0;
  202. int width = 0;
  203. while (tests[i].func) {
  204. int len = strlen(tests[i].desc);
  205. if (width < len)
  206. width = len;
  207. ++i;
  208. }
  209. i = 0;
  210. while (tests[i].func) {
  211. int curr = i++, err;
  212. if (!perf_test__matches(curr, argc, argv))
  213. continue;
  214. pr_info("%2d: %-*s:", i, width, tests[curr].desc);
  215. if (intlist__find(skiplist, i)) {
  216. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
  217. continue;
  218. }
  219. pr_debug("\n--- start ---\n");
  220. err = run_test(&tests[curr]);
  221. pr_debug("---- end ----\n%s:", tests[curr].desc);
  222. switch (err) {
  223. case TEST_OK:
  224. pr_info(" Ok\n");
  225. break;
  226. case TEST_SKIP:
  227. color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
  228. break;
  229. case TEST_FAIL:
  230. default:
  231. color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
  232. break;
  233. }
  234. }
  235. return 0;
  236. }
  237. static int perf_test__list(int argc, const char **argv)
  238. {
  239. int i = 0;
  240. while (tests[i].func) {
  241. int curr = i++;
  242. if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
  243. continue;
  244. pr_info("%2d: %s\n", i, tests[curr].desc);
  245. }
  246. return 0;
  247. }
  248. int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
  249. {
  250. const char * const test_usage[] = {
  251. "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
  252. NULL,
  253. };
  254. const char *skip = NULL;
  255. const struct option test_options[] = {
  256. OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
  257. OPT_INCR('v', "verbose", &verbose,
  258. "be more verbose (show symbol address, etc)"),
  259. OPT_END()
  260. };
  261. struct intlist *skiplist = NULL;
  262. argc = parse_options(argc, argv, test_options, test_usage, 0);
  263. if (argc >= 1 && !strcmp(argv[0], "list"))
  264. return perf_test__list(argc, argv);
  265. symbol_conf.priv_size = sizeof(int);
  266. symbol_conf.sort_by_name = true;
  267. symbol_conf.try_vmlinux_path = true;
  268. if (symbol__init() < 0)
  269. return -1;
  270. if (skip != NULL)
  271. skiplist = intlist__new(skip);
  272. return __cmd_test(argc, argv, skiplist);
  273. }