// SPDX-License-Identifier: GPL-2.0 /* * Test support for libpfm4 event encodings. * * Copyright 2020 Google LLC. */ #include "tests.h" #include "util/debug.h" #include "util/evlist.h" #include "util/pfm.h" #include #ifdef HAVE_LIBPFM static int test__pfm_events(void); static int test__pfm_group(void); #endif static const struct { int (*func)(void); const char *desc; } pfm_testcase_table[] = { #ifdef HAVE_LIBPFM { .func = test__pfm_events, .desc = "test of individual --pfm-events", }, { .func = test__pfm_group, .desc = "test groups of --pfm-events", }, #endif }; #ifdef HAVE_LIBPFM static int count_pfm_events(struct perf_evlist *evlist) { struct perf_evsel *evsel; int count = 0; perf_evlist__for_each_entry(evlist, evsel) { count++; } return count; } static int test__pfm_events(void) { struct evlist *evlist; struct option opt; size_t i; const struct { const char *events; int nr_events; } table[] = { { .events = "", .nr_events = 0, }, { .events = "instructions", .nr_events = 1, }, { .events = "instructions,cycles", .nr_events = 2, }, { .events = "stereolab", .nr_events = 0, }, { .events = "instructions,instructions", .nr_events = 2, }, { .events = "stereolab,instructions", .nr_events = 0, }, { .events = "instructions,stereolab", .nr_events = 1, }, }; for (i = 0; i < ARRAY_SIZE(table); i++) { evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; opt.value = evlist; parse_libpfm_events_option(&opt, table[i].events, 0); TEST_ASSERT_EQUAL(table[i].events, count_pfm_events(&evlist->core), table[i].nr_events); TEST_ASSERT_EQUAL(table[i].events, evlist->nr_groups, 0); evlist__delete(evlist); } return 0; } static int test__pfm_group(void) { struct evlist *evlist; struct option opt; size_t i; const struct { const char *events; int nr_events; int nr_groups; } table[] = { { .events = "{},", .nr_events = 0, .nr_groups = 0, }, { .events = "{instructions}", .nr_events = 1, .nr_groups = 1, }, { .events = "{instructions},{}", .nr_events = 1, .nr_groups = 1, }, { .events = "{},{instructions}", .nr_events = 0, .nr_groups = 0, }, { .events = "{instructions},{instructions}", .nr_events = 2, .nr_groups = 2, }, { .events = "{instructions,cycles},{instructions,cycles}", .nr_events = 4, .nr_groups = 2, }, { .events = "{stereolab}", .nr_events = 0, .nr_groups = 0, }, { .events = "{instructions,cycles},{instructions,stereolab}", .nr_events = 3, .nr_groups = 1, }, }; for (i = 0; i < ARRAY_SIZE(table); i++) { evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; opt.value = evlist; parse_libpfm_events_option(&opt, table[i].events, 0); TEST_ASSERT_EQUAL(table[i].events, count_pfm_events(&evlist->core), table[i].nr_events); TEST_ASSERT_EQUAL(table[i].events, evlist->nr_groups, table[i].nr_groups); evlist__delete(evlist); } return 0; } #endif const char *test__pfm_subtest_get_desc(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) return NULL; return pfm_testcase_table[i].desc; } int test__pfm_subtest_get_nr(void) { return (int)ARRAY_SIZE(pfm_testcase_table); } int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) { #ifdef HAVE_LIBPFM if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) return TEST_FAIL; return pfm_testcase_table[i].func(); #else return TEST_SKIP; #endif }