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