projects/linux·blob master · refs

646 lines · 18.8 KiB

1// SPDX-License-Identifier: GPL-2.0
2#include "evlist.h"
3#include "evsel.h"
4#include "parse-events.h"
5#include "pmu.h"
6#include "pmus.h"
7#include "tests.h"
8#include "debug.h"
9#include "fncache.h"
10#include <api/fs/fs.h>
11#include <ctype.h>
12#include <dirent.h>
13#include <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h>
18#include <sys/stat.h>
19#include <sys/types.h>
20
21/* Cleanup test PMU directory. */
22static int test_pmu_put(const char *dir, struct perf_pmu *pmu)
23{
24 char buf[PATH_MAX + 20];
25 int ret;
26
27 if (scnprintf(buf, sizeof(buf), "rm -fr %s", dir) < 0) {
28 pr_err("Failure to set up buffer for \"%s\"\n", dir);
29 return -EINVAL;
30 }
31 ret = system(buf);
32 if (ret)
33 pr_err("Failure to \"%s\"\n", buf);
34
35 list_del(&pmu->list);
36 perf_pmu__delete(pmu);
37 return ret;
38}
39
40/*
41 * Prepare test PMU directory data, normally exported by kernel at
42 * /sys/bus/event_source/devices/<pmu>/. Give as input a buffer to hold the file
43 * path, the result is PMU loaded using that directory.
44 */
45static struct perf_pmu *test_pmu_get(char *dir, size_t sz)
46{
47 /* Simulated format definitions. */
48 const struct test_format {
49 const char *name;
50 const char *value;
51 } test_formats[] = {
52 { "krava01", "config:0-1,62-63\n", },
53 { "krava02", "config:10-17\n", },
54 { "krava03", "config:5\n", },
55 { "krava11", "config1:0,2,4,6,8,20-28\n", },
56 { "krava12", "config1:63\n", },
57 { "krava13", "config1:45-47\n", },
58 { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
59 { "krava22", "config2:8,18,48,58\n", },
60 { "krava23", "config2:28-29,38\n", },
61 };
62 const char *test_event = "krava01=15,krava02=170,krava03=1,krava11=27,krava12=1,"
63 "krava13=2,krava21=119,krava22=11,krava23=2\n";
64
65 char name[PATH_MAX];
66 int dirfd, file;
67 struct perf_pmu *pmu = NULL;
68 ssize_t len;
69
70 /* Create equivalent of sysfs mount point. */
71 scnprintf(dir, sz, "/tmp/perf-pmu-test-XXXXXX");
72 if (!mkdtemp(dir)) {
73 pr_err("mkdtemp failed\n");
74 dir[0] = '\0';
75 return NULL;
76 }
77 dirfd = open(dir, O_DIRECTORY);
78 if (dirfd < 0) {
79 pr_err("Failed to open test directory \"%s\"\n", dir);
80 goto err_out;
81 }
82
83 /* Create the test PMU directory and give it a perf_event_attr type number. */
84 if (mkdirat(dirfd, "perf-pmu-test", 0755) < 0) {
85 pr_err("Failed to mkdir PMU directory\n");
86 goto err_out;
87 }
88 file = openat(dirfd, "perf-pmu-test/type", O_WRONLY | O_CREAT, 0600);
89 if (!file) {
90 pr_err("Failed to open for writing file \"type\"\n");
91 goto err_out;
92 }
93 len = strlen("9999");
94 if (write(file, "9999\n", len) < len) {
95 close(file);
96 pr_err("Failed to write to 'type' file\n");
97 goto err_out;
98 }
99 close(file);
100
101 /* Create format directory and files. */
102 if (mkdirat(dirfd, "perf-pmu-test/format", 0755) < 0) {
103 pr_err("Failed to mkdir PMU format directory\n)");
104 goto err_out;
105 }
106 for (size_t i = 0; i < ARRAY_SIZE(test_formats); i++) {
107 const struct test_format *format = &test_formats[i];
108
109 if (scnprintf(name, PATH_MAX, "perf-pmu-test/format/%s", format->name) < 0) {
110 pr_err("Failure to set up path for \"%s\"\n", format->name);
111 goto err_out;
112 }
113 file = openat(dirfd, name, O_WRONLY | O_CREAT, 0600);
114 if (!file) {
115 pr_err("Failed to open for writing file \"%s\"\n", name);
116 goto err_out;
117 }
118
119 if (write(file, format->value, strlen(format->value)) < 0) {
120 pr_err("Failed to write to file \"%s\"\n", name);
121 close(file);
122 goto err_out;
123 }
124 close(file);
125 }
126
127 /* Create test event. */
128 if (mkdirat(dirfd, "perf-pmu-test/events", 0755) < 0) {
129 pr_err("Failed to mkdir PMU events directory\n");
130 goto err_out;
131 }
132 file = openat(dirfd, "perf-pmu-test/events/test-event", O_WRONLY | O_CREAT, 0600);
133 if (!file) {
134 pr_err("Failed to open for writing file \"type\"\n");
135 goto err_out;
136 }
137 len = strlen(test_event);
138 if (write(file, test_event, len) < len) {
139 close(file);
140 pr_err("Failed to write to 'test-event' file\n");
141 goto err_out;
142 }
143 close(file);
144
145 /* Make the PMU reading the files created above. */
146 pmu = perf_pmus__add_test_pmu(dirfd, "perf-pmu-test");
147 if (!pmu)
148 pr_err("Test PMU creation failed\n");
149
150err_out:
151 if (!pmu)
152 test_pmu_put(dir, pmu);
153 if (dirfd >= 0)
154 close(dirfd);
155 return pmu;
156}
157
158static int test__pmu_format(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
159{
160 char dir[PATH_MAX];
161 struct perf_event_attr attr;
162 struct parse_events_terms terms;
163 int ret = TEST_FAIL;
164 struct perf_pmu *pmu = test_pmu_get(dir, sizeof(dir));
165
166 if (!pmu)
167 return TEST_FAIL;
168
169 parse_events_terms__init(&terms);
170 if (parse_events_terms(&terms,
171 "krava01=15,krava02=170,krava03=1,krava11=27,krava12=1,"
172 "krava13=2,krava21=119,krava22=11,krava23=2")) {
173 pr_err("Term parsing failed\n");
174 goto err_out;
175 }
176
177 memset(&attr, 0, sizeof(attr));
178 ret = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/false,
179 /*apply_hardcoded=*/false, /*err=*/NULL);
180 if (ret) {
181 pr_err("perf_pmu__config_terms failed");
182 goto err_out;
183 }
184
185 if (attr.config != 0xc00000000002a823) {
186 pr_err("Unexpected config value %llx\n", attr.config);
187 goto err_out;
188 }
189 if (attr.config1 != 0x8000400000000145) {
190 pr_err("Unexpected config1 value %llx\n", attr.config1);
191 goto err_out;
192 }
193 if (attr.config2 != 0x0400000020041d07) {
194 pr_err("Unexpected config2 value %llx\n", attr.config2);
195 }
196
197 ret = TEST_OK;
198err_out:
199 parse_events_terms__exit(&terms);
200 test_pmu_put(dir, pmu);
201 return ret;
202}
203
204static int test__pmu_config_helpers(struct test_suite *test __maybe_unused,
205 int subtest __maybe_unused)
206{
207 const char *event = "perf-pmu-test/config=15,config1=4,krava02=170,"
208 "krava03=1,krava11=27,krava12=1/";
209 struct parse_events_terms terms;
210 struct parse_events_error err;
211 LIST_HEAD(config_terms);
212 struct evlist *evlist;
213 struct perf_pmu *pmu;
214 struct evsel *evsel;
215 int ret = TEST_FAIL;
216 char dir[PATH_MAX];
217 u64 val;
218
219 pmu = test_pmu_get(dir, sizeof(dir));
220 if (!pmu)
221 return TEST_FAIL;
222
223 evlist = evlist__new();
224 if (evlist == NULL) {
225 pr_err("Failed allocation");
226 goto err_out;
227 }
228
229 parse_events_terms__init(&terms);
230 ret = parse_events(evlist, event, &err);
231 if (ret) {
232 pr_debug("failed to parse event '%s', err %d\n", event, ret);
233 parse_events_error__print(&err, event);
234 if (parse_events_error__contains(&err, "can't access trace events"))
235 ret = TEST_SKIP;
236 goto err_out;
237 }
238 evsel = evlist__first(evlist);
239
240 /* Test evsel__config_exists() */
241 TEST_ASSERT_EQUAL("krava01 should exist",
242 evsel__config_exists(evsel, "krava01"), true);
243 TEST_ASSERT_EQUAL("krava99 should not exist",
244 evsel__config_exists(evsel, "krava99"), false);
245
246 /*
247 * Set via config=15, krava01 bits 0-1
248 * Set via config1=4, krava11 bit 1
249 * Set values: krava02=170, krava03=1, krava11=27, krava12=1
250 *
251 * Test that already set values aren't overwritten.
252 */
253 evsel__set_config_if_unset(evsel, "krava01", 16);
254 evsel__get_config_val(evsel, "krava01", &val);
255 TEST_ASSERT_EQUAL("krava01 overwritten", (int) val, (15 & 0b11));
256
257 evsel__set_config_if_unset(evsel, "krava11", 45);
258 evsel__get_config_val(evsel, "krava11", &val);
259 TEST_ASSERT_EQUAL("krava11 overwritten", (int) val, (27 | (4 << 1)));
260
261 evsel__set_config_if_unset(evsel, "krava02", 32);
262 evsel__get_config_val(evsel, "krava02", &val);
263 TEST_ASSERT_EQUAL("krava02 overwritten", (int) val, 170);
264
265 evsel__set_config_if_unset(evsel, "krava03", 0);
266 evsel__get_config_val(evsel, "krava03", &val);
267 TEST_ASSERT_EQUAL("krava03 overwritten", (int) val, 1);
268
269 /*
270 * krava13 doesn't have any bits set by either krava13= or config1=
271 * but setting _any_ raw value for config1 implies that krava13
272 * shouldn't be overwritten. So it's value should remain as 0.
273 */
274 evsel__set_config_if_unset(evsel, "krava13", 5);
275 evsel__get_config_val(evsel, "krava13", &val);
276 TEST_ASSERT_EQUAL("krava13 overwritten", (int) val, 0);
277
278 /*
279 * Unset values: krava21, krava22, krava23
280 *
281 * Test that unset values are overwritten.
282 */
283 evsel__set_config_if_unset(evsel, "krava21", 13905);
284 evsel__get_config_val(evsel, "krava21", &val);
285 TEST_ASSERT_EQUAL("krava21 not overwritten", (int) val, 13905);
286
287 evsel__set_config_if_unset(evsel, "krava22", 11);
288 evsel__get_config_val(evsel, "krava22", &val);
289 TEST_ASSERT_EQUAL("krava22 not overwritten", (int) val, 11);
290
291 evsel__set_config_if_unset(evsel, "krava23", 0);
292 evsel__get_config_val(evsel, "krava23", &val);
293 TEST_ASSERT_EQUAL("krava23 not overwritten", (int) val, 0);
294 ret = TEST_OK;
295err_out:
296 parse_events_terms__exit(&terms);
297 evlist__put(evlist);
298 test_pmu_put(dir, pmu);
299 return ret;
300}
301
302static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
303{
304 char dir[PATH_MAX];
305 struct parse_events_error err;
306 struct evlist *evlist;
307 struct evsel *evsel;
308 struct perf_event_attr *attr;
309 int ret = TEST_FAIL;
310 struct perf_pmu *pmu = test_pmu_get(dir, sizeof(dir));
311 const char *event = "perf-pmu-test/test-event/";
312
313
314 if (!pmu)
315 return TEST_FAIL;
316
317 evlist = evlist__new();
318 if (evlist == NULL) {
319 pr_err("Failed allocation");
320 goto err_out;
321 }
322 parse_events_error__init(&err);
323 ret = parse_events(evlist, event, &err);
324 if (ret) {
325 pr_debug("failed to parse event '%s', err %d\n", event, ret);
326 parse_events_error__print(&err, event);
327 if (parse_events_error__contains(&err, "can't access trace events"))
328 ret = TEST_SKIP;
329 goto err_out;
330 }
331 evsel = evlist__first(evlist);
332 attr = &evsel->core.attr;
333 if (attr->config != 0xc00000000002a823) {
334 pr_err("Unexpected config value %llx\n", attr->config);
335 goto err_out;
336 }
337 if (attr->config1 != 0x8000400000000145) {
338 pr_err("Unexpected config1 value %llx\n", attr->config1);
339 goto err_out;
340 }
341 if (attr->config2 != 0x0400000020041d07) {
342 pr_err("Unexpected config2 value %llx\n", attr->config2);
343 goto err_out;
344 }
345
346 ret = TEST_OK;
347err_out:
348 parse_events_error__exit(&err);
349 evlist__put(evlist);
350 test_pmu_put(dir, pmu);
351 return ret;
352}
353
354static bool permitted_event_name(const char *name)
355{
356 bool has_lower = false, has_upper = false;
357 __u64 config;
358
359 for (size_t i = 0; i < strlen(name); i++) {
360 char c = name[i];
361
362 if (islower(c)) {
363 if (has_upper)
364 goto check_legacy;
365 has_lower = true;
366 continue;
367 }
368 if (isupper(c)) {
369 if (has_lower)
370 goto check_legacy;
371 has_upper = true;
372 continue;
373 }
374 if (!isdigit(c) && c != '.' && c != '_' && c != '-')
375 goto check_legacy;
376 }
377 return true;
378check_legacy:
379 /*
380 * If the event name matches a legacy cache name the legacy encoding
381 * will still be used. This isn't quite WAI as sysfs events should take
382 * priority, but this case happens on PowerPC and matches the behavior
383 * in older perf tools where legacy events were the priority. Be
384 * permissive and assume later PMU drivers will use all lower or upper
385 * case names.
386 */
387 if (parse_events__decode_legacy_cache(name, /*extended_pmu_type=*/0, &config) == 0) {
388 pr_warning("sysfs event '%s' should be all lower/upper case, it will be matched using legacy encoding.",
389 name);
390 return true;
391 }
392 return false;
393}
394
395static int test__pmu_event_names(struct test_suite *test __maybe_unused,
396 int subtest __maybe_unused)
397{
398 char path[PATH_MAX];
399 DIR *pmu_dir, *event_dir;
400 struct dirent *pmu_dent, *event_dent;
401 const char *sysfs = sysfs__mountpoint();
402 int ret = TEST_OK;
403
404 if (!sysfs) {
405 pr_err("Sysfs not mounted\n");
406 return TEST_FAIL;
407 }
408
409 snprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);
410 pmu_dir = opendir(path);
411 if (!pmu_dir) {
412 pr_err("Error opening \"%s\"\n", path);
413 return TEST_FAIL;
414 }
415 while ((pmu_dent = readdir(pmu_dir))) {
416 if (!strcmp(pmu_dent->d_name, ".") ||
417 !strcmp(pmu_dent->d_name, ".."))
418 continue;
419
420 snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/type",
421 sysfs, pmu_dent->d_name);
422
423 /* Does it look like a PMU? */
424 if (!file_available(path))
425 continue;
426
427 /* Process events. */
428 snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/events",
429 sysfs, pmu_dent->d_name);
430
431 event_dir = opendir(path);
432 if (!event_dir) {
433 pr_debug("Skipping as no event directory \"%s\"\n", path);
434 continue;
435 }
436 while ((event_dent = readdir(event_dir))) {
437 const char *event_name = event_dent->d_name;
438
439 if (!strcmp(event_name, ".") || !strcmp(event_name, ".."))
440 continue;
441
442 if (!permitted_event_name(event_name)) {
443 pr_err("Invalid sysfs event name: %s/%s\n",
444 pmu_dent->d_name, event_name);
445 ret = TEST_FAIL;
446 }
447 }
448 closedir(event_dir);
449 }
450 closedir(pmu_dir);
451 return ret;
452}
453
454static const char * const uncore_chas[] = {
455 "uncore_cha_0",
456 "uncore_cha_1",
457 "uncore_cha_2",
458 "uncore_cha_3",
459 "uncore_cha_4",
460 "uncore_cha_5",
461 "uncore_cha_6",
462 "uncore_cha_7",
463 "uncore_cha_8",
464 "uncore_cha_9",
465 "uncore_cha_10",
466 "uncore_cha_11",
467 "uncore_cha_12",
468 "uncore_cha_13",
469 "uncore_cha_14",
470 "uncore_cha_15",
471 "uncore_cha_16",
472 "uncore_cha_17",
473 "uncore_cha_18",
474 "uncore_cha_19",
475 "uncore_cha_20",
476 "uncore_cha_21",
477 "uncore_cha_22",
478 "uncore_cha_23",
479 "uncore_cha_24",
480 "uncore_cha_25",
481 "uncore_cha_26",
482 "uncore_cha_27",
483 "uncore_cha_28",
484 "uncore_cha_29",
485 "uncore_cha_30",
486 "uncore_cha_31",
487};
488
489static const char * const mrvl_ddrs[] = {
490 "mrvl_ddr_pmu_87e1b0000000",
491 "mrvl_ddr_pmu_87e1b1000000",
492 "mrvl_ddr_pmu_87e1b2000000",
493 "mrvl_ddr_pmu_87e1b3000000",
494 "mrvl_ddr_pmu_87e1b4000000",
495 "mrvl_ddr_pmu_87e1b5000000",
496 "mrvl_ddr_pmu_87e1b6000000",
497 "mrvl_ddr_pmu_87e1b7000000",
498 "mrvl_ddr_pmu_87e1b8000000",
499 "mrvl_ddr_pmu_87e1b9000000",
500 "mrvl_ddr_pmu_87e1ba000000",
501 "mrvl_ddr_pmu_87e1bb000000",
502 "mrvl_ddr_pmu_87e1bc000000",
503 "mrvl_ddr_pmu_87e1bd000000",
504 "mrvl_ddr_pmu_87e1be000000",
505 "mrvl_ddr_pmu_87e1bf000000",
506};
507
508static int test__name_len(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
509{
510 TEST_ASSERT_VAL("cpu", pmu_name_len_no_suffix("cpu") == strlen("cpu"));
511 TEST_ASSERT_VAL("i915", pmu_name_len_no_suffix("i915") == strlen("i915"));
512 TEST_ASSERT_VAL("cpum_cf", pmu_name_len_no_suffix("cpum_cf") == strlen("cpum_cf"));
513 for (size_t i = 0; i < ARRAY_SIZE(uncore_chas); i++) {
514 TEST_ASSERT_VAL("Strips uncore_cha suffix",
515 pmu_name_len_no_suffix(uncore_chas[i]) ==
516 strlen("uncore_cha"));
517 }
518 for (size_t i = 0; i < ARRAY_SIZE(mrvl_ddrs); i++) {
519 TEST_ASSERT_VAL("Strips mrvl_ddr_pmu suffix",
520 pmu_name_len_no_suffix(mrvl_ddrs[i]) ==
521 strlen("mrvl_ddr_pmu"));
522 }
523 return TEST_OK;
524}
525
526static int test__name_cmp(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
527{
528 TEST_ASSERT_EQUAL("cpu", pmu_name_cmp("cpu", "cpu"), 0);
529 TEST_ASSERT_EQUAL("i915", pmu_name_cmp("i915", "i915"), 0);
530 TEST_ASSERT_EQUAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_cf"), 0);
531 TEST_ASSERT_VAL("i915", pmu_name_cmp("cpu", "i915") < 0);
532 TEST_ASSERT_VAL("i915", pmu_name_cmp("i915", "cpu") > 0);
533 TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_ce") > 0);
534 TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_d0") < 0);
535 for (size_t i = 1; i < ARRAY_SIZE(uncore_chas); i++) {
536 TEST_ASSERT_VAL("uncore_cha suffixes ordered lt",
537 pmu_name_cmp(uncore_chas[i-1], uncore_chas[i]) < 0);
538 TEST_ASSERT_VAL("uncore_cha suffixes ordered gt",
539 pmu_name_cmp(uncore_chas[i], uncore_chas[i-1]) > 0);
540 }
541 for (size_t i = 1; i < ARRAY_SIZE(mrvl_ddrs); i++) {
542 TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered lt",
543 pmu_name_cmp(mrvl_ddrs[i-1], mrvl_ddrs[i]) < 0);
544 TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered gt",
545 pmu_name_cmp(mrvl_ddrs[i], mrvl_ddrs[i-1]) > 0);
546 }
547 return TEST_OK;
548}
549
550/**
551 * Test perf_pmu__wildcard_match() that's used to search for a PMU given a name passed
552 * on the command line. The name that's passed may also be a filename type glob
553 * match. If the name does not match, perf_pmu__wildcard_match() attempts to match the
554 * alias of the PMU, if provided.
555 */
556static int test__pmu_match(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
557{
558 struct perf_pmu test_pmu = {
559 .name = "pmuname",
560 };
561
562#define TEST_PMU_MATCH(msg, to_match, expect) \
563 TEST_ASSERT_EQUAL(msg, perf_pmu__wildcard_match(&test_pmu, to_match), expect)
564
565 TEST_PMU_MATCH("Exact match", "pmuname", true);
566 TEST_PMU_MATCH("Longer token", "longertoken", false);
567 TEST_PMU_MATCH("Shorter token", "pmu", false);
568
569 test_pmu.name = "pmuname_10";
570 TEST_PMU_MATCH("Diff suffix_", "pmuname_2", false);
571 TEST_PMU_MATCH("Sub suffix_", "pmuname_1", true);
572 TEST_PMU_MATCH("Same suffix_", "pmuname_10", true);
573 TEST_PMU_MATCH("No suffix_", "pmuname", true);
574 TEST_PMU_MATCH("Underscore_", "pmuname_", true);
575 TEST_PMU_MATCH("Substring_", "pmuna", false);
576
577 test_pmu.name = "pmuname_ab23";
578 TEST_PMU_MATCH("Diff suffix hex_", "pmuname_2", false);
579 TEST_PMU_MATCH("Sub suffix hex_", "pmuname_ab", true);
580 TEST_PMU_MATCH("Same suffix hex_", "pmuname_ab23", true);
581 TEST_PMU_MATCH("No suffix hex_", "pmuname", true);
582 TEST_PMU_MATCH("Underscore hex_", "pmuname_", true);
583 TEST_PMU_MATCH("Substring hex_", "pmuna", false);
584
585 test_pmu.name = "pmuname10";
586 TEST_PMU_MATCH("Diff suffix", "pmuname2", false);
587 TEST_PMU_MATCH("Sub suffix", "pmuname1", true);
588 TEST_PMU_MATCH("Same suffix", "pmuname10", true);
589 TEST_PMU_MATCH("No suffix", "pmuname", true);
590 TEST_PMU_MATCH("Underscore", "pmuname_", false);
591 TEST_PMU_MATCH("Substring", "pmuna", false);
592
593 test_pmu.name = "pmunameab23";
594 TEST_PMU_MATCH("Diff suffix hex", "pmuname2", false);
595 TEST_PMU_MATCH("Sub suffix hex", "pmunameab", true);
596 TEST_PMU_MATCH("Same suffix hex", "pmunameab23", true);
597 TEST_PMU_MATCH("No suffix hex", "pmuname", true);
598 TEST_PMU_MATCH("Underscore hex", "pmuname_", false);
599 TEST_PMU_MATCH("Substring hex", "pmuna", false);
600
601 /*
602 * 2 hex chars or less are not considered suffixes so it shouldn't be
603 * possible to wildcard by skipping the suffix. Therefore there are more
604 * false results here than above.
605 */
606 test_pmu.name = "pmuname_a3";
607 TEST_PMU_MATCH("Diff suffix 2 hex_", "pmuname_2", false);
608 /*
609 * This one should be false, but because pmuname_a3 ends in 3 which is
610 * decimal, it's not possible to determine if it's a short hex suffix or
611 * a normal decimal suffix following text. And we want to match on any
612 * length of decimal suffix. Run the test anyway and expect the wrong
613 * result. And slightly fuzzy matching shouldn't do too much harm.
614 */
615 TEST_PMU_MATCH("Sub suffix 2 hex_", "pmuname_a", true);
616 TEST_PMU_MATCH("Same suffix 2 hex_", "pmuname_a3", true);
617 TEST_PMU_MATCH("No suffix 2 hex_", "pmuname", false);
618 TEST_PMU_MATCH("Underscore 2 hex_", "pmuname_", false);
619 TEST_PMU_MATCH("Substring 2 hex_", "pmuna", false);
620
621 test_pmu.name = "pmuname_5";
622 TEST_PMU_MATCH("Glob 1", "pmu*", true);
623 TEST_PMU_MATCH("Glob 2", "nomatch*", false);
624 TEST_PMU_MATCH("Seq 1", "pmuname_[12345]", true);
625 TEST_PMU_MATCH("Seq 2", "pmuname_[67890]", false);
626 TEST_PMU_MATCH("? 1", "pmuname_?", true);
627 TEST_PMU_MATCH("? 2", "pmuname_1?", false);
628
629 return TEST_OK;
630}
631
632static struct test_case tests__pmu[] = {
633 TEST_CASE("Parsing with PMU format directory", pmu_format),
634 TEST_CASE("Parsing with PMU event", pmu_events),
635 TEST_CASE("PMU event names", pmu_event_names),
636 TEST_CASE("PMU name combining", name_len),
637 TEST_CASE("PMU name comparison", name_cmp),
638 TEST_CASE("PMU cmdline match", pmu_match),
639 TEST_CASE("PMU config helpers", pmu_config_helpers),
640 { .name = NULL, }
641};
642
643struct test_suite suite__pmu = {
644 .desc = "Sysfs PMU tests",
645 .test_cases = tests__pmu,
646};