blob: c66caa79c622960c15dfd3e1fcc67446a9cdb372 [file] [log] [blame]
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -03001/*
2 * builtin-test.c
3 *
4 * Builtin regression testing command: ever growing number of sanity tests
5 */
6#include "builtin.h"
7
8#include "util/cache.h"
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -02009#include "util/color.h"
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -030010#include "util/debug.h"
Arnaldo Carvalho de Meloebf294b2011-11-16 14:03:07 -020011#include "util/debugfs.h"
Arnaldo Carvalho de Melode5fa3a2011-01-15 10:42:46 -020012#include "util/evlist.h"
Arnaldo Carvalho de Melo69d25912012-11-09 11:32:52 -030013#include "util/machine.h"
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -030014#include "util/parse-options.h"
Arnaldo Carvalho de Melode5fa3a2011-01-15 10:42:46 -020015#include "util/parse-events.h"
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -030016#include "util/symbol.h"
Arnaldo Carvalho de Melofd782602011-01-18 15:15:24 -020017#include "util/thread_map.h"
Jiri Olsacd82a322012-03-15 20:09:17 +010018#include "util/pmu.h"
Arnaldo Carvalho de Melo6a6cd112012-09-18 11:56:28 -030019#include "event-parse.h"
Jiri Olsa13b62562011-07-14 11:25:33 +020020#include "../../include/linux/hw_breakpoint.h"
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -030021
Peter Zijlstra08aa0d12011-11-21 14:42:47 +010022#include <sys/mman.h>
23
Arnaldo Carvalho de Melo02522082011-01-04 11:55:27 -020024#include "util/cpumap.h"
Arnaldo Carvalho de Melod8548612011-01-04 00:16:20 -020025#include "util/evsel.h"
26#include <sys/types.h>
27
Jiri Olsa0a4e1ae2012-11-10 01:46:41 +010028#include "tests.h"
29
Arnaldo Carvalho de Melo02522082011-01-04 11:55:27 -020030#include <sched.h>
31
Arnaldo Carvalho de Melo02522082011-01-04 11:55:27 -020032
Jiri Olsacd82a322012-03-15 20:09:17 +010033static int test__perf_pmu(void)
34{
35 return perf_pmu__test();
36}
37
Arnaldo Carvalho de Meloeb2f2702012-09-26 13:23:10 -030038static int test__syscall_open_tp_fields(void)
39{
40 struct perf_record_opts opts = {
41 .target = {
42 .uid = UINT_MAX,
43 .uses_mmap = true,
44 },
45 .no_delay = true,
46 .freq = 1,
47 .mmap_pages = 256,
48 .raw_samples = true,
49 };
50 const char *filename = "/etc/passwd";
51 int flags = O_RDONLY | O_DIRECTORY;
52 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
53 struct perf_evsel *evsel;
54 int err = -1, i, nr_events = 0, nr_polls = 0;
55
56 if (evlist == NULL) {
57 pr_debug("%s: perf_evlist__new\n", __func__);
58 goto out;
59 }
60
61 evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
62 if (evsel == NULL) {
63 pr_debug("%s: perf_evsel__newtp\n", __func__);
64 goto out_delete_evlist;
65 }
66
67 perf_evlist__add(evlist, evsel);
68
69 err = perf_evlist__create_maps(evlist, &opts.target);
70 if (err < 0) {
71 pr_debug("%s: perf_evlist__create_maps\n", __func__);
72 goto out_delete_evlist;
73 }
74
75 perf_evsel__config(evsel, &opts, evsel);
76
77 evlist->threads->map[0] = getpid();
78
79 err = perf_evlist__open(evlist);
80 if (err < 0) {
81 pr_debug("perf_evlist__open: %s\n", strerror(errno));
82 goto out_delete_evlist;
83 }
84
85 err = perf_evlist__mmap(evlist, UINT_MAX, false);
86 if (err < 0) {
87 pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
88 goto out_delete_evlist;
89 }
90
91 perf_evlist__enable(evlist);
92
93 /*
Jiri Olsa945aea22012-10-30 23:01:43 +010094 * Generate the event:
95 */
Arnaldo Carvalho de Meloeb2f2702012-09-26 13:23:10 -030096 open(filename, flags);
97
98 while (1) {
99 int before = nr_events;
100
101 for (i = 0; i < evlist->nr_mmaps; i++) {
102 union perf_event *event;
103
104 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
105 const u32 type = event->header.type;
106 int tp_flags;
107 struct perf_sample sample;
108
109 ++nr_events;
110
111 if (type != PERF_RECORD_SAMPLE)
112 continue;
113
114 err = perf_evsel__parse_sample(evsel, event, &sample);
115 if (err) {
116 pr_err("Can't parse sample, err = %d\n", err);
117 goto out_munmap;
118 }
119
120 tp_flags = perf_evsel__intval(evsel, &sample, "flags");
121
122 if (flags != tp_flags) {
123 pr_debug("%s: Expected flags=%#x, got %#x\n",
124 __func__, flags, tp_flags);
125 goto out_munmap;
126 }
127
128 goto out_ok;
129 }
130 }
131
132 if (nr_events == before)
133 poll(evlist->pollfd, evlist->nr_fds, 10);
134
135 if (++nr_polls > 5) {
136 pr_debug("%s: no events!\n", __func__);
137 goto out_munmap;
138 }
139 }
140out_ok:
141 err = 0;
142out_munmap:
143 perf_evlist__munmap(evlist);
144out_delete_evlist:
145 perf_evlist__delete(evlist);
146out:
147 return err;
148}
149
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300150static struct test {
151 const char *desc;
152 int (*func)(void);
153} tests[] = {
154 {
155 .desc = "vmlinux symtab matches kallsyms",
156 .func = test__vmlinux_matches_kallsyms,
157 },
158 {
Arnaldo Carvalho de Melod8548612011-01-04 00:16:20 -0200159 .desc = "detect open syscall event",
160 .func = test__open_syscall_event,
161 },
162 {
Arnaldo Carvalho de Melo02522082011-01-04 11:55:27 -0200163 .desc = "detect open syscall event on all cpus",
164 .func = test__open_syscall_event_on_all_cpus,
165 },
166 {
Arnaldo Carvalho de Melode5fa3a2011-01-15 10:42:46 -0200167 .desc = "read samples using the mmap interface",
168 .func = test__basic_mmap,
169 },
170 {
Jiri Olsa13b62562011-07-14 11:25:33 +0200171 .desc = "parse events tests",
Jiri Olsaf50246e2012-05-21 09:12:49 +0200172 .func = parse_events__test,
Jiri Olsa13b62562011-07-14 11:25:33 +0200173 },
Peter Zijlstra08aa0d12011-11-21 14:42:47 +0100174#if defined(__x86_64__) || defined(__i386__)
175 {
176 .desc = "x86 rdpmc test",
177 .func = test__rdpmc,
178 },
179#endif
Jiri Olsa13b62562011-07-14 11:25:33 +0200180 {
Arnaldo Carvalho de Melo3e7c4392011-12-02 11:13:50 -0200181 .desc = "Validate PERF_RECORD_* events & perf_sample fields",
182 .func = test__PERF_RECORD,
183 },
184 {
Jiri Olsacd82a322012-03-15 20:09:17 +0100185 .desc = "Test perf pmu format parsing",
186 .func = test__perf_pmu,
187 },
188 {
Jiri Olsaf7add552012-07-22 14:14:40 +0200189 .desc = "Test dso data interface",
190 .func = dso__test_data,
191 },
192 {
Arnaldo Carvalho de Melo8ad70132012-09-06 13:11:18 -0300193 .desc = "roundtrip evsel->name check",
Jiri Olsacfffae22012-11-10 01:46:47 +0100194 .func = test__perf_evsel__roundtrip_name_test,
Arnaldo Carvalho de Melo8ad70132012-09-06 13:11:18 -0300195 },
196 {
Arnaldo Carvalho de Melo6a6cd112012-09-18 11:56:28 -0300197 .desc = "Check parsing of sched tracepoints fields",
Jiri Olsa5e24a092012-11-10 01:46:48 +0100198 .func = test__perf_evsel__tp_sched_test,
Arnaldo Carvalho de Melo6a6cd112012-09-18 11:56:28 -0300199 },
200 {
Arnaldo Carvalho de Meloeb2f2702012-09-26 13:23:10 -0300201 .desc = "Generate and check syscalls:sys_enter_open event fields",
202 .func = test__syscall_open_tp_fields,
203 },
204 {
Jiri Olsad898b242012-10-30 23:02:05 +0100205 .desc = "struct perf_event_attr setup",
206 .func = test_attr__run,
207 },
208 {
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300209 .func = NULL,
210 },
211};
212
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200213static bool perf_test__matches(int curr, int argc, const char *argv[])
214{
215 int i;
216
217 if (argc == 0)
218 return true;
219
220 for (i = 0; i < argc; ++i) {
221 char *end;
222 long nr = strtoul(argv[i], &end, 10);
223
224 if (*end == '\0') {
225 if (nr == curr + 1)
226 return true;
227 continue;
228 }
229
230 if (strstr(tests[curr].desc, argv[i]))
231 return true;
232 }
233
234 return false;
235}
236
237static int __cmd_test(int argc, const char *argv[])
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300238{
239 int i = 0;
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -0200240 int width = 0;
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300241
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300242 while (tests[i].func) {
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -0200243 int len = strlen(tests[i].desc);
244
245 if (width < len)
246 width = len;
247 ++i;
248 }
Jiri Olsa945aea22012-10-30 23:01:43 +0100249
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -0200250 i = 0;
251 while (tests[i].func) {
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200252 int curr = i++, err;
253
254 if (!perf_test__matches(curr, argc, argv))
255 continue;
256
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -0200257 pr_info("%2d: %-*s:", i, width, tests[curr].desc);
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300258 pr_debug("\n--- start ---\n");
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200259 err = tests[curr].func();
260 pr_debug("---- end ----\n%s:", tests[curr].desc);
Arnaldo Carvalho de Melo9a8e85a2012-10-24 15:44:41 -0200261 if (err)
262 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
263 else
264 pr_info(" Ok\n");
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300265 }
266
267 return 0;
268}
269
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200270static int perf_test__list(int argc, const char **argv)
271{
272 int i = 0;
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300273
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200274 while (tests[i].func) {
275 int curr = i++;
276
277 if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
278 continue;
279
280 pr_info("%2d: %s\n", i, tests[curr].desc);
281 }
282
283 return 0;
284}
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300285
Irina Tirdea1d037ca2012-09-11 01:15:03 +0300286int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300287{
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200288 const char * const test_usage[] = {
289 "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
290 NULL,
291 };
292 const struct option test_options[] = {
Namhyung Kimc30ab8a2012-01-08 02:25:26 +0900293 OPT_INCR('v', "verbose", &verbose,
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200294 "be more verbose (show symbol address, etc)"),
295 OPT_END()
296 };
297
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300298 argc = parse_options(argc, argv, test_options, test_usage, 0);
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200299 if (argc >= 1 && !strcmp(argv[0], "list"))
300 return perf_test__list(argc, argv);
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300301
302 symbol_conf.priv_size = sizeof(int);
303 symbol_conf.sort_by_name = true;
304 symbol_conf.try_vmlinux_path = true;
305
306 if (symbol__init() < 0)
307 return -1;
308
Arnaldo Carvalho de Meloe60770a2011-11-29 12:52:07 -0200309 return __cmd_test(argc, argv);
Arnaldo Carvalho de Melo1c6a8002010-04-29 18:58:32 -0300310}