提交 13b62567 编写于 作者: J Jiri Olsa 提交者: Ingo Molnar

perf tools: Add automated tests for events parsing

Adding builtin test for parse_events function, which is
responsible for parsing/processing "-e" option for
stat/top/record commands.

This new test will run within the builtin test command suite
(perf test).

One or several tests were added for each type of event.
More tests could be added easily if needed.
Signed-off-by: NJiri Olsa <jolsa@redhat.com>
Cc: acme@redhat.com
Cc: a.p.zijlstra@chello.nl
Cc: paulus@samba.org
Link: http://lkml.kernel.org/r/1310635534-4013-3-git-send-email-jolsa@redhat.comSigned-off-by: NIngo Molnar <mingo@elte.hu>
上级 f120f9d5
......@@ -12,6 +12,7 @@
#include "util/parse-events.h"
#include "util/symbol.h"
#include "util/thread_map.h"
#include "../../include/linux/hw_breakpoint.h"
static long page_size;
......@@ -600,6 +601,246 @@ static int test__basic_mmap(void)
#undef nsyscalls
}
#define TEST_ASSERT_VAL(text, cond) \
do { \
if (!cond) { \
pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
return -1; \
} \
} while (0)
static int test__checkevent_tracepoint(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong sample_type",
(PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
evsel->attr.sample_type);
TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
return 0;
}
static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
list_for_each_entry(evsel, &evlist->entries, node) {
TEST_ASSERT_VAL("wrong type",
PERF_TYPE_TRACEPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong sample_type",
(PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
== evsel->attr.sample_type);
TEST_ASSERT_VAL("wrong sample_period",
1 == evsel->attr.sample_period);
}
return 0;
}
static int test__checkevent_raw(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
return 0;
}
static int test__checkevent_numeric(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
return 0;
}
static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
TEST_ASSERT_VAL("wrong config",
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
return 0;
}
static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
TEST_ASSERT_VAL("wrong config",
PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
return 0;
}
static int test__checkevent_genhw(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config);
return 0;
}
static int test__checkevent_breakpoint(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) ==
evsel->attr.bp_type);
TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 ==
evsel->attr.bp_len);
return 0;
}
static int test__checkevent_breakpoint_x(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
TEST_ASSERT_VAL("wrong bp_type",
HW_BREAKPOINT_X == evsel->attr.bp_type);
TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len);
return 0;
}
static int test__checkevent_breakpoint_r(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type",
PERF_TYPE_BREAKPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
TEST_ASSERT_VAL("wrong bp_type",
HW_BREAKPOINT_R == evsel->attr.bp_type);
TEST_ASSERT_VAL("wrong bp_len",
HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
return 0;
}
static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type",
PERF_TYPE_BREAKPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
TEST_ASSERT_VAL("wrong bp_type",
HW_BREAKPOINT_W == evsel->attr.bp_type);
TEST_ASSERT_VAL("wrong bp_len",
HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
return 0;
}
static struct test__event_st {
const char *name;
__u32 type;
int (*check)(struct perf_evlist *evlist);
} test__events[] = {
{
.name = "syscalls:sys_enter_open",
.check = test__checkevent_tracepoint,
},
{
.name = "syscalls:*",
.check = test__checkevent_tracepoint_multi,
},
{
.name = "r1",
.check = test__checkevent_raw,
},
{
.name = "1:1",
.check = test__checkevent_numeric,
},
{
.name = "instructions",
.check = test__checkevent_symbolic_name,
},
{
.name = "faults",
.check = test__checkevent_symbolic_alias,
},
{
.name = "L1-dcache-load-miss",
.check = test__checkevent_genhw,
},
{
.name = "mem:0",
.check = test__checkevent_breakpoint,
},
{
.name = "mem:0:x",
.check = test__checkevent_breakpoint_x,
},
{
.name = "mem:0:r",
.check = test__checkevent_breakpoint_r,
},
{
.name = "mem:0:w",
.check = test__checkevent_breakpoint_w,
},
};
#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
static int test__parse_events(void)
{
struct perf_evlist *evlist;
u_int i;
int ret = 0;
for (i = 0; i < TEST__EVENTS_CNT; i++) {
struct test__event_st *e = &test__events[i];
evlist = perf_evlist__new(NULL, NULL);
if (evlist == NULL)
break;
ret = parse_events(evlist, e->name, 0);
if (ret) {
pr_debug("failed to parse event '%s', err %d\n",
e->name, ret);
break;
}
ret = e->check(evlist);
if (ret)
break;
perf_evlist__delete(evlist);
}
return ret;
}
static struct test {
const char *desc;
int (*func)(void);
......@@ -620,6 +861,10 @@ static struct test {
.desc = "read samples using the mmap interface",
.func = test__basic_mmap,
},
{
.desc = "parse events tests",
.func = test__parse_events,
},
{
.func = NULL,
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册