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