2020-09-24 21:44:55 +09:00
// 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 ;
2020-11-30 14:52:44 -03:00
TEST_ASSERT_VAL ( " evlist is empty " , ! evlist__empty ( evlist ) ) ;
2020-09-24 21:44:55 +09:00
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 rblist metric_events ;
2020-11-30 15:04:05 -03:00
struct evlist * evlist = evlist__new_default ( ) ;
2020-09-24 21:44:55 +09:00
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 ) ;
2021-11-07 01:00:01 -08:00
parse_events_error__init ( & err ) ;
2020-09-24 21:44:55 +09:00
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 ) ;
2021-11-07 01:00:00 -08:00
parse_events_error__print ( & err , event_str ) ;
2020-09-24 21:44:55 +09:00
goto out ;
}
rblist__init ( & metric_events ) ;
ret = test_expand_events ( evlist , & metric_events ) ;
out :
2021-11-07 01:00:01 -08:00
parse_events_error__exit ( & err ) ;
2020-09-24 21:44:55 +09:00
evlist__delete ( evlist ) ;
return ret ;
}
static int expand_libpfm_events ( void )
{
int ret ;
struct evlist * evlist ;
struct rblist metric_events ;
2020-10-27 16:28:54 +09:00
const char event_str [ ] = " CYCLES " ;
2020-09-24 21:44:55 +09:00
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 ;
}
2020-11-30 14:52:44 -03:00
if ( evlist__empty ( evlist ) ) {
2020-09-24 21:44:55 +09:00
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 ,
} ,
} ;
2021-10-15 10:21:13 -07:00
const struct pmu_events_map ev_map = {
2020-09-24 21:44:55 +09:00
. 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 ;
}
2021-11-03 23:41:50 -07:00
static int test__expand_cgroup_events ( struct test * test __maybe_unused ,
int subtest __maybe_unused )
2020-09-24 21:44:55 +09:00
{
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 ;
}
2021-11-03 23:41:50 -07:00
DEFINE_SUITE ( " Event expansion for cgroups " , expand_cgroup_events ) ;