builtin-test.c 3.7 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * builtin-test.c
 *
 * Builtin regression testing command: ever growing number of sanity tests
 */
#include "builtin.h"

#include "util/cache.h"
9
#include "util/color.h"
10
#include "util/debug.h"
11
#include "util/debugfs.h"
12
#include "util/evlist.h"
13
#include "util/machine.h"
14
#include "util/parse-options.h"
15
#include "util/parse-events.h"
16
#include "util/symbol.h"
17
#include "util/thread_map.h"
18
#include "util/pmu.h"
19
#include "event-parse.h"
20
#include "../../include/linux/hw_breakpoint.h"
21

22 23
#include <sys/mman.h>

24
#include "util/cpumap.h"
25 26 27
#include "util/evsel.h"
#include <sys/types.h>

28 29
#include "tests.h"

30 31 32
#include <sched.h>


33 34 35 36 37 38 39 40
static struct test {
	const char *desc;
	int (*func)(void);
} tests[] = {
	{
		.desc = "vmlinux symtab matches kallsyms",
		.func = test__vmlinux_matches_kallsyms,
	},
41 42 43 44
	{
		.desc = "detect open syscall event",
		.func = test__open_syscall_event,
	},
45 46 47 48
	{
		.desc = "detect open syscall event on all cpus",
		.func = test__open_syscall_event_on_all_cpus,
	},
49 50 51 52
	{
		.desc = "read samples using the mmap interface",
		.func = test__basic_mmap,
	},
53 54
	{
		.desc = "parse events tests",
55
		.func = parse_events__test,
56
	},
57 58 59 60 61 62
#if defined(__x86_64__) || defined(__i386__)
	{
		.desc = "x86 rdpmc test",
		.func = test__rdpmc,
	},
#endif
63 64 65 66
	{
		.desc = "Validate PERF_RECORD_* events & perf_sample fields",
		.func = test__PERF_RECORD,
	},
67 68
	{
		.desc = "Test perf pmu format parsing",
69
		.func = test__pmu,
70
	},
71 72 73 74
	{
		.desc = "Test dso data interface",
		.func = dso__test_data,
	},
75 76
	{
		.desc = "roundtrip evsel->name check",
77
		.func = test__perf_evsel__roundtrip_name_test,
78
	},
79 80
	{
		.desc = "Check parsing of sched tracepoints fields",
81
		.func = test__perf_evsel__tp_sched_test,
82
	},
83 84 85 86
	{
		.desc = "Generate and check syscalls:sys_enter_open event fields",
		.func = test__syscall_open_tp_fields,
	},
87 88 89 90
	{
		.desc = "struct perf_event_attr setup",
		.func = test_attr__run,
	},
91 92 93 94 95
	{
		.func = NULL,
	},
};

96
static bool perf_test__matches(int curr, int argc, const char *argv[])
97
{
98 99 100 101 102 103 104 105 106 107 108 109 110 111
	int i;

	if (argc == 0)
		return true;

	for (i = 0; i < argc; ++i) {
		char *end;
		long nr = strtoul(argv[i], &end, 10);

		if (*end == '\0') {
			if (nr == curr + 1)
				return true;
			continue;
		}
112

113 114 115 116 117 118 119 120 121 122
		if (strstr(tests[curr].desc, argv[i]))
			return true;
	}

	return false;
}

static int __cmd_test(int argc, const char *argv[])
{
	int i = 0;
123
	int width = 0;
124

125 126 127 128 129 130 131
	while (tests[i].func) {
		int len = strlen(tests[i].desc);

		if (width < len)
			width = len;
		++i;
	}
132

133
	i = 0;
134
	while (tests[i].func) {
135 136 137 138 139
		int curr = i++, err;

		if (!perf_test__matches(curr, argc, argv))
			continue;

140
		pr_info("%2d: %-*s:", i, width, tests[curr].desc);
141
		pr_debug("\n--- start ---\n");
142 143
		err = tests[curr].func();
		pr_debug("---- end ----\n%s:", tests[curr].desc);
144 145 146 147
		if (err)
			color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
		else
			pr_info(" Ok\n");
148 149 150 151 152
	}

	return 0;
}

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
static int perf_test__list(int argc, const char **argv)
{
	int i = 0;

	while (tests[i].func) {
		int curr = i++;

		if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
			continue;

		pr_info("%2d: %s\n", i, tests[curr].desc);
	}

	return 0;
}
168

169
int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
170 171 172 173 174 175
{
	const char * const test_usage[] = {
	"perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
	NULL,
	};
	const struct option test_options[] = {
176
	OPT_INCR('v', "verbose", &verbose,
177 178
		    "be more verbose (show symbol address, etc)"),
	OPT_END()
179
	};
180 181

	argc = parse_options(argc, argv, test_options, test_usage, 0);
182 183
	if (argc >= 1 && !strcmp(argv[0], "list"))
		return perf_test__list(argc, argv);
184 185 186 187 188 189 190 191

	symbol_conf.priv_size = sizeof(int);
	symbol_conf.sort_by_name = true;
	symbol_conf.try_vmlinux_path = true;

	if (symbol__init() < 0)
		return -1;

192
	return __cmd_test(argc, argv);
193
}