perf test: Add test case struct.
[linux-2.6-microblaze.git] / tools / perf / tests / builtin-test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-test.c
4  *
5  * Builtin regression testing command: ever growing number of sanity tests
6  */
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <dirent.h>
14 #include <sys/wait.h>
15 #include <sys/stat.h>
16 #include "builtin.h"
17 #include "hist.h"
18 #include "intlist.h"
19 #include "tests.h"
20 #include "debug.h"
21 #include "color.h"
22 #include <subcmd/parse-options.h>
23 #include "string2.h"
24 #include "symbol.h"
25 #include "util/rlimit.h"
26 #include <linux/kernel.h>
27 #include <linux/string.h>
28 #include <subcmd/exec-cmd.h>
29 #include <linux/zalloc.h>
30
31 static bool dont_fork;
32
33 struct test_suite *__weak arch_tests[] = {
34         NULL,
35 };
36
37 static struct test_suite *generic_tests[] = {
38         &suite__vmlinux_matches_kallsyms,
39         &suite__openat_syscall_event,
40         &suite__openat_syscall_event_on_all_cpus,
41         &suite__basic_mmap,
42         &suite__mem,
43         &suite__parse_events,
44         &suite__expr,
45         &suite__PERF_RECORD,
46         &suite__pmu,
47         &suite__pmu_events,
48         &suite__dso_data,
49         &suite__dso_data_cache,
50         &suite__dso_data_reopen,
51         &suite__perf_evsel__roundtrip_name_test,
52         &suite__perf_evsel__tp_sched_test,
53         &suite__syscall_openat_tp_fields,
54         &suite__attr,
55         &suite__hists_link,
56         &suite__python_use,
57         &suite__bp_signal,
58         &suite__bp_signal_overflow,
59         &suite__bp_accounting,
60         &suite__wp,
61         &suite__task_exit,
62         &suite__sw_clock_freq,
63         &suite__code_reading,
64         &suite__sample_parsing,
65         &suite__keep_tracking,
66         &suite__parse_no_sample_id_all,
67         &suite__hists_filter,
68         &suite__mmap_thread_lookup,
69         &suite__thread_maps_share,
70         &suite__hists_output,
71         &suite__hists_cumulate,
72         &suite__switch_tracking,
73         &suite__fdarray__filter,
74         &suite__fdarray__add,
75         &suite__kmod_path__parse,
76         &suite__thread_map,
77         &suite__llvm,
78         &suite__session_topology,
79         &suite__bpf,
80         &suite__thread_map_synthesize,
81         &suite__thread_map_remove,
82         &suite__cpu_map_synthesize,
83         &suite__synthesize_stat_config,
84         &suite__synthesize_stat,
85         &suite__synthesize_stat_round,
86         &suite__event_update,
87         &suite__event_times,
88         &suite__backward_ring_buffer,
89         &suite__cpu_map_print,
90         &suite__cpu_map_merge,
91         &suite__sdt_event,
92         &suite__is_printable_array,
93         &suite__bitmap_print,
94         &suite__perf_hooks,
95         &suite__clang,
96         &suite__unit_number__scnprint,
97         &suite__mem2node,
98         &suite__time_utils,
99         &suite__jit_write_elf,
100         &suite__pfm,
101         &suite__api_io,
102         &suite__maps__merge_in,
103         &suite__demangle_java,
104         &suite__demangle_ocaml,
105         &suite__parse_metric,
106         &suite__pe_file_parsing,
107         &suite__expand_cgroup_events,
108         &suite__perf_time_to_tsc,
109         &suite__dlfilter,
110         NULL,
111 };
112
113 static struct test_suite **tests[] = {
114         generic_tests,
115         arch_tests,
116 };
117
118 static int num_subtests(const struct test_suite *t)
119 {
120         int num;
121
122         if (t->subtest.get_nr)
123                 return t->subtest.get_nr();
124
125         if (!t->test_cases)
126                 return 0;
127
128         num = 0;
129         while (t->test_cases[num].name)
130                 num++;
131
132         return num;
133 }
134
135 static bool has_subtests(const struct test_suite *t)
136 {
137         return t->subtest.get_nr || num_subtests(t) > 1;
138 }
139
140 static const char *skip_reason(const struct test_suite *t, int subtest)
141 {
142         if (t->subtest.skip_reason)
143                 return t->subtest.skip_reason(subtest);
144
145         return NULL;
146 }
147
148 static const char *test_description(const struct test_suite *t, int subtest)
149 {
150         if (t->test_cases && subtest >= 0)
151                 return t->test_cases[subtest].desc;
152
153         if (t->subtest.get_desc && subtest >= 0)
154                 return t->subtest.get_desc(subtest);
155
156         return t->desc;
157 }
158
159 static bool is_supported(const struct test_suite *t)
160 {
161         return !t->is_supported || t->is_supported();
162 }
163
164 static test_fnptr test_function(const struct test_suite *t, int subtest)
165 {
166         if (t->func)
167                 return t->func;
168
169         if (subtest <= 0)
170                 return t->test_cases[0].run_case;
171
172         return t->test_cases[subtest].run_case;
173 }
174
175 static bool perf_test__matches(const char *desc, int curr, int argc, const char *argv[])
176 {
177         int i;
178
179         if (argc == 0)
180                 return true;
181
182         for (i = 0; i < argc; ++i) {
183                 char *end;
184                 long nr = strtoul(argv[i], &end, 10);
185
186                 if (*end == '\0') {
187                         if (nr == curr + 1)
188                                 return true;
189                         continue;
190                 }
191
192                 if (strcasestr(desc, argv[i]))
193                         return true;
194         }
195
196         return false;
197 }
198
199 static int run_test(struct test_suite *test, int subtest)
200 {
201         int status, err = -1, child = dont_fork ? 0 : fork();
202         char sbuf[STRERR_BUFSIZE];
203
204         if (child < 0) {
205                 pr_err("failed to fork test: %s\n",
206                         str_error_r(errno, sbuf, sizeof(sbuf)));
207                 return -1;
208         }
209
210         if (!child) {
211                 if (!dont_fork) {
212                         pr_debug("test child forked, pid %d\n", getpid());
213
214                         if (verbose <= 0) {
215                                 int nullfd = open("/dev/null", O_WRONLY);
216
217                                 if (nullfd >= 0) {
218                                         close(STDERR_FILENO);
219                                         close(STDOUT_FILENO);
220
221                                         dup2(nullfd, STDOUT_FILENO);
222                                         dup2(STDOUT_FILENO, STDERR_FILENO);
223                                         close(nullfd);
224                                 }
225                         } else {
226                                 signal(SIGSEGV, sighandler_dump_stack);
227                                 signal(SIGFPE, sighandler_dump_stack);
228                         }
229                 }
230
231                 err = test_function(test, subtest)(test, subtest);
232                 if (!dont_fork)
233                         exit(err);
234         }
235
236         if (!dont_fork) {
237                 wait(&status);
238
239                 if (WIFEXITED(status)) {
240                         err = (signed char)WEXITSTATUS(status);
241                         pr_debug("test child finished with %d\n", err);
242                 } else if (WIFSIGNALED(status)) {
243                         err = -1;
244                         pr_debug("test child interrupted\n");
245                 }
246         }
247
248         return err;
249 }
250
251 #define for_each_test(j, k, t)                  \
252         for (j = 0; j < ARRAY_SIZE(tests); j++) \
253                 for (k = 0, t = tests[j][k]; tests[j][k]; k++, t = tests[j][k])
254
255 static int test_and_print(struct test_suite *t, bool force_skip, int subtest)
256 {
257         int err;
258
259         if (!force_skip) {
260                 pr_debug("\n--- start ---\n");
261                 err = run_test(t, subtest);
262                 pr_debug("---- end ----\n");
263         } else {
264                 pr_debug("\n--- force skipped ---\n");
265                 err = TEST_SKIP;
266         }
267
268         if (!has_subtests(t))
269                 pr_debug("%s:", t->desc);
270         else
271                 pr_debug("%s subtest %d:", t->desc, subtest + 1);
272
273         switch (err) {
274         case TEST_OK:
275                 pr_info(" Ok\n");
276                 break;
277         case TEST_SKIP: {
278                 const char *reason = skip_reason(t, subtest);
279
280                 if (reason)
281                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason);
282                 else
283                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
284         }
285                 break;
286         case TEST_FAIL:
287         default:
288                 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
289                 break;
290         }
291
292         return err;
293 }
294
295 static const char *shell_test__description(char *description, size_t size,
296                                            const char *path, const char *name)
297 {
298         FILE *fp;
299         char filename[PATH_MAX];
300
301         path__join(filename, sizeof(filename), path, name);
302         fp = fopen(filename, "r");
303         if (!fp)
304                 return NULL;
305
306         /* Skip shebang */
307         while (fgetc(fp) != '\n');
308
309         description = fgets(description, size, fp);
310         fclose(fp);
311
312         return description ? strim(description + 1) : NULL;
313 }
314
315 #define for_each_shell_test(entlist, nr, base, ent)                     \
316         for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++)      \
317                 if (!is_directory(base, ent) && ent->d_name[0] != '.')
318
319 static const char *shell_tests__dir(char *path, size_t size)
320 {
321         const char *devel_dirs[] = { "./tools/perf/tests", "./tests", };
322         char *exec_path;
323         unsigned int i;
324
325         for (i = 0; i < ARRAY_SIZE(devel_dirs); ++i) {
326                 struct stat st;
327                 if (!lstat(devel_dirs[i], &st)) {
328                         scnprintf(path, size, "%s/shell", devel_dirs[i]);
329                         if (!lstat(devel_dirs[i], &st))
330                                 return path;
331                 }
332         }
333
334         /* Then installed path. */
335         exec_path = get_argv_exec_path();
336         scnprintf(path, size, "%s/tests/shell", exec_path);
337         free(exec_path);
338         return path;
339 }
340
341 static int shell_tests__max_desc_width(void)
342 {
343         struct dirent **entlist;
344         struct dirent *ent;
345         int n_dirs, e;
346         char path_dir[PATH_MAX];
347         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
348         int width = 0;
349
350         if (path == NULL)
351                 return -1;
352
353         n_dirs = scandir(path, &entlist, NULL, alphasort);
354         if (n_dirs == -1)
355                 return -1;
356
357         for_each_shell_test(entlist, n_dirs, path, ent) {
358                 char bf[256];
359                 const char *desc = shell_test__description(bf, sizeof(bf), path, ent->d_name);
360
361                 if (desc) {
362                         int len = strlen(desc);
363
364                         if (width < len)
365                                 width = len;
366                 }
367         }
368
369         for (e = 0; e < n_dirs; e++)
370                 zfree(&entlist[e]);
371         free(entlist);
372         return width;
373 }
374
375 struct shell_test {
376         const char *dir;
377         const char *file;
378 };
379
380 static int shell_test__run(struct test_suite *test, int subdir __maybe_unused)
381 {
382         int err;
383         char script[PATH_MAX];
384         struct shell_test *st = test->priv;
385
386         path__join(script, sizeof(script) - 3, st->dir, st->file);
387
388         if (verbose)
389                 strncat(script, " -v", sizeof(script) - strlen(script) - 1);
390
391         err = system(script);
392         if (!err)
393                 return TEST_OK;
394
395         return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL;
396 }
397
398 static int run_shell_tests(int argc, const char *argv[], int i, int width,
399                                 struct intlist *skiplist)
400 {
401         struct dirent **entlist;
402         struct dirent *ent;
403         int n_dirs, e;
404         char path_dir[PATH_MAX];
405         struct shell_test st = {
406                 .dir = shell_tests__dir(path_dir, sizeof(path_dir)),
407         };
408
409         if (st.dir == NULL)
410                 return -1;
411
412         n_dirs = scandir(st.dir, &entlist, NULL, alphasort);
413         if (n_dirs == -1) {
414                 pr_err("failed to open shell test directory: %s\n",
415                         st.dir);
416                 return -1;
417         }
418
419         for_each_shell_test(entlist, n_dirs, st.dir, ent) {
420                 int curr = i++;
421                 char desc[256];
422                 struct test_suite test = {
423                         .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name),
424                         .func = shell_test__run,
425                         .priv = &st,
426                 };
427
428                 if (!perf_test__matches(test.desc, curr, argc, argv))
429                         continue;
430
431                 st.file = ent->d_name;
432                 pr_info("%2d: %-*s:", i, width, test.desc);
433
434                 if (intlist__find(skiplist, i)) {
435                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
436                         continue;
437                 }
438
439                 test_and_print(&test, false, -1);
440         }
441
442         for (e = 0; e < n_dirs; e++)
443                 zfree(&entlist[e]);
444         free(entlist);
445         return 0;
446 }
447
448 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
449 {
450         struct test_suite *t;
451         unsigned int j, k;
452         int i = 0;
453         int width = shell_tests__max_desc_width();
454
455         for_each_test(j, k, t) {
456                 int len = strlen(test_description(t, -1));
457
458                 if (width < len)
459                         width = len;
460         }
461
462         for_each_test(j, k, t) {
463                 int curr = i++, err;
464                 int subi;
465
466                 if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) {
467                         bool skip = true;
468                         int subn;
469
470                         subn = num_subtests(t);
471
472                         for (subi = 0; subi < subn; subi++) {
473                                 if (perf_test__matches(test_description(t, subi),
474                                                         curr, argc, argv))
475                                         skip = false;
476                         }
477
478                         if (skip)
479                                 continue;
480                 }
481
482                 if (!is_supported(t)) {
483                         pr_debug("%2d: %-*s: Disabled\n", i, width,
484                                  test_description(t, -1));
485                         continue;
486                 }
487
488                 pr_info("%2d: %-*s:", i, width, test_description(t, -1));
489
490                 if (intlist__find(skiplist, i)) {
491                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
492                         continue;
493                 }
494
495                 if (!has_subtests(t)) {
496                         test_and_print(t, false, -1);
497                 } else {
498                         int subn = num_subtests(t);
499                         /*
500                          * minus 2 to align with normal testcases.
501                          * For subtest we print additional '.x' in number.
502                          * for example:
503                          *
504                          * 35: Test LLVM searching and compiling                        :
505                          * 35.1: Basic BPF llvm compiling test                          : Ok
506                          */
507                         int subw = width > 2 ? width - 2 : width;
508                         bool skip = false;
509
510                         if (subn <= 0) {
511                                 color_fprintf(stderr, PERF_COLOR_YELLOW,
512                                               " Skip (not compiled in)\n");
513                                 continue;
514                         }
515                         pr_info("\n");
516
517                         for (subi = 0; subi < subn; subi++) {
518                                 int len = strlen(test_description(t, subi));
519
520                                 if (subw < len)
521                                         subw = len;
522                         }
523
524                         for (subi = 0; subi < subn; subi++) {
525                                 if (!perf_test__matches(test_description(t, subi),
526                                                         curr, argc, argv))
527                                         continue;
528
529                                 pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
530                                         test_description(t, subi));
531                                 err = test_and_print(t, skip, subi);
532                                 if (err != TEST_OK && t->subtest.skip_if_fail)
533                                         skip = true;
534                         }
535                 }
536         }
537
538         return run_shell_tests(argc, argv, i, width, skiplist);
539 }
540
541 static int perf_test__list_shell(int argc, const char **argv, int i)
542 {
543         struct dirent **entlist;
544         struct dirent *ent;
545         int n_dirs, e;
546         char path_dir[PATH_MAX];
547         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
548
549         if (path == NULL)
550                 return -1;
551
552         n_dirs = scandir(path, &entlist, NULL, alphasort);
553         if (n_dirs == -1)
554                 return -1;
555
556         for_each_shell_test(entlist, n_dirs, path, ent) {
557                 int curr = i++;
558                 char bf[256];
559                 struct test_suite t = {
560                         .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name),
561                 };
562
563                 if (!perf_test__matches(t.desc, curr, argc, argv))
564                         continue;
565
566                 pr_info("%2d: %s\n", i, t.desc);
567
568         }
569
570         for (e = 0; e < n_dirs; e++)
571                 zfree(&entlist[e]);
572         free(entlist);
573         return 0;
574 }
575
576 static int perf_test__list(int argc, const char **argv)
577 {
578         unsigned int j, k;
579         struct test_suite *t;
580         int i = 0;
581
582         for_each_test(j, k, t) {
583                 int curr = i++;
584
585                 if (!perf_test__matches(test_description(t, -1), curr, argc, argv) ||
586                     !is_supported(t))
587                         continue;
588
589                 pr_info("%2d: %s\n", i, test_description(t, -1));
590
591                 if (has_subtests(t)) {
592                         int subn = num_subtests(t);
593                         int subi;
594
595                         for (subi = 0; subi < subn; subi++)
596                                 pr_info("%2d:%1d: %s\n", i, subi + 1,
597                                         test_description(t, subi));
598                 }
599         }
600
601         perf_test__list_shell(argc, argv, i);
602
603         return 0;
604 }
605
606 int cmd_test(int argc, const char **argv)
607 {
608         const char *test_usage[] = {
609         "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
610         NULL,
611         };
612         const char *skip = NULL;
613         const struct option test_options[] = {
614         OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
615         OPT_INCR('v', "verbose", &verbose,
616                     "be more verbose (show symbol address, etc)"),
617         OPT_BOOLEAN('F', "dont-fork", &dont_fork,
618                     "Do not fork for testcase"),
619         OPT_END()
620         };
621         const char * const test_subcommands[] = { "list", NULL };
622         struct intlist *skiplist = NULL;
623         int ret = hists__init();
624
625         if (ret < 0)
626                 return ret;
627
628         argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
629         if (argc >= 1 && !strcmp(argv[0], "list"))
630                 return perf_test__list(argc - 1, argv + 1);
631
632         symbol_conf.priv_size = sizeof(int);
633         symbol_conf.sort_by_name = true;
634         symbol_conf.try_vmlinux_path = true;
635
636         if (symbol__init(NULL) < 0)
637                 return -1;
638
639         if (skip != NULL)
640                 skiplist = intlist__new(skip);
641         /*
642          * Tests that create BPF maps, for instance, need more than the 64K
643          * default:
644          */
645         rlimit__bump_memlock();
646
647         return __cmd_test(argc, argv, skiplist);
648 }