123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- // SPDX-License-Identifier: GPL-2.0
- #include "tests.h"
- #include "debug.h"
- #include "evlist.h"
- #include "cgroup.h"
- #include "rblist.h"
- #include "metricgroup.h"
- #include "parse-events.h"
- #include "pmu-events/pmu-events.h"
- #include "pfm.h"
- #include <subcmd/parse-options.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- static int test_expand_events(struct evlist *evlist,
- struct rblist *metric_events)
- {
- int i, ret = TEST_FAIL;
- int nr_events;
- bool was_group_event;
- int nr_members; /* for the first evsel only */
- const char cgrp_str[] = "A,B,C";
- const char *cgrp_name[] = { "A", "B", "C" };
- int nr_cgrps = ARRAY_SIZE(cgrp_name);
- char **ev_name;
- struct evsel *evsel;
- TEST_ASSERT_VAL("evlist is empty", !perf_evlist__empty(evlist));
- nr_events = evlist->core.nr_entries;
- ev_name = calloc(nr_events, sizeof(*ev_name));
- if (ev_name == NULL) {
- pr_debug("memory allocation failure\n");
- return TEST_FAIL;
- }
- i = 0;
- evlist__for_each_entry(evlist, evsel) {
- ev_name[i] = strdup(evsel->name);
- if (ev_name[i] == NULL) {
- pr_debug("memory allocation failure\n");
- goto out;
- }
- i++;
- }
- /* remember grouping info */
- was_group_event = evsel__is_group_event(evlist__first(evlist));
- nr_members = evlist__first(evlist)->core.nr_members;
- ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false);
- if (ret < 0) {
- pr_debug("failed to expand events for cgroups\n");
- goto out;
- }
- ret = TEST_FAIL;
- if (evlist->core.nr_entries != nr_events * nr_cgrps) {
- pr_debug("event count doesn't match\n");
- goto out;
- }
- i = 0;
- evlist__for_each_entry(evlist, evsel) {
- if (strcmp(evsel->name, ev_name[i % nr_events])) {
- pr_debug("event name doesn't match:\n");
- pr_debug(" evsel[%d]: %s\n expected: %s\n",
- i, evsel->name, ev_name[i % nr_events]);
- goto out;
- }
- if (strcmp(evsel->cgrp->name, cgrp_name[i / nr_events])) {
- pr_debug("cgroup name doesn't match:\n");
- pr_debug(" evsel[%d]: %s\n expected: %s\n",
- i, evsel->cgrp->name, cgrp_name[i / nr_events]);
- goto out;
- }
- if ((i % nr_events) == 0) {
- if (evsel__is_group_event(evsel) != was_group_event) {
- pr_debug("event group doesn't match: got %s, expect %s\n",
- evsel__is_group_event(evsel) ? "true" : "false",
- was_group_event ? "true" : "false");
- goto out;
- }
- if (evsel->core.nr_members != nr_members) {
- pr_debug("event group member doesn't match: %d vs %d\n",
- evsel->core.nr_members, nr_members);
- goto out;
- }
- }
- i++;
- }
- ret = TEST_OK;
- out: for (i = 0; i < nr_events; i++)
- free(ev_name[i]);
- free(ev_name);
- return ret;
- }
- static int expand_default_events(void)
- {
- int ret;
- struct evlist *evlist;
- struct rblist metric_events;
- evlist = perf_evlist__new_default();
- TEST_ASSERT_VAL("failed to get evlist", evlist);
- rblist__init(&metric_events);
- ret = test_expand_events(evlist, &metric_events);
- evlist__delete(evlist);
- return ret;
- }
- static int expand_group_events(void)
- {
- int ret;
- struct evlist *evlist;
- struct rblist metric_events;
- struct parse_events_error err;
- const char event_str[] = "{cycles,instructions}";
- symbol_conf.event_group = true;
- evlist = evlist__new();
- TEST_ASSERT_VAL("failed to get evlist", evlist);
- ret = parse_events(evlist, event_str, &err);
- if (ret < 0) {
- pr_debug("failed to parse event '%s', err %d, str '%s'\n",
- event_str, ret, err.str);
- parse_events_print_error(&err, event_str);
- goto out;
- }
- rblist__init(&metric_events);
- ret = test_expand_events(evlist, &metric_events);
- out:
- evlist__delete(evlist);
- return ret;
- }
- static int expand_libpfm_events(void)
- {
- int ret;
- struct evlist *evlist;
- struct rblist metric_events;
- const char event_str[] = "CYCLES";
- struct option opt = {
- .value = &evlist,
- };
- symbol_conf.event_group = true;
- evlist = evlist__new();
- TEST_ASSERT_VAL("failed to get evlist", evlist);
- ret = parse_libpfm_events_option(&opt, event_str, 0);
- if (ret < 0) {
- pr_debug("failed to parse libpfm event '%s', err %d\n",
- event_str, ret);
- goto out;
- }
- if (perf_evlist__empty(evlist)) {
- pr_debug("libpfm was not enabled\n");
- goto out;
- }
- rblist__init(&metric_events);
- ret = test_expand_events(evlist, &metric_events);
- out:
- evlist__delete(evlist);
- return ret;
- }
- static int expand_metric_events(void)
- {
- int ret;
- struct evlist *evlist;
- struct rblist metric_events;
- const char metric_str[] = "CPI";
- struct pmu_event pme_test[] = {
- {
- .metric_expr = "instructions / cycles",
- .metric_name = "IPC",
- },
- {
- .metric_expr = "1 / IPC",
- .metric_name = "CPI",
- },
- {
- .metric_expr = NULL,
- .metric_name = NULL,
- },
- };
- struct pmu_events_map ev_map = {
- .cpuid = "test",
- .version = "1",
- .type = "core",
- .table = pme_test,
- };
- evlist = evlist__new();
- TEST_ASSERT_VAL("failed to get evlist", evlist);
- rblist__init(&metric_events);
- ret = metricgroup__parse_groups_test(evlist, &ev_map, metric_str,
- false, false, &metric_events);
- if (ret < 0) {
- pr_debug("failed to parse '%s' metric\n", metric_str);
- goto out;
- }
- ret = test_expand_events(evlist, &metric_events);
- out:
- metricgroup__rblist_exit(&metric_events);
- evlist__delete(evlist);
- return ret;
- }
- int test__expand_cgroup_events(struct test *test __maybe_unused,
- int subtest __maybe_unused)
- {
- int ret;
- ret = expand_default_events();
- TEST_ASSERT_EQUAL("failed to expand default events", ret, 0);
- ret = expand_group_events();
- TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
- ret = expand_libpfm_events();
- TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
- ret = expand_metric_events();
- TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0);
- return ret;
- }
|