1 /* 2 * builtin-test.c 3 * 4 * Builtin regression testing command: ever growing number of sanity tests 5 */ 6 #include "builtin.h" 7 #include "intlist.h" 8 #include "tests.h" 9 #include "debug.h" 10 #include "color.h" 11 #include "parse-options.h" 12 #include "symbol.h" 13 14 static struct test { 15 const char *desc; 16 int (*func)(void); 17 } tests[] = { 18 { 19 .desc = "vmlinux symtab matches kallsyms", 20 .func = test__vmlinux_matches_kallsyms, 21 }, 22 { 23 .desc = "detect open syscall event", 24 .func = test__open_syscall_event, 25 }, 26 { 27 .desc = "detect open syscall event on all cpus", 28 .func = test__open_syscall_event_on_all_cpus, 29 }, 30 { 31 .desc = "read samples using the mmap interface", 32 .func = test__basic_mmap, 33 }, 34 { 35 .desc = "parse events tests", 36 .func = test__parse_events, 37 }, 38 #if defined(__x86_64__) || defined(__i386__) 39 { 40 .desc = "x86 rdpmc test", 41 .func = test__rdpmc, 42 }, 43 #endif 44 { 45 .desc = "Validate PERF_RECORD_* events & perf_sample fields", 46 .func = test__PERF_RECORD, 47 }, 48 { 49 .desc = "Test perf pmu format parsing", 50 .func = test__pmu, 51 }, 52 { 53 .desc = "Test dso data interface", 54 .func = test__dso_data, 55 }, 56 { 57 .desc = "roundtrip evsel->name check", 58 .func = test__perf_evsel__roundtrip_name_test, 59 }, 60 { 61 .desc = "Check parsing of sched tracepoints fields", 62 .func = test__perf_evsel__tp_sched_test, 63 }, 64 { 65 .desc = "Generate and check syscalls:sys_enter_open event fields", 66 .func = test__syscall_open_tp_fields, 67 }, 68 { 69 .desc = "struct perf_event_attr setup", 70 .func = test__attr, 71 }, 72 { 73 .desc = "Test matching and linking mutliple hists", 74 .func = test__hists_link, 75 }, 76 { 77 .desc = "Try 'use perf' in python, checking link problems", 78 .func = test__python_use, 79 }, 80 { 81 .func = NULL, 82 }, 83 }; 84 85 static bool perf_test__matches(int curr, int argc, const char *argv[]) 86 { 87 int i; 88 89 if (argc == 0) 90 return true; 91 92 for (i = 0; i < argc; ++i) { 93 char *end; 94 long nr = strtoul(argv[i], &end, 10); 95 96 if (*end == '\0') { 97 if (nr == curr + 1) 98 return true; 99 continue; 100 } 101 102 if (strstr(tests[curr].desc, argv[i])) 103 return true; 104 } 105 106 return false; 107 } 108 109 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) 110 { 111 int i = 0; 112 int width = 0; 113 114 while (tests[i].func) { 115 int len = strlen(tests[i].desc); 116 117 if (width < len) 118 width = len; 119 ++i; 120 } 121 122 i = 0; 123 while (tests[i].func) { 124 int curr = i++, err; 125 126 if (!perf_test__matches(curr, argc, argv)) 127 continue; 128 129 pr_info("%2d: %-*s:", i, width, tests[curr].desc); 130 131 if (intlist__find(skiplist, i)) { 132 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); 133 continue; 134 } 135 136 pr_debug("\n--- start ---\n"); 137 err = tests[curr].func(); 138 pr_debug("---- end ----\n%s:", tests[curr].desc); 139 140 switch (err) { 141 case TEST_OK: 142 pr_info(" Ok\n"); 143 break; 144 case TEST_SKIP: 145 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n"); 146 break; 147 case TEST_FAIL: 148 default: 149 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); 150 break; 151 } 152 } 153 154 return 0; 155 } 156 157 static int perf_test__list(int argc, const char **argv) 158 { 159 int i = 0; 160 161 while (tests[i].func) { 162 int curr = i++; 163 164 if (argc > 1 && !strstr(tests[curr].desc, argv[1])) 165 continue; 166 167 pr_info("%2d: %s\n", i, tests[curr].desc); 168 } 169 170 return 0; 171 } 172 173 int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) 174 { 175 const char * const test_usage[] = { 176 "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]", 177 NULL, 178 }; 179 const char *skip = NULL; 180 const struct option test_options[] = { 181 OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), 182 OPT_INCR('v', "verbose", &verbose, 183 "be more verbose (show symbol address, etc)"), 184 OPT_END() 185 }; 186 struct intlist *skiplist = NULL; 187 188 argc = parse_options(argc, argv, test_options, test_usage, 0); 189 if (argc >= 1 && !strcmp(argv[0], "list")) 190 return perf_test__list(argc, argv); 191 192 symbol_conf.priv_size = sizeof(int); 193 symbol_conf.sort_by_name = true; 194 symbol_conf.try_vmlinux_path = true; 195 196 if (symbol__init() < 0) 197 return -1; 198 199 if (skip != NULL) 200 skiplist = intlist__new(skip); 201 202 return __cmd_test(argc, argv, skiplist); 203 } 204