brintos

brintos / linux-shallow public Read only

0
0
Text · 20.8 KiB · 1e0f5a3 Raw
755 lines · c
1// SPDX-License-Identifier: GPL-2.02#include "util/debug.h"3#include "util/dso.h"4#include "util/event.h"5#include "util/map.h"6#include "util/symbol.h"7#include "util/sort.h"8#include "util/evsel.h"9#include "util/evlist.h"10#include "util/machine.h"11#include "util/parse-events.h"12#include "util/thread.h"13#include "tests/tests.h"14#include "tests/hists_common.h"15#include <linux/kernel.h>16 17struct sample {18	u32 pid;19	u64 ip;20	struct thread *thread;21	struct map *map;22	struct symbol *sym;23};24 25/* For the numbers, see hists_common.c */26static struct sample fake_samples[] = {27	/* perf [kernel] schedule() */28	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },29	/* perf [perf]   main() */30	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, },31	/* perf [perf]   cmd_record() */32	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_CMD_RECORD, },33	/* perf [libc]   malloc() */34	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },35	/* perf [libc]   free() */36	{ .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_FREE, },37	/* perf [perf]   main() */38	{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },39	/* perf [kernel] page_fault() */40	{ .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },41	/* bash [bash]   main() */42	{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_MAIN, },43	/* bash [bash]   xmalloc() */44	{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_XMALLOC, },45	/* bash [kernel] page_fault() */46	{ .pid = FAKE_PID_BASH,  .ip = FAKE_IP_KERNEL_PAGE_FAULT, },47};48 49/*50 * Will be cast to struct ip_callchain which has all 64 bit entries51 * of nr and ips[].52 */53static u64 fake_callchains[][10] = {54	/*   schedule => run_command => main */55	{ 3, FAKE_IP_KERNEL_SCHEDULE, FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, },56	/*   main  */57	{ 1, FAKE_IP_PERF_MAIN, },58	/*   cmd_record => run_command => main */59	{ 3, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, },60	/*   malloc => cmd_record => run_command => main */61	{ 4, FAKE_IP_LIBC_MALLOC, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND,62	     FAKE_IP_PERF_MAIN, },63	/*   free => cmd_record => run_command => main */64	{ 4, FAKE_IP_LIBC_FREE, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND,65	     FAKE_IP_PERF_MAIN, },66	/*   main */67	{ 1, FAKE_IP_PERF_MAIN, },68	/*   page_fault => sys_perf_event_open => run_command => main */69	{ 4, FAKE_IP_KERNEL_PAGE_FAULT, FAKE_IP_KERNEL_SYS_PERF_EVENT_OPEN,70	     FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, },71	/*   main */72	{ 1, FAKE_IP_BASH_MAIN, },73	/*   xmalloc => malloc => xmalloc => malloc => xmalloc => main */74	{ 6, FAKE_IP_BASH_XMALLOC, FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_XMALLOC,75	     FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_XMALLOC, FAKE_IP_BASH_MAIN, },76	/*   page_fault => malloc => main */77	{ 3, FAKE_IP_KERNEL_PAGE_FAULT, FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_MAIN, },78};79 80static int add_hist_entries(struct hists *hists, struct machine *machine)81{82	struct addr_location al;83	struct evsel *evsel = hists_to_evsel(hists);84	struct perf_sample sample = { .period = 1000, };85	size_t i;86 87	addr_location__init(&al);88	for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {89		struct hist_entry_iter iter = {90			.evsel = evsel,91			.sample	= &sample,92			.hide_unresolved = false,93		};94 95		if (symbol_conf.cumulate_callchain)96			iter.ops = &hist_iter_cumulative;97		else98			iter.ops = &hist_iter_normal;99 100		sample.cpumode = PERF_RECORD_MISC_USER;101		sample.pid = fake_samples[i].pid;102		sample.tid = fake_samples[i].pid;103		sample.ip = fake_samples[i].ip;104		sample.callchain = (struct ip_callchain *)fake_callchains[i];105 106		if (machine__resolve(machine, &al, &sample) < 0)107			goto out;108 109		if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack,110					 NULL) < 0) {111			goto out;112		}113 114		thread__put(fake_samples[i].thread);115		fake_samples[i].thread = thread__get(al.thread);116		map__put(fake_samples[i].map);117		fake_samples[i].map = map__get(al.map);118		fake_samples[i].sym = al.sym;119	}120 121	addr_location__exit(&al);122	return TEST_OK;123 124out:125	pr_debug("Not enough memory for adding a hist entry\n");126	addr_location__exit(&al);127	return TEST_FAIL;128}129 130static void del_hist_entries(struct hists *hists)131{132	struct hist_entry *he;133	struct rb_root_cached *root_in;134	struct rb_root_cached *root_out;135	struct rb_node *node;136 137	if (hists__has(hists, need_collapse))138		root_in = &hists->entries_collapsed;139	else140		root_in = hists->entries_in;141 142	root_out = &hists->entries;143 144	while (!RB_EMPTY_ROOT(&root_out->rb_root)) {145		node = rb_first_cached(root_out);146 147		he = rb_entry(node, struct hist_entry, rb_node);148		rb_erase_cached(node, root_out);149		rb_erase_cached(&he->rb_node_in, root_in);150		hist_entry__delete(he);151	}152}153 154static void put_fake_samples(void)155{156	size_t i;157 158	for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {159		map__zput(fake_samples[i].map);160		thread__zput(fake_samples[i].thread);161	}162}163 164typedef int (*test_fn_t)(struct evsel *, struct machine *);165 166#define COMM(he)  (thread__comm_str(he->thread))167#define DSO(he)   (dso__short_name(map__dso(he->ms.map)))168#define SYM(he)   (he->ms.sym->name)169#define CPU(he)   (he->cpu)170#define DEPTH(he) (he->callchain->max_depth)171#define CDSO(cl)  (dso__short_name(map__dso(cl->ms.map)))172#define CSYM(cl)  (cl->ms.sym->name)173 174struct result {175	u64 children;176	u64 self;177	const char *comm;178	const char *dso;179	const char *sym;180};181 182struct callchain_result {183	u64 nr;184	struct {185		const char *dso;186		const char *sym;187	} node[10];188};189 190static int do_test(struct hists *hists, struct result *expected, size_t nr_expected,191		   struct callchain_result *expected_callchain, size_t nr_callchain)192{193	char buf[32];194	size_t i, c;195	struct hist_entry *he;196	struct rb_root *root;197	struct rb_node *node;198	struct callchain_node *cnode;199	struct callchain_list *clist;200 201	/*202	 * adding and deleting hist entries must be done outside of this203	 * function since TEST_ASSERT_VAL() returns in case of failure.204	 */205	hists__collapse_resort(hists, NULL);206	evsel__output_resort(hists_to_evsel(hists), NULL);207 208	if (verbose > 2) {209		pr_info("use callchain: %d, cumulate callchain: %d\n",210			symbol_conf.use_callchain,211			symbol_conf.cumulate_callchain);212		print_hists_out(hists);213	}214 215	root = &hists->entries.rb_root;216	for (node = rb_first(root), i = 0;217	     node && (he = rb_entry(node, struct hist_entry, rb_node));218	     node = rb_next(node), i++) {219		scnprintf(buf, sizeof(buf), "Invalid hist entry #%zd", i);220 221		TEST_ASSERT_VAL("Incorrect number of hist entry",222				i < nr_expected);223		TEST_ASSERT_VAL(buf, he->stat.period == expected[i].self &&224				!strcmp(COMM(he), expected[i].comm) &&225				!strcmp(DSO(he), expected[i].dso) &&226				!strcmp(SYM(he), expected[i].sym));227 228		if (symbol_conf.cumulate_callchain)229			TEST_ASSERT_VAL(buf, he->stat_acc->period == expected[i].children);230 231		if (!symbol_conf.use_callchain)232			continue;233 234		/* check callchain entries */235		root = &he->callchain->node.rb_root;236 237		TEST_ASSERT_VAL("callchains expected", !RB_EMPTY_ROOT(root));238		cnode = rb_entry(rb_first(root), struct callchain_node, rb_node);239 240		c = 0;241		list_for_each_entry(clist, &cnode->val, list) {242			scnprintf(buf, sizeof(buf), "Invalid callchain entry #%zd/%zd", i, c);243 244			TEST_ASSERT_VAL("Incorrect number of callchain entry",245					c < expected_callchain[i].nr);246			TEST_ASSERT_VAL(buf,247				!strcmp(CDSO(clist), expected_callchain[i].node[c].dso) &&248				!strcmp(CSYM(clist), expected_callchain[i].node[c].sym));249			c++;250		}251		/* TODO: handle multiple child nodes properly */252		TEST_ASSERT_VAL("Incorrect number of callchain entry",253				c <= expected_callchain[i].nr);254	}255	TEST_ASSERT_VAL("Incorrect number of hist entry",256			i == nr_expected);257	TEST_ASSERT_VAL("Incorrect number of callchain entry",258			!symbol_conf.use_callchain || nr_expected == nr_callchain);259	return 0;260}261 262/* NO callchain + NO children */263static int test1(struct evsel *evsel, struct machine *machine)264{265	int err;266	struct hists *hists = evsel__hists(evsel);267	/*268	 * expected output:269	 *270	 * Overhead  Command  Shared Object          Symbol271	 * ========  =======  =============  ==============272	 *   20.00%     perf  perf           [.] main273	 *   10.00%     bash  [kernel]       [k] page_fault274	 *   10.00%     bash  bash           [.] main275	 *   10.00%     bash  bash           [.] xmalloc276	 *   10.00%     perf  [kernel]       [k] page_fault277	 *   10.00%     perf  [kernel]       [k] schedule278	 *   10.00%     perf  libc           [.] free279	 *   10.00%     perf  libc           [.] malloc280	 *   10.00%     perf  perf           [.] cmd_record281	 */282	struct result expected[] = {283		{ 0, 2000, "perf", "perf",     "main" },284		{ 0, 1000, "bash", "[kernel]", "page_fault" },285		{ 0, 1000, "bash", "bash",     "main" },286		{ 0, 1000, "bash", "bash",     "xmalloc" },287		{ 0, 1000, "perf", "[kernel]", "page_fault" },288		{ 0, 1000, "perf", "[kernel]", "schedule" },289		{ 0, 1000, "perf", "libc",     "free" },290		{ 0, 1000, "perf", "libc",     "malloc" },291		{ 0, 1000, "perf", "perf",     "cmd_record" },292	};293 294	symbol_conf.use_callchain = false;295	symbol_conf.cumulate_callchain = false;296	evsel__reset_sample_bit(evsel, CALLCHAIN);297 298	setup_sorting(NULL);299	callchain_register_param(&callchain_param);300 301	err = add_hist_entries(hists, machine);302	if (err < 0)303		goto out;304 305	err = do_test(hists, expected, ARRAY_SIZE(expected), NULL, 0);306 307out:308	del_hist_entries(hists);309	reset_output_field();310	return err;311}312 313/* callchain + NO children */314static int test2(struct evsel *evsel, struct machine *machine)315{316	int err;317	struct hists *hists = evsel__hists(evsel);318	/*319	 * expected output:320	 *321	 * Overhead  Command  Shared Object          Symbol322	 * ========  =======  =============  ==============323	 *   20.00%     perf  perf           [.] main324	 *              |325	 *              --- main326	 *327	 *   10.00%     bash  [kernel]       [k] page_fault328	 *              |329	 *              --- page_fault330	 *                  malloc331	 *                  main332	 *333	 *   10.00%     bash  bash           [.] main334	 *              |335	 *              --- main336	 *337	 *   10.00%     bash  bash           [.] xmalloc338	 *              |339	 *              --- xmalloc340	 *                  malloc341	 *                  xmalloc     <--- NOTE: there's a cycle342	 *                  malloc343	 *                  xmalloc344	 *                  main345	 *346	 *   10.00%     perf  [kernel]       [k] page_fault347	 *              |348	 *              --- page_fault349	 *                  sys_perf_event_open350	 *                  run_command351	 *                  main352	 *353	 *   10.00%     perf  [kernel]       [k] schedule354	 *              |355	 *              --- schedule356	 *                  run_command357	 *                  main358	 *359	 *   10.00%     perf  libc           [.] free360	 *              |361	 *              --- free362	 *                  cmd_record363	 *                  run_command364	 *                  main365	 *366	 *   10.00%     perf  libc           [.] malloc367	 *              |368	 *              --- malloc369	 *                  cmd_record370	 *                  run_command371	 *                  main372	 *373	 *   10.00%     perf  perf           [.] cmd_record374	 *              |375	 *              --- cmd_record376	 *                  run_command377	 *                  main378	 *379	 */380	struct result expected[] = {381		{ 0, 2000, "perf", "perf",     "main" },382		{ 0, 1000, "bash", "[kernel]", "page_fault" },383		{ 0, 1000, "bash", "bash",     "main" },384		{ 0, 1000, "bash", "bash",     "xmalloc" },385		{ 0, 1000, "perf", "[kernel]", "page_fault" },386		{ 0, 1000, "perf", "[kernel]", "schedule" },387		{ 0, 1000, "perf", "libc",     "free" },388		{ 0, 1000, "perf", "libc",     "malloc" },389		{ 0, 1000, "perf", "perf",     "cmd_record" },390	};391	struct callchain_result expected_callchain[] = {392		{393			1, {	{ "perf",     "main" }, },394		},395		{396			3, {	{ "[kernel]", "page_fault" },397				{ "libc",     "malloc" },398				{ "bash",     "main" }, },399		},400		{401			1, {	{ "bash",     "main" }, },402		},403		{404			6, {	{ "bash",     "xmalloc" },405				{ "libc",     "malloc" },406				{ "bash",     "xmalloc" },407				{ "libc",     "malloc" },408				{ "bash",     "xmalloc" },409				{ "bash",     "main" }, },410		},411		{412			4, {	{ "[kernel]", "page_fault" },413				{ "[kernel]", "sys_perf_event_open" },414				{ "perf",     "run_command" },415				{ "perf",     "main" }, },416		},417		{418			3, {	{ "[kernel]", "schedule" },419				{ "perf",     "run_command" },420				{ "perf",     "main" }, },421		},422		{423			4, {	{ "libc",     "free" },424				{ "perf",     "cmd_record" },425				{ "perf",     "run_command" },426				{ "perf",     "main" }, },427		},428		{429			4, {	{ "libc",     "malloc" },430				{ "perf",     "cmd_record" },431				{ "perf",     "run_command" },432				{ "perf",     "main" }, },433		},434		{435			3, {	{ "perf",     "cmd_record" },436				{ "perf",     "run_command" },437				{ "perf",     "main" }, },438		},439	};440 441	symbol_conf.use_callchain = true;442	symbol_conf.cumulate_callchain = false;443	evsel__set_sample_bit(evsel, CALLCHAIN);444 445	setup_sorting(NULL);446	callchain_register_param(&callchain_param);447 448	err = add_hist_entries(hists, machine);449	if (err < 0)450		goto out;451 452	err = do_test(hists, expected, ARRAY_SIZE(expected),453		      expected_callchain, ARRAY_SIZE(expected_callchain));454 455out:456	del_hist_entries(hists);457	reset_output_field();458	return err;459}460 461/* NO callchain + children */462static int test3(struct evsel *evsel, struct machine *machine)463{464	int err;465	struct hists *hists = evsel__hists(evsel);466	/*467	 * expected output:468	 *469	 * Children      Self  Command  Shared Object                   Symbol470	 * ========  ========  =======  =============  =======================471	 *   70.00%    20.00%     perf  perf           [.] main472	 *   50.00%     0.00%     perf  perf           [.] run_command473	 *   30.00%    10.00%     bash  bash           [.] main474	 *   30.00%    10.00%     perf  perf           [.] cmd_record475	 *   20.00%     0.00%     bash  libc           [.] malloc476	 *   10.00%    10.00%     bash  [kernel]       [k] page_fault477	 *   10.00%    10.00%     bash  bash           [.] xmalloc478	 *   10.00%    10.00%     perf  [kernel]       [k] page_fault479	 *   10.00%    10.00%     perf  libc           [.] malloc480	 *   10.00%    10.00%     perf  [kernel]       [k] schedule481	 *   10.00%    10.00%     perf  libc           [.] free482	 *   10.00%     0.00%     perf  [kernel]       [k] sys_perf_event_open483	 */484	struct result expected[] = {485		{ 7000, 2000, "perf", "perf",     "main" },486		{ 5000,    0, "perf", "perf",     "run_command" },487		{ 3000, 1000, "bash", "bash",     "main" },488		{ 3000, 1000, "perf", "perf",     "cmd_record" },489		{ 2000,    0, "bash", "libc",     "malloc" },490		{ 1000, 1000, "bash", "[kernel]", "page_fault" },491		{ 1000, 1000, "bash", "bash",     "xmalloc" },492		{ 1000, 1000, "perf", "[kernel]", "page_fault" },493		{ 1000, 1000, "perf", "[kernel]", "schedule" },494		{ 1000, 1000, "perf", "libc",     "free" },495		{ 1000, 1000, "perf", "libc",     "malloc" },496		{ 1000,    0, "perf", "[kernel]", "sys_perf_event_open" },497	};498 499	symbol_conf.use_callchain = false;500	symbol_conf.cumulate_callchain = true;501	evsel__reset_sample_bit(evsel, CALLCHAIN);502 503	setup_sorting(NULL);504	callchain_register_param(&callchain_param);505 506	err = add_hist_entries(hists, machine);507	if (err < 0)508		goto out;509 510	err = do_test(hists, expected, ARRAY_SIZE(expected), NULL, 0);511 512out:513	del_hist_entries(hists);514	reset_output_field();515	return err;516}517 518/* callchain + children */519static int test4(struct evsel *evsel, struct machine *machine)520{521	int err;522	struct hists *hists = evsel__hists(evsel);523	/*524	 * expected output:525	 *526	 * Children      Self  Command  Shared Object                   Symbol527	 * ========  ========  =======  =============  =======================528	 *   70.00%    20.00%     perf  perf           [.] main529	 *              |530	 *              --- main531	 *532	 *   50.00%     0.00%     perf  perf           [.] run_command533	 *              |534	 *              --- run_command535	 *                  main536	 *537	 *   30.00%    10.00%     bash  bash           [.] main538	 *              |539	 *              --- main540	 *541	 *   30.00%    10.00%     perf  perf           [.] cmd_record542	 *              |543	 *              --- cmd_record544	 *                  run_command545	 *                  main546	 *547	 *   20.00%     0.00%     bash  libc           [.] malloc548	 *              |549	 *              --- malloc550	 *                 |551	 *                 |--50.00%-- xmalloc552	 *                 |           main553	 *                  --50.00%-- main554	 *555	 *   10.00%    10.00%     bash  [kernel]       [k] page_fault556	 *              |557	 *              --- page_fault558	 *                  malloc559	 *                  main560	 *561	 *   10.00%    10.00%     bash  bash           [.] xmalloc562	 *              |563	 *              --- xmalloc564	 *                  malloc565	 *                  xmalloc     <--- NOTE: there's a cycle566	 *                  malloc567	 *                  xmalloc568	 *                  main569	 *570	 *   10.00%     0.00%     perf  [kernel]       [k] sys_perf_event_open571	 *              |572	 *              --- sys_perf_event_open573	 *                  run_command574	 *                  main575	 *576	 *   10.00%    10.00%     perf  [kernel]       [k] page_fault577	 *              |578	 *              --- page_fault579	 *                  sys_perf_event_open580	 *                  run_command581	 *                  main582	 *583	 *   10.00%    10.00%     perf  [kernel]       [k] schedule584	 *              |585	 *              --- schedule586	 *                  run_command587	 *                  main588	 *589	 *   10.00%    10.00%     perf  libc           [.] free590	 *              |591	 *              --- free592	 *                  cmd_record593	 *                  run_command594	 *                  main595	 *596	 *   10.00%    10.00%     perf  libc           [.] malloc597	 *              |598	 *              --- malloc599	 *                  cmd_record600	 *                  run_command601	 *                  main602	 *603	 */604	struct result expected[] = {605		{ 7000, 2000, "perf", "perf",     "main" },606		{ 5000,    0, "perf", "perf",     "run_command" },607		{ 3000, 1000, "bash", "bash",     "main" },608		{ 3000, 1000, "perf", "perf",     "cmd_record" },609		{ 2000,    0, "bash", "libc",     "malloc" },610		{ 1000, 1000, "bash", "[kernel]", "page_fault" },611		{ 1000, 1000, "bash", "bash",     "xmalloc" },612		{ 1000,    0, "perf", "[kernel]", "sys_perf_event_open" },613		{ 1000, 1000, "perf", "[kernel]", "page_fault" },614		{ 1000, 1000, "perf", "[kernel]", "schedule" },615		{ 1000, 1000, "perf", "libc",     "free" },616		{ 1000, 1000, "perf", "libc",     "malloc" },617	};618	struct callchain_result expected_callchain[] = {619		{620			1, {	{ "perf",     "main" }, },621		},622		{623			2, {	{ "perf",     "run_command" },624				{ "perf",     "main" }, },625		},626		{627			1, {	{ "bash",     "main" }, },628		},629		{630			3, {	{ "perf",     "cmd_record" },631				{ "perf",     "run_command" },632				{ "perf",     "main" }, },633		},634		{635			4, {	{ "libc",     "malloc" },636				{ "bash",     "xmalloc" },637				{ "bash",     "main" },638				{ "bash",     "main" }, },639		},640		{641			3, {	{ "[kernel]", "page_fault" },642				{ "libc",     "malloc" },643				{ "bash",     "main" }, },644		},645		{646			6, {	{ "bash",     "xmalloc" },647				{ "libc",     "malloc" },648				{ "bash",     "xmalloc" },649				{ "libc",     "malloc" },650				{ "bash",     "xmalloc" },651				{ "bash",     "main" }, },652		},653		{654			3, {	{ "[kernel]", "sys_perf_event_open" },655				{ "perf",     "run_command" },656				{ "perf",     "main" }, },657		},658		{659			4, {	{ "[kernel]", "page_fault" },660				{ "[kernel]", "sys_perf_event_open" },661				{ "perf",     "run_command" },662				{ "perf",     "main" }, },663		},664		{665			3, {	{ "[kernel]", "schedule" },666				{ "perf",     "run_command" },667				{ "perf",     "main" }, },668		},669		{670			4, {	{ "libc",     "free" },671				{ "perf",     "cmd_record" },672				{ "perf",     "run_command" },673				{ "perf",     "main" }, },674		},675		{676			4, {	{ "libc",     "malloc" },677				{ "perf",     "cmd_record" },678				{ "perf",     "run_command" },679				{ "perf",     "main" }, },680		},681	};682 683	symbol_conf.use_callchain = true;684	symbol_conf.cumulate_callchain = true;685	evsel__set_sample_bit(evsel, CALLCHAIN);686 687	setup_sorting(NULL);688 689	callchain_param = callchain_param_default;690	callchain_register_param(&callchain_param);691 692	err = add_hist_entries(hists, machine);693	if (err < 0)694		goto out;695 696	err = do_test(hists, expected, ARRAY_SIZE(expected),697		      expected_callchain, ARRAY_SIZE(expected_callchain));698 699out:700	del_hist_entries(hists);701	reset_output_field();702	return err;703}704 705static int test__hists_cumulate(struct test_suite *test __maybe_unused, int subtest __maybe_unused)706{707	int err = TEST_FAIL;708	struct machines machines;709	struct machine *machine;710	struct evsel *evsel;711	struct evlist *evlist = evlist__new();712	size_t i;713	test_fn_t testcases[] = {714		test1,715		test2,716		test3,717		test4,718	};719 720	TEST_ASSERT_VAL("No memory", evlist);721 722	err = parse_event(evlist, "cpu-clock");723	if (err)724		goto out;725	err = TEST_FAIL;726 727	machines__init(&machines);728 729	/* setup threads/dso/map/symbols also */730	machine = setup_fake_machine(&machines);731	if (!machine)732		goto out;733 734	if (verbose > 1)735		machine__fprintf(machine, stderr);736 737	evsel = evlist__first(evlist);738 739	for (i = 0; i < ARRAY_SIZE(testcases); i++) {740		err = testcases[i](evsel, machine);741		if (err < 0)742			break;743	}744 745out:746	/* tear down everything */747	evlist__delete(evlist);748	machines__exit(&machines);749	put_fake_samples();750 751	return err;752}753 754DEFINE_SUITE("Cumulate child hist entries", hists_cumulate);755