Merge branches 'acpi-battery', 'acpi-video' and 'acpi-misc'
[sfrench/cifs-2.6.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         &suite__sigtrap,
111         NULL,
112 };
113
114 static struct test_suite **tests[] = {
115         generic_tests,
116         arch_tests,
117 };
118
119 static int num_subtests(const struct test_suite *t)
120 {
121         int num;
122
123         if (!t->test_cases)
124                 return 0;
125
126         num = 0;
127         while (t->test_cases[num].name)
128                 num++;
129
130         return num;
131 }
132
133 static bool has_subtests(const struct test_suite *t)
134 {
135         return num_subtests(t) > 1;
136 }
137
138 static const char *skip_reason(const struct test_suite *t, int subtest)
139 {
140         if (t->test_cases && subtest >= 0)
141                 return t->test_cases[subtest].skip_reason;
142
143         return NULL;
144 }
145
146 static const char *test_description(const struct test_suite *t, int subtest)
147 {
148         if (t->test_cases && subtest >= 0)
149                 return t->test_cases[subtest].desc;
150
151         return t->desc;
152 }
153
154 static test_fnptr test_function(const struct test_suite *t, int subtest)
155 {
156         if (subtest <= 0)
157                 return t->test_cases[0].run_case;
158
159         return t->test_cases[subtest].run_case;
160 }
161
162 static bool perf_test__matches(const char *desc, int curr, int argc, const char *argv[])
163 {
164         int i;
165
166         if (argc == 0)
167                 return true;
168
169         for (i = 0; i < argc; ++i) {
170                 char *end;
171                 long nr = strtoul(argv[i], &end, 10);
172
173                 if (*end == '\0') {
174                         if (nr == curr + 1)
175                                 return true;
176                         continue;
177                 }
178
179                 if (strcasestr(desc, argv[i]))
180                         return true;
181         }
182
183         return false;
184 }
185
186 static int run_test(struct test_suite *test, int subtest)
187 {
188         int status, err = -1, child = dont_fork ? 0 : fork();
189         char sbuf[STRERR_BUFSIZE];
190
191         if (child < 0) {
192                 pr_err("failed to fork test: %s\n",
193                         str_error_r(errno, sbuf, sizeof(sbuf)));
194                 return -1;
195         }
196
197         if (!child) {
198                 if (!dont_fork) {
199                         pr_debug("test child forked, pid %d\n", getpid());
200
201                         if (verbose <= 0) {
202                                 int nullfd = open("/dev/null", O_WRONLY);
203
204                                 if (nullfd >= 0) {
205                                         close(STDERR_FILENO);
206                                         close(STDOUT_FILENO);
207
208                                         dup2(nullfd, STDOUT_FILENO);
209                                         dup2(STDOUT_FILENO, STDERR_FILENO);
210                                         close(nullfd);
211                                 }
212                         } else {
213                                 signal(SIGSEGV, sighandler_dump_stack);
214                                 signal(SIGFPE, sighandler_dump_stack);
215                         }
216                 }
217
218                 err = test_function(test, subtest)(test, subtest);
219                 if (!dont_fork)
220                         exit(err);
221         }
222
223         if (!dont_fork) {
224                 wait(&status);
225
226                 if (WIFEXITED(status)) {
227                         err = (signed char)WEXITSTATUS(status);
228                         pr_debug("test child finished with %d\n", err);
229                 } else if (WIFSIGNALED(status)) {
230                         err = -1;
231                         pr_debug("test child interrupted\n");
232                 }
233         }
234
235         return err;
236 }
237
238 #define for_each_test(j, k, t)                  \
239         for (j = 0; j < ARRAY_SIZE(tests); j++) \
240                 for (k = 0, t = tests[j][k]; tests[j][k]; k++, t = tests[j][k])
241
242 static int test_and_print(struct test_suite *t, int subtest)
243 {
244         int err;
245
246         pr_debug("\n--- start ---\n");
247         err = run_test(t, subtest);
248         pr_debug("---- end ----\n");
249
250         if (!has_subtests(t))
251                 pr_debug("%s:", t->desc);
252         else
253                 pr_debug("%s subtest %d:", t->desc, subtest + 1);
254
255         switch (err) {
256         case TEST_OK:
257                 pr_info(" Ok\n");
258                 break;
259         case TEST_SKIP: {
260                 const char *reason = skip_reason(t, subtest);
261
262                 if (reason)
263                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason);
264                 else
265                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
266         }
267                 break;
268         case TEST_FAIL:
269         default:
270                 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
271                 break;
272         }
273
274         return err;
275 }
276
277 static const char *shell_test__description(char *description, size_t size,
278                                            const char *path, const char *name)
279 {
280         FILE *fp;
281         char filename[PATH_MAX];
282         int ch;
283
284         path__join(filename, sizeof(filename), path, name);
285         fp = fopen(filename, "r");
286         if (!fp)
287                 return NULL;
288
289         /* Skip shebang */
290         do {
291                 ch = fgetc(fp);
292         } while (ch != EOF && ch != '\n');
293
294         description = fgets(description, size, fp);
295         fclose(fp);
296
297         return description ? strim(description + 1) : NULL;
298 }
299
300 #define for_each_shell_test(entlist, nr, base, ent)                     \
301         for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++)      \
302                 if (!is_directory(base, ent) && ent->d_name[0] != '.')
303
304 static const char *shell_tests__dir(char *path, size_t size)
305 {
306         const char *devel_dirs[] = { "./tools/perf/tests", "./tests", };
307         char *exec_path;
308         unsigned int i;
309
310         for (i = 0; i < ARRAY_SIZE(devel_dirs); ++i) {
311                 struct stat st;
312                 if (!lstat(devel_dirs[i], &st)) {
313                         scnprintf(path, size, "%s/shell", devel_dirs[i]);
314                         if (!lstat(devel_dirs[i], &st))
315                                 return path;
316                 }
317         }
318
319         /* Then installed path. */
320         exec_path = get_argv_exec_path();
321         scnprintf(path, size, "%s/tests/shell", exec_path);
322         free(exec_path);
323         return path;
324 }
325
326 static int shell_tests__max_desc_width(void)
327 {
328         struct dirent **entlist;
329         struct dirent *ent;
330         int n_dirs, e;
331         char path_dir[PATH_MAX];
332         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
333         int width = 0;
334
335         if (path == NULL)
336                 return -1;
337
338         n_dirs = scandir(path, &entlist, NULL, alphasort);
339         if (n_dirs == -1)
340                 return -1;
341
342         for_each_shell_test(entlist, n_dirs, path, ent) {
343                 char bf[256];
344                 const char *desc = shell_test__description(bf, sizeof(bf), path, ent->d_name);
345
346                 if (desc) {
347                         int len = strlen(desc);
348
349                         if (width < len)
350                                 width = len;
351                 }
352         }
353
354         for (e = 0; e < n_dirs; e++)
355                 zfree(&entlist[e]);
356         free(entlist);
357         return width;
358 }
359
360 struct shell_test {
361         const char *dir;
362         const char *file;
363 };
364
365 static int shell_test__run(struct test_suite *test, int subdir __maybe_unused)
366 {
367         int err;
368         char script[PATH_MAX];
369         struct shell_test *st = test->priv;
370
371         path__join(script, sizeof(script) - 3, st->dir, st->file);
372
373         if (verbose)
374                 strncat(script, " -v", sizeof(script) - strlen(script) - 1);
375
376         err = system(script);
377         if (!err)
378                 return TEST_OK;
379
380         return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL;
381 }
382
383 static int run_shell_tests(int argc, const char *argv[], int i, int width,
384                                 struct intlist *skiplist)
385 {
386         struct dirent **entlist;
387         struct dirent *ent;
388         int n_dirs, e;
389         char path_dir[PATH_MAX];
390         struct shell_test st = {
391                 .dir = shell_tests__dir(path_dir, sizeof(path_dir)),
392         };
393
394         if (st.dir == NULL)
395                 return -1;
396
397         n_dirs = scandir(st.dir, &entlist, NULL, alphasort);
398         if (n_dirs == -1) {
399                 pr_err("failed to open shell test directory: %s\n",
400                         st.dir);
401                 return -1;
402         }
403
404         for_each_shell_test(entlist, n_dirs, st.dir, ent) {
405                 int curr = i++;
406                 char desc[256];
407                 struct test_case test_cases[] = {
408                         {
409                                 .desc = shell_test__description(desc,
410                                                                 sizeof(desc),
411                                                                 st.dir,
412                                                                 ent->d_name),
413                                 .run_case = shell_test__run,
414                         },
415                         { .name = NULL, }
416                 };
417                 struct test_suite test_suite = {
418                         .desc = test_cases[0].desc,
419                         .test_cases = test_cases,
420                         .priv = &st,
421                 };
422
423                 if (test_suite.desc == NULL ||
424                     !perf_test__matches(test_suite.desc, curr, argc, argv))
425                         continue;
426
427                 st.file = ent->d_name;
428                 pr_info("%3d: %-*s:", i, width, test_suite.desc);
429
430                 if (intlist__find(skiplist, i)) {
431                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
432                         continue;
433                 }
434
435                 test_and_print(&test_suite, 0);
436         }
437
438         for (e = 0; e < n_dirs; e++)
439                 zfree(&entlist[e]);
440         free(entlist);
441         return 0;
442 }
443
444 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
445 {
446         struct test_suite *t;
447         unsigned int j, k;
448         int i = 0;
449         int width = shell_tests__max_desc_width();
450
451         for_each_test(j, k, t) {
452                 int len = strlen(test_description(t, -1));
453
454                 if (width < len)
455                         width = len;
456         }
457
458         for_each_test(j, k, t) {
459                 int curr = i++;
460                 int subi;
461
462                 if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) {
463                         bool skip = true;
464                         int subn;
465
466                         subn = num_subtests(t);
467
468                         for (subi = 0; subi < subn; subi++) {
469                                 if (perf_test__matches(test_description(t, subi),
470                                                         curr, argc, argv))
471                                         skip = false;
472                         }
473
474                         if (skip)
475                                 continue;
476                 }
477
478                 pr_info("%3d: %-*s:", i, width, test_description(t, -1));
479
480                 if (intlist__find(skiplist, i)) {
481                         color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
482                         continue;
483                 }
484
485                 if (!has_subtests(t)) {
486                         test_and_print(t, -1);
487                 } else {
488                         int subn = num_subtests(t);
489                         /*
490                          * minus 2 to align with normal testcases.
491                          * For subtest we print additional '.x' in number.
492                          * for example:
493                          *
494                          * 35: Test LLVM searching and compiling                        :
495                          * 35.1: Basic BPF llvm compiling test                          : Ok
496                          */
497                         int subw = width > 2 ? width - 2 : width;
498
499                         if (subn <= 0) {
500                                 color_fprintf(stderr, PERF_COLOR_YELLOW,
501                                               " Skip (not compiled in)\n");
502                                 continue;
503                         }
504                         pr_info("\n");
505
506                         for (subi = 0; subi < subn; subi++) {
507                                 int len = strlen(test_description(t, subi));
508
509                                 if (subw < len)
510                                         subw = len;
511                         }
512
513                         for (subi = 0; subi < subn; subi++) {
514                                 if (!perf_test__matches(test_description(t, subi),
515                                                         curr, argc, argv))
516                                         continue;
517
518                                 pr_info("%3d.%1d: %-*s:", i, subi + 1, subw,
519                                         test_description(t, subi));
520                                 test_and_print(t, subi);
521                         }
522                 }
523         }
524
525         return run_shell_tests(argc, argv, i, width, skiplist);
526 }
527
528 static int perf_test__list_shell(int argc, const char **argv, int i)
529 {
530         struct dirent **entlist;
531         struct dirent *ent;
532         int n_dirs, e;
533         char path_dir[PATH_MAX];
534         const char *path = shell_tests__dir(path_dir, sizeof(path_dir));
535
536         if (path == NULL)
537                 return -1;
538
539         n_dirs = scandir(path, &entlist, NULL, alphasort);
540         if (n_dirs == -1)
541                 return -1;
542
543         for_each_shell_test(entlist, n_dirs, path, ent) {
544                 int curr = i++;
545                 char bf[256];
546                 struct test_suite t = {
547                         .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name),
548                 };
549
550                 if (!perf_test__matches(t.desc, curr, argc, argv))
551                         continue;
552
553                 pr_info("%3d: %s\n", i, t.desc);
554
555         }
556
557         for (e = 0; e < n_dirs; e++)
558                 zfree(&entlist[e]);
559         free(entlist);
560         return 0;
561 }
562
563 static int perf_test__list(int argc, const char **argv)
564 {
565         unsigned int j, k;
566         struct test_suite *t;
567         int i = 0;
568
569         for_each_test(j, k, t) {
570                 int curr = i++;
571
572                 if (!perf_test__matches(test_description(t, -1), curr, argc, argv))
573                         continue;
574
575                 pr_info("%3d: %s\n", i, test_description(t, -1));
576
577                 if (has_subtests(t)) {
578                         int subn = num_subtests(t);
579                         int subi;
580
581                         for (subi = 0; subi < subn; subi++)
582                                 pr_info("%3d:%1d: %s\n", i, subi + 1,
583                                         test_description(t, subi));
584                 }
585         }
586
587         perf_test__list_shell(argc, argv, i);
588
589         return 0;
590 }
591
592 int cmd_test(int argc, const char **argv)
593 {
594         const char *test_usage[] = {
595         "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
596         NULL,
597         };
598         const char *skip = NULL;
599         const struct option test_options[] = {
600         OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
601         OPT_INCR('v', "verbose", &verbose,
602                     "be more verbose (show symbol address, etc)"),
603         OPT_BOOLEAN('F', "dont-fork", &dont_fork,
604                     "Do not fork for testcase"),
605         OPT_END()
606         };
607         const char * const test_subcommands[] = { "list", NULL };
608         struct intlist *skiplist = NULL;
609         int ret = hists__init();
610
611         if (ret < 0)
612                 return ret;
613
614         /* Unbuffered output */
615         setvbuf(stdout, NULL, _IONBF, 0);
616
617         argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
618         if (argc >= 1 && !strcmp(argv[0], "list"))
619                 return perf_test__list(argc - 1, argv + 1);
620
621         symbol_conf.priv_size = sizeof(int);
622         symbol_conf.sort_by_name = true;
623         symbol_conf.try_vmlinux_path = true;
624
625         if (symbol__init(NULL) < 0)
626                 return -1;
627
628         if (skip != NULL)
629                 skiplist = intlist__new(skip);
630         /*
631          * Tests that create BPF maps, for instance, need more than the 64K
632          * default:
633          */
634         rlimit__bump_memlock();
635
636         return __cmd_test(argc, argv, skiplist);
637 }