Merge tag 'for-4.14/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / tools / perf / tests / builtin-test.c
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/types.h>
10 #include <dirent.h>
11 #include <sys/wait.h>
12 #include <sys/stat.h>
13 #include "builtin.h"
14 #include "hist.h"
15 #include "intlist.h"
16 #include "tests.h"
17 #include "debug.h"
18 #include "color.h"
19 #include <subcmd/parse-options.h>
20 #include "string2.h"
21 #include "symbol.h"
22 #include <linux/kernel.h>
23 #include <subcmd/exec-cmd.h>
24
25 static bool dont_fork;
26
27 struct test __weak arch_tests[] = {
28         {
29                 .func = NULL,
30         },
31 };
32
33 static struct test generic_tests[] = {
34         {
35                 .desc = "vmlinux symtab matches kallsyms",
36                 .func = test__vmlinux_matches_kallsyms,
37         },
38         {
39                 .desc = "Detect openat syscall event",
40                 .func = test__openat_syscall_event,
41         },
42         {
43                 .desc = "Detect openat syscall event on all cpus",
44                 .func = test__openat_syscall_event_on_all_cpus,
45         },
46         {
47                 .desc = "Read samples using the mmap interface",
48                 .func = test__basic_mmap,
49         },
50         {
51                 .desc = "Test data source output",
52                 .func = test__mem,
53         },
54         {
55                 .desc = "Parse event definition strings",
56                 .func = test__parse_events,
57         },
58         {
59                 .desc = "Simple expression parser",
60                 .func = test__expr,
61         },
62         {
63                 .desc = "PERF_RECORD_* events & perf_sample fields",
64                 .func = test__PERF_RECORD,
65         },
66         {
67                 .desc = "Parse perf pmu format",
68                 .func = test__pmu,
69         },
70         {
71                 .desc = "DSO data read",
72                 .func = test__dso_data,
73         },
74         {
75                 .desc = "DSO data cache",
76                 .func = test__dso_data_cache,
77         },
78         {
79                 .desc = "DSO data reopen",
80                 .func = test__dso_data_reopen,
81         },
82         {
83                 .desc = "Roundtrip evsel->name",
84                 .func = test__perf_evsel__roundtrip_name_test,
85         },
86         {
87                 .desc = "Parse sched tracepoints fields",
88                 .func = test__perf_evsel__tp_sched_test,
89         },
90         {
91                 .desc = "syscalls:sys_enter_openat event fields",
92                 .func = test__syscall_openat_tp_fields,
93         },
94         {
95                 .desc = "Setup struct perf_event_attr",
96                 .func = test__attr,
97         },
98         {
99                 .desc = "Match and link multiple hists",
100                 .func = test__hists_link,
101         },
102         {
103                 .desc = "'import perf' in python",
104                 .func = test__python_use,
105         },
106         {
107                 .desc = "Breakpoint overflow signal handler",
108                 .func = test__bp_signal,
109                 .is_supported = test__bp_signal_is_supported,
110         },
111         {
112                 .desc = "Breakpoint overflow sampling",
113                 .func = test__bp_signal_overflow,
114                 .is_supported = test__bp_signal_is_supported,
115         },
116         {
117                 .desc = "Number of exit events of a simple workload",
118                 .func = test__task_exit,
119         },
120         {
121                 .desc = "Software clock events period values",
122                 .func = test__sw_clock_freq,
123         },
124         {
125                 .desc = "Object code reading",
126                 .func = test__code_reading,
127         },
128         {
129                 .desc = "Sample parsing",
130                 .func = test__sample_parsing,
131         },
132         {
133                 .desc = "Use a dummy software event to keep tracking",
134                 .func = test__keep_tracking,
135         },
136         {
137                 .desc = "Parse with no sample_id_all bit set",
138                 .func = test__parse_no_sample_id_all,
139         },
140         {
141                 .desc = "Filter hist entries",
142                 .func = test__hists_filter,
143         },
144         {
145                 .desc = "Lookup mmap thread",
146                 .func = test__mmap_thread_lookup,
147         },
148         {
149                 .desc = "Share thread mg",
150                 .func = test__thread_mg_share,
151         },
152         {
153                 .desc = "Sort output of hist entries",
154                 .func = test__hists_output,
155         },
156         {
157                 .desc = "Cumulate child hist entries",
158                 .func = test__hists_cumulate,
159         },
160         {
161                 .desc = "Track with sched_switch",
162                 .func = test__switch_tracking,
163         },
164         {
165                 .desc = "Filter fds with revents mask in a fdarray",
166                 .func = test__fdarray__filter,
167         },
168         {
169                 .desc = "Add fd to a fdarray, making it autogrow",
170                 .func = test__fdarray__add,
171         },
172         {
173                 .desc = "kmod_path__parse",
174                 .func = test__kmod_path__parse,
175         },
176         {
177                 .desc = "Thread map",
178                 .func = test__thread_map,
179         },
180         {
181                 .desc = "LLVM search and compile",
182                 .func = test__llvm,
183                 .subtest = {
184                         .skip_if_fail   = true,
185                         .get_nr         = test__llvm_subtest_get_nr,
186                         .get_desc       = test__llvm_subtest_get_desc,
187                 },
188         },
189         {
190                 .desc = "Session topology",
191                 .func = test__session_topology,
192         },
193         {
194                 .desc = "BPF filter",
195                 .func = test__bpf,
196                 .subtest = {
197                         .skip_if_fail   = true,
198                         .get_nr         = test__bpf_subtest_get_nr,
199                         .get_desc       = test__bpf_subtest_get_desc,
200                 },
201         },
202         {
203                 .desc = "Synthesize thread map",
204                 .func = test__thread_map_synthesize,
205         },
206         {
207                 .desc = "Remove thread map",
208                 .func = test__thread_map_remove,
209         },
210         {
211                 .desc = "Synthesize cpu map",
212                 .func = test__cpu_map_synthesize,
213         },
214         {
215                 .desc = "Synthesize stat config",
216                 .func = test__synthesize_stat_config,
217         },
218         {
219                 .desc = "Synthesize stat",
220                 .func = test__synthesize_stat,
221         },
222         {
223                 .desc = "Synthesize stat round",
224                 .func = test__synthesize_stat_round,
225         },
226         {
227                 .desc = "Synthesize attr update",
228                 .func = test__event_update,
229         },
230         {
231                 .desc = "Event times",
232                 .func = test__event_times,
233         },
234         {
235                 .desc = "Read backward ring buffer",
236                 .func = test__backward_ring_buffer,
237         },
238         {
239                 .desc = "Print cpu map",
240                 .func = test__cpu_map_print,
241         },
242         {
243                 .desc = "Probe SDT events",
244                 .func = test__sdt_event,
245         },
246         {
247                 .desc = "is_printable_array",
248                 .func = test__is_printable_array,
249         },
250         {
251                 .desc = "Print bitmap",
252                 .func = test__bitmap_print,
253         },
254         {
255                 .desc = "perf hooks",
256                 .func = test__perf_hooks,
257         },
258         {
259                 .desc = "builtin clang support",
260                 .func = test__clang,
261                 .subtest = {
262                         .skip_if_fail   = true,
263                         .get_nr         = test__clang_subtest_get_nr,
264                         .get_desc       = test__clang_subtest_get_desc,
265                 }
266         },
267         {
268                 .desc = "unit_number__scnprintf",
269                 .func = test__unit_number__scnprint,
270         },
271         {
272                 .func = NULL,
273         },
274 };
275
276 static struct test *tests[] = {
277         generic_tests,
278         arch_tests,
279 };
280
281 static bool perf_test__matches(struct test *test, int curr, int argc, const char *argv[])
282 {
283         int i;
284
285         if (argc == 0)
286                 return true;
287
288         for (i = 0; i < argc; ++i) {
289                 char *end;
290                 long nr = strtoul(argv[i], &end, 10);
291
292                 if (*end == '\0') {
293                         if (nr == curr + 1)
294                                 return true;
295                         continue;
296                 }
297
298                 if (strcasestr(test->desc, argv[i]))
299                         return true;
300         }
301
302         return false;
303 }
304
305 static int run_test(struct test *test, int subtest)
306 {
307         int status, err = -1, child = dont_fork ? 0 : fork();
308         char sbuf[STRERR_BUFSIZE];
309
310         if (child < 0) {
311                 pr_err("failed to fork test: %s\n",
312                         str_error_r(errno, sbuf, sizeof(sbuf)));
313                 return -1;
314         }
315
316         if (!child) {
317                 if (!dont_fork) {
318                         pr_debug("test child forked, pid %d\n", getpid());
319
320                         if (verbose <= 0) {
321                                 int nullfd = open("/dev/null", O_WRONLY);
322
323                                 if (nullfd >= 0) {
324                                         close(STDERR_FILENO);
325                                         close(STDOUT_FILENO);
326
327                                         dup2(nullfd, STDOUT_FILENO);
328                                         dup2(STDOUT_FILENO, STDERR_FILENO);
329                                         close(nullfd);
330                                 }
331                         } else {
332                                 signal(SIGSEGV, sighandler_dump_stack);
333                                 signal(SIGFPE, sighandler_dump_stack);
334                         }
335                 }
336
337                 err = test->func(test, subtest);
338                 if (!dont_fork)
339                         exit(err);
340         }
341
342         if (!dont_fork) {
343                 wait(&status);
344
345                 if (WIFEXITED(status)) {
346                         err = (signed char)WEXITSTATUS(status);
347                         pr_debug("test child finished with %d\n", err);
348                 } else if (WIFSIGNALED(status)) {
349                         err = -1;
350                         pr_debug("test child interrupted\n");
351                 }
352         }
353
354         return err;
355 }
356
357 #define for_each_test(j, t)                                     \
358         for (j = 0; j < ARRAY_SIZE(tests); j++) \
359                 for (t = &tests[j][0]; t->func; t++)
360
361 static int test_and_print(struct test *t, bool force_skip, int subtest)
362 {
363         int err;
364
365         if (!force_skip) {
366                 pr_debug("\n--- start ---\n");
367                 err = run_test(t, subtest);
368                 pr_debug("---- end ----\n");
369         } else {
370                 pr_debug("\n--- force skipped ---\n");
371                 err = TEST_SKIP;
372         }
373
374         if (!t->subtest.get_nr)
375                 pr_debug("%s:", t->desc);
376         else
377                 pr_debug("%s subtest %d:", t->desc, subtest);
378
379         switch (err) {
380         case TEST_OK:
381                 pr_info(" Ok\n");
382                 break;
383         case TEST_SKIP:
384                 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
385                 break;
386         case TEST_FAIL:
387         default:
388                 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
389                 break;
390         }
391
392         return err;
393 }
394
395 static const char *shell_test__description(char *description, size_t size,
396                                            const char *path, const char *name)
397 {
398         FILE *fp;
399         char filename[PATH_MAX];
400
401         path__join(filename, sizeof(filename), path, name);
402         fp = fopen(filename, "r");
403         if (!fp)
404                 return NULL;
405
406         description = fgets(description, size, fp);
407         fclose(fp);
408
409         return description ? trim(description + 1) : NULL;
410 }
411
412 #define for_each_shell_test(dir, ent)           \
413         while ((ent = readdir(dir)) != NULL)    \
414                 if (ent->d_type == DT_REG && ent->d_name[0] != '.')
415
416 static const char *shell_tests__dir(char *path, size_t size)
417 {
418         const char *devel_dirs[] = { "./tools/perf/tests", "./tests", };
419         char *exec_path;
420         unsigned int i;
421
422         for (i = 0; i < ARRAY_SIZE(devel_dirs); ++i) {
423                 struct stat st;
424                 if (!lstat(devel_dirs[i], &st)) {
425                         scnprintf(path, size, "%s/shell", devel_dirs[i]);
426                         if (!lstat(devel_dirs[i], &st))
427                                 return path;
428                 }
429         }
430
431         /* Then installed path. */
432         exec_path = get_argv_exec_path();
433         scnprintf(path, size, "%s/tests/shell", exec_path);
434         free(exec_path);
435         return path;
436 }
437
438 static int shell_tests__max_desc_width(void)
439 {
440         DIR *dir;
441         struct dirent *ent;
442         char path_dir[PATH_MAX];
443         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
444         int width = 0;
445
446         if (path == NULL)
447                 return -1;
448
449         dir = opendir(path);
450         if (!dir)
451                 return -1;
452
453         for_each_shell_test(dir, ent) {
454                 char bf[256];
455                 const char *desc = shell_test__description(bf, sizeof(bf), path, ent->d_name);
456
457                 if (desc) {
458                         int len = strlen(desc);
459
460                         if (width < len)
461                                 width = len;
462                 }
463         }
464
465         closedir(dir);
466         return width;
467 }
468
469 struct shell_test {
470         const char *dir;
471         const char *file;
472 };
473
474 static int shell_test__run(struct test *test, int subdir __maybe_unused)
475 {
476         int err;
477         char script[PATH_MAX];
478         struct shell_test *st = test->priv;
479
480         path__join(script, sizeof(script), st->dir, st->file);
481
482         err = system(script);
483         if (!err)
484                 return TEST_OK;
485
486         return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL;
487 }
488
489 static int run_shell_tests(int argc, const char *argv[], int i, int width)
490 {
491         DIR *dir;
492         struct dirent *ent;
493         char path_dir[PATH_MAX];
494         struct shell_test st = {
495                 .dir = shell_tests__dir(path_dir, sizeof(path_dir)),
496         };
497
498         if (st.dir == NULL)
499                 return -1;
500
501         dir = opendir(st.dir);
502         if (!dir)
503                 return -1;
504
505         for_each_shell_test(dir, ent) {
506                 int curr = i++;
507                 char desc[256];
508                 struct test test = {
509                         .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name),
510                         .func = shell_test__run,
511                         .priv = &st,
512                 };
513
514                 if (!perf_test__matches(&test, curr, argc, argv))
515                         continue;
516
517                 st.file = ent->d_name;
518                 pr_info("%2d: %-*s:", i, width, test.desc);
519                 test_and_print(&test, false, -1);
520         }
521
522         closedir(dir);
523         return 0;
524 }
525
526 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
527 {
528         struct test *t;
529         unsigned int j;
530         int i = 0;
531         int width = shell_tests__max_desc_width();
532
533         for_each_test(j, t) {
534                 int len = strlen(t->desc);
535
536                 if (width < len)
537                         width = len;
538         }
539
540         for_each_test(j, t) {
541                 int curr = i++, err;
542
543                 if (!perf_test__matches(t, curr, argc, argv))
544                         continue;
545
546                 if (t->is_supported && !t->is_supported()) {
547                         pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
548                         continue;
549                 }
550
551                 pr_info("%2d: %-*s:", i, width, t->desc);
552
553                 if (intlist__find(skiplist, i)) {
554                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
555                         continue;
556                 }
557
558                 if (!t->subtest.get_nr) {
559                         test_and_print(t, false, -1);
560                 } else {
561                         int subn = t->subtest.get_nr();
562                         /*
563                          * minus 2 to align with normal testcases.
564                          * For subtest we print additional '.x' in number.
565                          * for example:
566                          *
567                          * 35: Test LLVM searching and compiling                        :
568                          * 35.1: Basic BPF llvm compiling test                          : Ok
569                          */
570                         int subw = width > 2 ? width - 2 : width;
571                         bool skip = false;
572                         int subi;
573
574                         if (subn <= 0) {
575                                 color_fprintf(stderr, PERF_COLOR_YELLOW,
576                                               " Skip (not compiled in)\n");
577                                 continue;
578                         }
579                         pr_info("\n");
580
581                         for (subi = 0; subi < subn; subi++) {
582                                 int len = strlen(t->subtest.get_desc(subi));
583
584                                 if (subw < len)
585                                         subw = len;
586                         }
587
588                         for (subi = 0; subi < subn; subi++) {
589                                 pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
590                                         t->subtest.get_desc(subi));
591                                 err = test_and_print(t, skip, subi);
592                                 if (err != TEST_OK && t->subtest.skip_if_fail)
593                                         skip = true;
594                         }
595                 }
596         }
597
598         return run_shell_tests(argc, argv, i, width);
599 }
600
601 static int perf_test__list_shell(int argc, const char **argv, int i)
602 {
603         DIR *dir;
604         struct dirent *ent;
605         char path_dir[PATH_MAX];
606         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
607
608         if (path == NULL)
609                 return -1;
610
611         dir = opendir(path);
612         if (!dir)
613                 return -1;
614
615         for_each_shell_test(dir, ent) {
616                 int curr = i++;
617                 char bf[256];
618                 struct test t = {
619                         .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name),
620                 };
621
622                 if (!perf_test__matches(&t, curr, argc, argv))
623                         continue;
624
625                 pr_info("%2d: %s\n", i, t.desc);
626         }
627
628         closedir(dir);
629         return 0;
630 }
631
632 static int perf_test__list(int argc, const char **argv)
633 {
634         unsigned int j;
635         struct test *t;
636         int i = 0;
637
638         for_each_test(j, t) {
639                 int curr = i++;
640
641                 if (!perf_test__matches(t, curr, argc, argv) ||
642                     (t->is_supported && !t->is_supported()))
643                         continue;
644
645                 pr_info("%2d: %s\n", i, t->desc);
646         }
647
648         perf_test__list_shell(argc, argv, i);
649
650         return 0;
651 }
652
653 int cmd_test(int argc, const char **argv)
654 {
655         const char *test_usage[] = {
656         "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
657         NULL,
658         };
659         const char *skip = NULL;
660         const struct option test_options[] = {
661         OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
662         OPT_INCR('v', "verbose", &verbose,
663                     "be more verbose (show symbol address, etc)"),
664         OPT_BOOLEAN('F', "dont-fork", &dont_fork,
665                     "Do not fork for testcase"),
666         OPT_END()
667         };
668         const char * const test_subcommands[] = { "list", NULL };
669         struct intlist *skiplist = NULL;
670         int ret = hists__init();
671
672         if (ret < 0)
673                 return ret;
674
675         argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
676         if (argc >= 1 && !strcmp(argv[0], "list"))
677                 return perf_test__list(argc - 1, argv + 1);
678
679         symbol_conf.priv_size = sizeof(int);
680         symbol_conf.sort_by_name = true;
681         symbol_conf.try_vmlinux_path = true;
682
683         if (symbol__init(NULL) < 0)
684                 return -1;
685
686         if (skip != NULL)
687                 skiplist = intlist__new(skip);
688
689         return __cmd_test(argc, argv, skiplist);
690 }