1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Test support for libpfm4 event encodings. |
4 | * |
5 | * Copyright 2020 Google LLC. |
6 | */ |
7 | #include "tests.h" |
8 | #include "util/debug.h" |
9 | #include "util/evlist.h" |
10 | #include "util/pfm.h" |
11 | |
12 | #include <linux/kernel.h> |
13 | |
14 | #ifdef HAVE_LIBPFM |
15 | static int count_pfm_events(struct perf_evlist *evlist) |
16 | { |
17 | struct perf_evsel *evsel; |
18 | int count = 0; |
19 | |
20 | perf_evlist__for_each_entry(evlist, evsel) { |
21 | count++; |
22 | } |
23 | return count; |
24 | } |
25 | |
26 | static int test__pfm_events(struct test_suite *test __maybe_unused, |
27 | int subtest __maybe_unused) |
28 | { |
29 | struct evlist *evlist; |
30 | struct option opt; |
31 | size_t i; |
32 | const struct { |
33 | const char *events; |
34 | int nr_events; |
35 | } table[] = { |
36 | { |
37 | .events = "" , |
38 | .nr_events = 0, |
39 | }, |
40 | { |
41 | .events = "instructions" , |
42 | .nr_events = 1, |
43 | }, |
44 | { |
45 | .events = "instructions,cycles" , |
46 | .nr_events = 2, |
47 | }, |
48 | { |
49 | .events = "stereolab" , |
50 | .nr_events = 0, |
51 | }, |
52 | { |
53 | .events = "instructions,instructions" , |
54 | .nr_events = 2, |
55 | }, |
56 | { |
57 | .events = "stereolab,instructions" , |
58 | .nr_events = 0, |
59 | }, |
60 | { |
61 | .events = "instructions,stereolab" , |
62 | .nr_events = 1, |
63 | }, |
64 | }; |
65 | |
66 | for (i = 0; i < ARRAY_SIZE(table); i++) { |
67 | evlist = evlist__new(); |
68 | if (evlist == NULL) |
69 | return -ENOMEM; |
70 | |
71 | opt.value = evlist; |
72 | parse_libpfm_events_option(&opt, |
73 | table[i].events, |
74 | 0); |
75 | TEST_ASSERT_EQUAL(table[i].events, |
76 | count_pfm_events(&evlist->core), |
77 | table[i].nr_events); |
78 | TEST_ASSERT_EQUAL(table[i].events, |
79 | evlist__nr_groups(evlist), |
80 | 0); |
81 | |
82 | evlist__delete(evlist); |
83 | } |
84 | return 0; |
85 | } |
86 | |
87 | static int test__pfm_group(struct test_suite *test __maybe_unused, |
88 | int subtest __maybe_unused) |
89 | { |
90 | struct evlist *evlist; |
91 | struct option opt; |
92 | size_t i; |
93 | const struct { |
94 | const char *events; |
95 | int nr_events; |
96 | int nr_groups; |
97 | } table[] = { |
98 | { |
99 | .events = "{}," , |
100 | .nr_events = 0, |
101 | .nr_groups = 0, |
102 | }, |
103 | { |
104 | .events = "{instructions}" , |
105 | .nr_events = 1, |
106 | .nr_groups = 0, |
107 | }, |
108 | { |
109 | .events = "{instructions},{}" , |
110 | .nr_events = 1, |
111 | .nr_groups = 0, |
112 | }, |
113 | { |
114 | .events = "{},{instructions}" , |
115 | .nr_events = 1, |
116 | .nr_groups = 0, |
117 | }, |
118 | { |
119 | .events = "{instructions},{instructions}" , |
120 | .nr_events = 2, |
121 | .nr_groups = 0, |
122 | }, |
123 | { |
124 | .events = "{instructions,cycles},{instructions,cycles}" , |
125 | .nr_events = 4, |
126 | .nr_groups = 2, |
127 | }, |
128 | { |
129 | .events = "{stereolab}" , |
130 | .nr_events = 0, |
131 | .nr_groups = 0, |
132 | }, |
133 | { |
134 | .events = |
135 | "{instructions,cycles},{instructions,stereolab}" , |
136 | .nr_events = 3, |
137 | .nr_groups = 1, |
138 | }, |
139 | { |
140 | .events = "instructions}" , |
141 | .nr_events = 1, |
142 | .nr_groups = 0, |
143 | }, |
144 | { |
145 | .events = "{{instructions}}" , |
146 | .nr_events = 0, |
147 | .nr_groups = 0, |
148 | }, |
149 | }; |
150 | |
151 | for (i = 0; i < ARRAY_SIZE(table); i++) { |
152 | evlist = evlist__new(); |
153 | if (evlist == NULL) |
154 | return -ENOMEM; |
155 | |
156 | opt.value = evlist; |
157 | parse_libpfm_events_option(&opt, |
158 | table[i].events, |
159 | 0); |
160 | TEST_ASSERT_EQUAL(table[i].events, |
161 | count_pfm_events(&evlist->core), |
162 | table[i].nr_events); |
163 | TEST_ASSERT_EQUAL(table[i].events, |
164 | evlist__nr_groups(evlist), |
165 | table[i].nr_groups); |
166 | |
167 | evlist__delete(evlist); |
168 | } |
169 | return 0; |
170 | } |
171 | #else |
172 | static int test__pfm_events(struct test_suite *test __maybe_unused, |
173 | int subtest __maybe_unused) |
174 | { |
175 | return TEST_SKIP; |
176 | } |
177 | |
178 | static int test__pfm_group(struct test_suite *test __maybe_unused, |
179 | int subtest __maybe_unused) |
180 | { |
181 | return TEST_SKIP; |
182 | } |
183 | #endif |
184 | |
185 | static struct test_case pfm_tests[] = { |
186 | TEST_CASE_REASON("test of individual --pfm-events" , pfm_events, "not compiled in" ), |
187 | TEST_CASE_REASON("test groups of --pfm-events" , pfm_group, "not compiled in" ), |
188 | { .name = NULL, } |
189 | }; |
190 | |
191 | struct test_suite suite__pfm = { |
192 | .desc = "Test libpfm4 support" , |
193 | .test_cases = pfm_tests, |
194 | }; |
195 | |