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->core.nr_groups, 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 = 1, 107 }, 108 { 109 .events = "{instructions},{}", 110 .nr_events = 1, 111 .nr_groups = 1, 112 }, 113 { 114 .events = "{},{instructions}", 115 .nr_events = 1, 116 .nr_groups = 1, 117 }, 118 { 119 .events = "{instructions},{instructions}", 120 .nr_events = 2, 121 .nr_groups = 2, 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->core.nr_groups, 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