Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
643cb15
Documentation
arch
block
certs
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
arch
build
cgroup
firewire
hv
iio
include
laptop
lguest
lib
net
nfsd
perf
Documentation
arch
bench
config
jvmti
python
scripts
tests
attr
.gitignore
Build
attr.c
attr.py
bp_signal.c
bp_signal_overflow.c
bpf-script-example.c
bpf-script-test-kbuild.c
bpf-script-test-prologue.c
bpf-script-test-relocation.c
bpf.c
builtin-test.c
code-reading.c
cpumap.c
dso-data.c
dwarf-unwind.c
event-times.c
event_update.c
evsel-roundtrip-name.c
evsel-tp-sched.c
fdarray.c
hists_common.c
hists_common.h
hists_cumulate.c
hists_filter.c
hists_link.c
hists_output.c
keep-tracking.c
kmod-path.c
llvm.c
llvm.h
make
mmap-basic.c
mmap-thread-lookup.c
openat-syscall-all-cpus.c
openat-syscall-tp-fields.c
openat-syscall.c
parse-events.c
parse-no-sample-id-all.c
perf-record.c
perf-targz-src-pkg
pmu.c
python-use.c
sample-parsing.c
stat.c
sw-clock.c
switch-tracking.c
task-exit.c
tests.h
thread-map.c
thread-mg-share.c
topology.c
vmlinux-kallsyms.c
trace
ui
util
.gitignore
Build
CREDITS
MANIFEST
Makefile
Makefile.perf
builtin-annotate.c
builtin-bench.c
builtin-buildid-cache.c
builtin-buildid-list.c
builtin-config.c
builtin-data.c
builtin-diff.c
builtin-evlist.c
builtin-help.c
builtin-inject.c
builtin-kmem.c
builtin-kvm.c
builtin-list.c
builtin-lock.c
builtin-mem.c
builtin-probe.c
builtin-record.c
builtin-report.c
builtin-sched.c
builtin-script.c
builtin-stat.c
builtin-timechart.c
builtin-top.c
builtin-trace.c
builtin-version.c
builtin.h
command-list.txt
design.txt
perf-archive.sh
perf-completion.sh
perf-read-vdso.c
perf-sys.h
perf-with-kcore.sh
perf.c
perf.h
power
scripts
spi
testing
thermal
time
usb
virtio
vm
Makefile
usr
virt
.get_maintainer.ignore
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
tools
/
perf
/
tests
/
builtin-test.c
Blame
Blame
Latest commit
History
History
448 lines (401 loc) · 9.15 KB
Breadcrumbs
linux
/
tools
/
perf
/
tests
/
builtin-test.c
Top
File metadata and controls
Code
Blame
448 lines (401 loc) · 9.15 KB
Raw
/* * builtin-test.c * * Builtin regression testing command: ever growing number of sanity tests */ #include <unistd.h> #include <string.h> #include "builtin.h" #include "hist.h" #include "intlist.h" #include "tests.h" #include "debug.h" #include "color.h" #include <subcmd/parse-options.h> #include "symbol.h" struct test __weak arch_tests[] = { { .func = NULL, }, }; static struct test generic_tests[] = { { .desc = "vmlinux symtab matches kallsyms", .func = test__vmlinux_matches_kallsyms, }, { .desc = "detect openat syscall event", .func = test__openat_syscall_event, }, { .desc = "detect openat syscall event on all cpus", .func = test__openat_syscall_event_on_all_cpus, }, { .desc = "read samples using the mmap interface", .func = test__basic_mmap, }, { .desc = "parse events tests", .func = test__parse_events, }, { .desc = "Validate PERF_RECORD_* events & perf_sample fields", .func = test__PERF_RECORD, }, { .desc = "Test perf pmu format parsing", .func = test__pmu, }, { .desc = "Test dso data read", .func = test__dso_data, }, { .desc = "Test dso data cache", .func = test__dso_data_cache, }, { .desc = "Test dso data reopen", .func = test__dso_data_reopen, }, { .desc = "roundtrip evsel->name check", .func = test__perf_evsel__roundtrip_name_test, }, { .desc = "Check parsing of sched tracepoints fields", .func = test__perf_evsel__tp_sched_test, }, { .desc = "Generate and check syscalls:sys_enter_openat event fields", .func = test__syscall_openat_tp_fields, }, { .desc = "struct perf_event_attr setup", .func = test__attr, }, { .desc = "Test matching and linking multiple hists", .func = test__hists_link, }, { .desc = "Try 'import perf' in python, checking link problems", .func = test__python_use, }, { .desc = "Test breakpoint overflow signal handler", .func = test__bp_signal, }, { .desc = "Test breakpoint overflow sampling", .func = test__bp_signal_overflow, }, { .desc = "Test number of exit event of a simple workload", .func = test__task_exit, }, { .desc = "Test software clock events have valid period values", .func = test__sw_clock_freq, }, { .desc = "Test object code reading", .func = test__code_reading, }, { .desc = "Test sample parsing", .func = test__sample_parsing, }, { .desc = "Test using a dummy software event to keep tracking", .func = test__keep_tracking, }, { .desc = "Test parsing with no sample_id_all bit set", .func = test__parse_no_sample_id_all, }, { .desc = "Test filtering hist entries", .func = test__hists_filter, }, { .desc = "Test mmap thread lookup", .func = test__mmap_thread_lookup, }, { .desc = "Test thread mg sharing", .func = test__thread_mg_share, }, { .desc = "Test output sorting of hist entries", .func = test__hists_output, }, { .desc = "Test cumulation of child hist entries", .func = test__hists_cumulate, }, { .desc = "Test tracking with sched_switch", .func = test__switch_tracking, }, { .desc = "Filter fds with revents mask in a fdarray", .func = test__fdarray__filter, }, { .desc = "Add fd to a fdarray, making it autogrow", .func = test__fdarray__add, }, { .desc = "Test kmod_path__parse function", .func = test__kmod_path__parse, }, { .desc = "Test thread map", .func = test__thread_map, }, { .desc = "Test LLVM searching and compiling", .func = test__llvm, .subtest = { .skip_if_fail = true, .get_nr = test__llvm_subtest_get_nr, .get_desc = test__llvm_subtest_get_desc, }, }, { .desc = "Test topology in session", .func = test_session_topology, }, { .desc = "Test BPF filter", .func = test__bpf, .subtest = { .skip_if_fail = true, .get_nr = test__bpf_subtest_get_nr, .get_desc = test__bpf_subtest_get_desc, }, }, { .desc = "Test thread map synthesize", .func = test__thread_map_synthesize, }, { .desc = "Test cpu map synthesize", .func = test__cpu_map_synthesize, }, { .desc = "Test stat config synthesize", .func = test__synthesize_stat_config, }, { .desc = "Test stat synthesize", .func = test__synthesize_stat, }, { .desc = "Test stat round synthesize", .func = test__synthesize_stat_round, }, { .desc = "Test attr update synthesize", .func = test__event_update, }, { .desc = "Test events times", .func = test__event_times, }, { .func = NULL, }, }; static struct test *tests[] = { generic_tests, arch_tests, }; static bool perf_test__matches(struct test *test, int curr, int argc, const char *argv[]) { 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; } if (strcasestr(test->desc, argv[i])) return true; } return false; } static int run_test(struct test *test, int subtest) { int status, err = -1, child = fork(); char sbuf[STRERR_BUFSIZE]; if (child < 0) { pr_err("failed to fork test: %s\n", strerror_r(errno, sbuf, sizeof(sbuf))); return -1; } if (!child) { pr_debug("test child forked, pid %d\n", getpid()); if (!verbose) { int nullfd = open("/dev/null", O_WRONLY); if (nullfd >= 0) { close(STDERR_FILENO); close(STDOUT_FILENO); dup2(nullfd, STDOUT_FILENO); dup2(STDOUT_FILENO, STDERR_FILENO); close(nullfd); } } else { signal(SIGSEGV, sighandler_dump_stack); signal(SIGFPE, sighandler_dump_stack); } err = test->func(subtest); exit(err); } wait(&status); if (WIFEXITED(status)) { err = (signed char)WEXITSTATUS(status); pr_debug("test child finished with %d\n", err); } else if (WIFSIGNALED(status)) { err = -1; pr_debug("test child interrupted\n"); } return err; } #define for_each_test(j, t) \ for (j = 0; j < ARRAY_SIZE(tests); j++) \ for (t = &tests[j][0]; t->func; t++) static int test_and_print(struct test *t, bool force_skip, int subtest) { int err; if (!force_skip) { pr_debug("\n--- start ---\n"); err = run_test(t, subtest); pr_debug("---- end ----\n"); } else { pr_debug("\n--- force skipped ---\n"); err = TEST_SKIP; } if (!t->subtest.get_nr) pr_debug("%s:", t->desc); else pr_debug("%s subtest %d:", t->desc, subtest); switch (err) { case TEST_OK: pr_info(" Ok\n"); break; case TEST_SKIP: color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n"); break; case TEST_FAIL: default: color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); break; } return err; } static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) { struct test *t; unsigned int j; int i = 0; int width = 0; for_each_test(j, t) { int len = strlen(t->desc); if (width < len) width = len; } for_each_test(j, t) { int curr = i++, err; if (!perf_test__matches(t, curr, argc, argv)) continue; pr_info("%2d: %-*s:", i, width, t->desc); if (intlist__find(skiplist, i)) { color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); continue; } if (!t->subtest.get_nr) { test_and_print(t, false, -1); } else { int subn = t->subtest.get_nr(); /* * minus 2 to align with normal testcases. * For subtest we print additional '.x' in number. * for example: * * 35: Test LLVM searching and compiling : * 35.1: Basic BPF llvm compiling test : Ok */ int subw = width > 2 ? width - 2 : width; bool skip = false; int subi; if (subn <= 0) { color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (not compiled in)\n"); continue; } pr_info("\n"); for (subi = 0; subi < subn; subi++) { int len = strlen(t->subtest.get_desc(subi)); if (subw < len) subw = len; } for (subi = 0; subi < subn; subi++) { pr_info("%2d.%1d: %-*s:", i, subi + 1, subw, t->subtest.get_desc(subi)); err = test_and_print(t, skip, subi); if (err != TEST_OK && t->subtest.skip_if_fail) skip = true; } } } return 0; } static int perf_test__list(int argc, const char **argv) { unsigned int j; struct test *t; int i = 0; for_each_test(j, t) { if (argc > 1 && !strstr(t->desc, argv[1])) continue; pr_info("%2d: %s\n", ++i, t->desc); } return 0; } int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) { const char *test_usage[] = { "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]", NULL, }; const char *skip = NULL; const struct option test_options[] = { OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), OPT_END() }; const char * const test_subcommands[] = { "list", NULL }; struct intlist *skiplist = NULL; int ret = hists__init(); if (ret < 0) return ret; argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); if (argc >= 1 && !strcmp(argv[0], "list")) return perf_test__list(argc, argv); symbol_conf.priv_size = sizeof(int); symbol_conf.sort_by_name = true; symbol_conf.try_vmlinux_path = true; if (symbol__init(NULL) < 0) return -1; if (skip != NULL) skiplist = intlist__new(skip); return __cmd_test(argc, argv, skiplist); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
You can’t perform that action at this time.