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 parse_events_error__exit(&err); 70 evlist__delete(evlist); 71 return ret; 72 } 73 74 static int test__tool_pmu_without_pmu(struct test_suite *test __maybe_unused, 75 int subtest __maybe_unused) 76 { 77 int i; 78 79 tool_pmu__for_each_event(i) { 80 int ret = do_test(i, /*with_pmu=*/false); 81 82 if (ret != TEST_OK) 83 return ret; 84 } 85 return TEST_OK; 86 } 87 88 static int test__tool_pmu_with_pmu(struct test_suite *test __maybe_unused, 89 int subtest __maybe_unused) 90 { 91 int i; 92 93 tool_pmu__for_each_event(i) { 94 int ret = do_test(i, /*with_pmu=*/true); 95 96 if (ret != TEST_OK) 97 return ret; 98 } 99 return TEST_OK; 100 } 101 102 static struct test_case tests__tool_pmu[] = { 103 TEST_CASE("Parsing without PMU name", tool_pmu_without_pmu), 104 TEST_CASE("Parsing with PMU name", tool_pmu_with_pmu), 105 { .name = NULL, } 106 }; 107 108 struct test_suite suite__tool_pmu = { 109 .desc = "Tool PMU", 110 .test_cases = tests__tool_pmu, 111 }; 112