1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 #include "debug.h" 3 #include "evlist.h" 4 #include "parse-events.h" 5 #include "tests.h" 6 #include "tool_pmu.h" 7 8 static int do_test(enum tool_pmu_event ev, bool with_pmu) 9 { 10 struct evlist *evlist = evlist__new(); 11 struct evsel *evsel; 12 struct parse_events_error err; 13 int ret; 14 char str[128]; 15 bool found = false; 16 17 if (!evlist) { 18 pr_err("evlist allocation failed\n"); 19 return TEST_FAIL; 20 } 21 22 if (with_pmu) 23 snprintf(str, sizeof(str), "tool/%s/", tool_pmu__event_to_str(ev)); 24 else 25 snprintf(str, sizeof(str), "%s", tool_pmu__event_to_str(ev)); 26 27 parse_events_error__init(&err); 28 ret = parse_events(evlist, str, &err); 29 if (ret) { 30 if (tool_pmu__skip_event(tool_pmu__event_to_str(ev))) { 31 ret = TEST_OK; 32 goto out; 33 } 34 35 pr_debug("FAILED %s:%d failed to parse event '%s', err %d\n", 36 __FILE__, __LINE__, str, ret); 37 parse_events_error__print(&err, str); 38 ret = TEST_FAIL; 39 goto out; 40 } 41 42 ret = TEST_OK; 43 if (with_pmu ? (evlist->core.nr_entries != 1) : (evlist->core.nr_entries < 1)) { 44 pr_debug("FAILED %s:%d Unexpected number of events for '%s' of %d\n", 45 __FILE__, __LINE__, str, evlist->core.nr_entries); 46 ret = TEST_FAIL; 47 goto out; 48 } 49 50 evlist__for_each_entry(evlist, evsel) { 51 if (perf_pmu__is_tool(evsel->pmu)) { 52 if (evsel->core.attr.config != ev) { 53 pr_debug("FAILED %s:%d Unexpected config for '%s', %lld != %d\n", 54 __FILE__, __LINE__, str, evsel->core.attr.config, ev); 55 ret = TEST_FAIL; 56 goto out; 57 } 58 found = true; 59 } 60 } 61 62 if (!found && !tool_pmu__skip_event(tool_pmu__event_to_str(ev))) { 63 pr_debug("FAILED %s:%d Didn't find tool event '%s' in parsed evsels\n", 64 __FILE__, __LINE__, str); 65 ret = TEST_FAIL; 66 } 67 68 out: 69 evlist__delete(evlist); 70 return ret; 71 } 72 73 static int test__tool_pmu_without_pmu(struct test_suite *test __maybe_unused, 74 int subtest __maybe_unused) 75 { 76 int i; 77 78 tool_pmu__for_each_event(i) { 79 int ret = do_test(i, /*with_pmu=*/false); 80 81 if (ret != TEST_OK) 82 return ret; 83 } 84 return TEST_OK; 85 } 86 87 static int test__tool_pmu_with_pmu(struct test_suite *test __maybe_unused, 88 int subtest __maybe_unused) 89 { 90 int i; 91 92 tool_pmu__for_each_event(i) { 93 int ret = do_test(i, /*with_pmu=*/true); 94 95 if (ret != TEST_OK) 96 return ret; 97 } 98 return TEST_OK; 99 } 100 101 static struct test_case tests__tool_pmu[] = { 102 TEST_CASE("Parsing without PMU name", tool_pmu_without_pmu), 103 TEST_CASE("Parsing with PMU name", tool_pmu_with_pmu), 104 { .name = NULL, } 105 }; 106 107 struct test_suite suite__tool_pmu = { 108 .desc = "Tool PMU", 109 .test_cases = tests__tool_pmu, 110 }; 111