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