Home | History | Annotate | Download | only in tests
      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 multiple 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 		.desc = "Test breakpoint overflow signal handler",
     82 		.func = test__bp_signal,
     83 	},
     84 	{
     85 		.desc = "Test breakpoint overflow sampling",
     86 		.func = test__bp_signal_overflow,
     87 	},
     88 	{
     89 		.desc = "Test number of exit event of a simple workload",
     90 		.func = test__task_exit,
     91 	},
     92 	{
     93 		.desc = "Test software clock events have valid period values",
     94 		.func = test__sw_clock_freq,
     95 	},
     96 #if defined(__x86_64__) || defined(__i386__)
     97 	{
     98 		.desc = "Test converting perf time to TSC",
     99 		.func = test__perf_time_to_tsc,
    100 	},
    101 #endif
    102 	{
    103 		.desc = "Test object code reading",
    104 		.func = test__code_reading,
    105 	},
    106 	{
    107 		.desc = "Test sample parsing",
    108 		.func = test__sample_parsing,
    109 	},
    110 	{
    111 		.desc = "Test using a dummy software event to keep tracking",
    112 		.func = test__keep_tracking,
    113 	},
    114 	{
    115 		.desc = "Test parsing with no sample_id_all bit set",
    116 		.func = test__parse_no_sample_id_all,
    117 	},
    118 	{
    119 		.func = NULL,
    120 	},
    121 };
    122 
    123 static bool perf_test__matches(int curr, int argc, const char *argv[])
    124 {
    125 	int i;
    126 
    127 	if (argc == 0)
    128 		return true;
    129 
    130 	for (i = 0; i < argc; ++i) {
    131 		char *end;
    132 		long nr = strtoul(argv[i], &end, 10);
    133 
    134 		if (*end == '\0') {
    135 			if (nr == curr + 1)
    136 				return true;
    137 			continue;
    138 		}
    139 
    140 		if (strstr(tests[curr].desc, argv[i]))
    141 			return true;
    142 	}
    143 
    144 	return false;
    145 }
    146 
    147 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
    148 {
    149 	int i = 0;
    150 	int width = 0;
    151 
    152 	while (tests[i].func) {
    153 		int len = strlen(tests[i].desc);
    154 
    155 		if (width < len)
    156 			width = len;
    157 		++i;
    158 	}
    159 
    160 	i = 0;
    161 	while (tests[i].func) {
    162 		int curr = i++, err;
    163 
    164 		if (!perf_test__matches(curr, argc, argv))
    165 			continue;
    166 
    167 		pr_info("%2d: %-*s:", i, width, tests[curr].desc);
    168 
    169 		if (intlist__find(skiplist, i)) {
    170 			color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
    171 			continue;
    172 		}
    173 
    174 		pr_debug("\n--- start ---\n");
    175 		err = tests[curr].func();
    176 		pr_debug("---- end ----\n%s:", tests[curr].desc);
    177 
    178 		switch (err) {
    179 		case TEST_OK:
    180 			pr_info(" Ok\n");
    181 			break;
    182 		case TEST_SKIP:
    183 			color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
    184 			break;
    185 		case TEST_FAIL:
    186 		default:
    187 			color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
    188 			break;
    189 		}
    190 	}
    191 
    192 	return 0;
    193 }
    194 
    195 static int perf_test__list(int argc, const char **argv)
    196 {
    197 	int i = 0;
    198 
    199 	while (tests[i].func) {
    200 		int curr = i++;
    201 
    202 		if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
    203 			continue;
    204 
    205 		pr_info("%2d: %s\n", i, tests[curr].desc);
    206 	}
    207 
    208 	return 0;
    209 }
    210 
    211 int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
    212 {
    213 	const char * const test_usage[] = {
    214 	"perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
    215 	NULL,
    216 	};
    217 	const char *skip = NULL;
    218 	const struct option test_options[] = {
    219 	OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
    220 	OPT_INCR('v', "verbose", &verbose,
    221 		    "be more verbose (show symbol address, etc)"),
    222 	OPT_END()
    223 	};
    224 	struct intlist *skiplist = NULL;
    225 
    226 	argc = parse_options(argc, argv, test_options, test_usage, 0);
    227 	if (argc >= 1 && !strcmp(argv[0], "list"))
    228 		return perf_test__list(argc, argv);
    229 
    230 	symbol_conf.priv_size = sizeof(int);
    231 	symbol_conf.sort_by_name = true;
    232 	symbol_conf.try_vmlinux_path = true;
    233 
    234 	if (symbol__init() < 0)
    235 		return -1;
    236 
    237 	if (skip != NULL)
    238 		skiplist = intlist__new(skip);
    239 
    240 	return __cmd_test(argc, argv, skiplist);
    241 }
    242