1 #include "perf.h" 2 #include "util/debug.h" 3 #include "util/symbol.h" 4 #include "util/sort.h" 5 #include "util/evsel.h" 6 #include "util/evlist.h" 7 #include "util/machine.h" 8 #include "util/thread.h" 9 #include "util/parse-events.h" 10 #include "tests/tests.h" 11 #include "tests/hists_common.h" 12 13 struct sample { 14 u32 pid; 15 u64 ip; 16 struct thread *thread; 17 struct map *map; 18 struct symbol *sym; 19 }; 20 21 /* For the numbers, see hists_common.c */ 22 static struct sample fake_samples[] = { 23 /* perf [kernel] schedule() */ 24 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, }, 25 /* perf [perf] main() */ 26 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, }, 27 /* perf [perf] cmd_record() */ 28 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_CMD_RECORD, }, 29 /* perf [libc] malloc() */ 30 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, }, 31 /* perf [libc] free() */ 32 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_FREE, }, 33 /* perf [perf] main() */ 34 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, }, 35 /* perf [kernel] page_fault() */ 36 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, }, 37 /* bash [bash] main() */ 38 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_MAIN, }, 39 /* bash [bash] xmalloc() */ 40 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, }, 41 /* bash [kernel] page_fault() */ 42 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, }, 43 }; 44 45 /* 46 * Will be casted to struct ip_callchain which has all 64 bit entries 47 * of nr and ips[]. 48 */ 49 static u64 fake_callchains[][10] = { 50 /* schedule => run_command => main */ 51 { 3, FAKE_IP_KERNEL_SCHEDULE, FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, }, 52 /* main */ 53 { 1, FAKE_IP_PERF_MAIN, }, 54 /* cmd_record => run_command => main */ 55 { 3, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, }, 56 /* malloc => cmd_record => run_command => main */ 57 { 4, FAKE_IP_LIBC_MALLOC, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND, 58 FAKE_IP_PERF_MAIN, }, 59 /* free => cmd_record => run_command => main */ 60 { 4, FAKE_IP_LIBC_FREE, FAKE_IP_PERF_CMD_RECORD, FAKE_IP_PERF_RUN_COMMAND, 61 FAKE_IP_PERF_MAIN, }, 62 /* main */ 63 { 1, FAKE_IP_PERF_MAIN, }, 64 /* page_fault => sys_perf_event_open => run_command => main */ 65 { 4, FAKE_IP_KERNEL_PAGE_FAULT, FAKE_IP_KERNEL_SYS_PERF_EVENT_OPEN, 66 FAKE_IP_PERF_RUN_COMMAND, FAKE_IP_PERF_MAIN, }, 67 /* main */ 68 { 1, FAKE_IP_BASH_MAIN, }, 69 /* xmalloc => malloc => xmalloc => malloc => xmalloc => main */ 70 { 6, FAKE_IP_BASH_XMALLOC, FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_XMALLOC, 71 FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_XMALLOC, FAKE_IP_BASH_MAIN, }, 72 /* page_fault => malloc => main */ 73 { 3, FAKE_IP_KERNEL_PAGE_FAULT, FAKE_IP_LIBC_MALLOC, FAKE_IP_BASH_MAIN, }, 74 }; 75 76 static int add_hist_entries(struct hists *hists, struct machine *machine) 77 { 78 struct addr_location al; 79 struct perf_evsel *evsel = hists_to_evsel(hists); 80 struct perf_sample sample = { .period = 1000, }; 81 size_t i; 82 83 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 84 const union perf_event event = { 85 .header = { 86 .misc = PERF_RECORD_MISC_USER, 87 }, 88 }; 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 else 98 iter.ops = &hist_iter_normal; 99 100 sample.pid = fake_samples[i].pid; 101 sample.tid = fake_samples[i].pid; 102 sample.ip = fake_samples[i].ip; 103 sample.callchain = (struct ip_callchain *)fake_callchains[i]; 104 105 if (perf_event__preprocess_sample(&event, machine, &al, 106 &sample) < 0) 107 goto out; 108 109 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH, 110 NULL) < 0) { 111 addr_location__put(&al); 112 goto out; 113 } 114 115 fake_samples[i].thread = al.thread; 116 fake_samples[i].map = al.map; 117 fake_samples[i].sym = al.sym; 118 } 119 120 return TEST_OK; 121 122 out: 123 pr_debug("Not enough memory for adding a hist entry\n"); 124 return TEST_FAIL; 125 } 126 127 static void del_hist_entries(struct hists *hists) 128 { 129 struct hist_entry *he; 130 struct rb_root *root_in; 131 struct rb_root *root_out; 132 struct rb_node *node; 133 134 if (sort__need_collapse) 135 root_in = &hists->entries_collapsed; 136 else 137 root_in = hists->entries_in; 138 139 root_out = &hists->entries; 140 141 while (!RB_EMPTY_ROOT(root_out)) { 142 node = rb_first(root_out); 143 144 he = rb_entry(node, struct hist_entry, rb_node); 145 rb_erase(node, root_out); 146 rb_erase(&he->rb_node_in, root_in); 147 hist_entry__delete(he); 148 } 149 } 150 151 typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); 152 153 #define COMM(he) (thread__comm_str(he->thread)) 154 #define DSO(he) (he->ms.map->dso->short_name) 155 #define SYM(he) (he->ms.sym->name) 156 #define CPU(he) (he->cpu) 157 #define PID(he) (he->thread->tid) 158 #define DEPTH(he) (he->callchain->max_depth) 159 #define CDSO(cl) (cl->ms.map->dso->short_name) 160 #define CSYM(cl) (cl->ms.sym->name) 161 162 struct result { 163 u64 children; 164 u64 self; 165 const char *comm; 166 const char *dso; 167 const char *sym; 168 }; 169 170 struct callchain_result { 171 u64 nr; 172 struct { 173 const char *dso; 174 const char *sym; 175 } node[10]; 176 }; 177 178 static int do_test(struct hists *hists, struct result *expected, size_t nr_expected, 179 struct callchain_result *expected_callchain, size_t nr_callchain) 180 { 181 char buf[32]; 182 size_t i, c; 183 struct hist_entry *he; 184 struct rb_root *root; 185 struct rb_node *node; 186 struct callchain_node *cnode; 187 struct callchain_list *clist; 188 189 /* 190 * adding and deleting hist entries must be done outside of this 191 * function since TEST_ASSERT_VAL() returns in case of failure. 192 */ 193 hists__collapse_resort(hists, NULL); 194 hists__output_resort(hists, NULL); 195 196 if (verbose > 2) { 197 pr_info("use callchain: %d, cumulate callchain: %d\n", 198 symbol_conf.use_callchain, 199 symbol_conf.cumulate_callchain); 200 print_hists_out(hists); 201 } 202 203 root = &hists->entries; 204 for (node = rb_first(root), i = 0; 205 node && (he = rb_entry(node, struct hist_entry, rb_node)); 206 node = rb_next(node), i++) { 207 scnprintf(buf, sizeof(buf), "Invalid hist entry #%zd", i); 208 209 TEST_ASSERT_VAL("Incorrect number of hist entry", 210 i < nr_expected); 211 TEST_ASSERT_VAL(buf, he->stat.period == expected[i].self && 212 !strcmp(COMM(he), expected[i].comm) && 213 !strcmp(DSO(he), expected[i].dso) && 214 !strcmp(SYM(he), expected[i].sym)); 215 216 if (symbol_conf.cumulate_callchain) 217 TEST_ASSERT_VAL(buf, he->stat_acc->period == expected[i].children); 218 219 if (!symbol_conf.use_callchain) 220 continue; 221 222 /* check callchain entries */ 223 root = &he->callchain->node.rb_root; 224 cnode = rb_entry(rb_first(root), struct callchain_node, rb_node); 225 226 c = 0; 227 list_for_each_entry(clist, &cnode->val, list) { 228 scnprintf(buf, sizeof(buf), "Invalid callchain entry #%zd/%zd", i, c); 229 230 TEST_ASSERT_VAL("Incorrect number of callchain entry", 231 c < expected_callchain[i].nr); 232 TEST_ASSERT_VAL(buf, 233 !strcmp(CDSO(clist), expected_callchain[i].node[c].dso) && 234 !strcmp(CSYM(clist), expected_callchain[i].node[c].sym)); 235 c++; 236 } 237 /* TODO: handle multiple child nodes properly */ 238 TEST_ASSERT_VAL("Incorrect number of callchain entry", 239 c <= expected_callchain[i].nr); 240 } 241 TEST_ASSERT_VAL("Incorrect number of hist entry", 242 i == nr_expected); 243 TEST_ASSERT_VAL("Incorrect number of callchain entry", 244 !symbol_conf.use_callchain || nr_expected == nr_callchain); 245 return 0; 246 } 247 248 /* NO callchain + NO children */ 249 static int test1(struct perf_evsel *evsel, struct machine *machine) 250 { 251 int err; 252 struct hists *hists = evsel__hists(evsel); 253 /* 254 * expected output: 255 * 256 * Overhead Command Shared Object Symbol 257 * ======== ======= ============= ============== 258 * 20.00% perf perf [.] main 259 * 10.00% bash [kernel] [k] page_fault 260 * 10.00% bash bash [.] main 261 * 10.00% bash bash [.] xmalloc 262 * 10.00% perf [kernel] [k] page_fault 263 * 10.00% perf [kernel] [k] schedule 264 * 10.00% perf libc [.] free 265 * 10.00% perf libc [.] malloc 266 * 10.00% perf perf [.] cmd_record 267 */ 268 struct result expected[] = { 269 { 0, 2000, "perf", "perf", "main" }, 270 { 0, 1000, "bash", "[kernel]", "page_fault" }, 271 { 0, 1000, "bash", "bash", "main" }, 272 { 0, 1000, "bash", "bash", "xmalloc" }, 273 { 0, 1000, "perf", "[kernel]", "page_fault" }, 274 { 0, 1000, "perf", "[kernel]", "schedule" }, 275 { 0, 1000, "perf", "libc", "free" }, 276 { 0, 1000, "perf", "libc", "malloc" }, 277 { 0, 1000, "perf", "perf", "cmd_record" }, 278 }; 279 280 symbol_conf.use_callchain = false; 281 symbol_conf.cumulate_callchain = false; 282 perf_evsel__reset_sample_bit(evsel, CALLCHAIN); 283 284 setup_sorting(); 285 callchain_register_param(&callchain_param); 286 287 err = add_hist_entries(hists, machine); 288 if (err < 0) 289 goto out; 290 291 err = do_test(hists, expected, ARRAY_SIZE(expected), NULL, 0); 292 293 out: 294 del_hist_entries(hists); 295 reset_output_field(); 296 return err; 297 } 298 299 /* callcain + NO children */ 300 static int test2(struct perf_evsel *evsel, struct machine *machine) 301 { 302 int err; 303 struct hists *hists = evsel__hists(evsel); 304 /* 305 * expected output: 306 * 307 * Overhead Command Shared Object Symbol 308 * ======== ======= ============= ============== 309 * 20.00% perf perf [.] main 310 * | 311 * --- main 312 * 313 * 10.00% bash [kernel] [k] page_fault 314 * | 315 * --- page_fault 316 * malloc 317 * main 318 * 319 * 10.00% bash bash [.] main 320 * | 321 * --- main 322 * 323 * 10.00% bash bash [.] xmalloc 324 * | 325 * --- xmalloc 326 * malloc 327 * xmalloc <--- NOTE: there's a cycle 328 * malloc 329 * xmalloc 330 * main 331 * 332 * 10.00% perf [kernel] [k] page_fault 333 * | 334 * --- page_fault 335 * sys_perf_event_open 336 * run_command 337 * main 338 * 339 * 10.00% perf [kernel] [k] schedule 340 * | 341 * --- schedule 342 * run_command 343 * main 344 * 345 * 10.00% perf libc [.] free 346 * | 347 * --- free 348 * cmd_record 349 * run_command 350 * main 351 * 352 * 10.00% perf libc [.] malloc 353 * | 354 * --- malloc 355 * cmd_record 356 * run_command 357 * main 358 * 359 * 10.00% perf perf [.] cmd_record 360 * | 361 * --- cmd_record 362 * run_command 363 * main 364 * 365 */ 366 struct result expected[] = { 367 { 0, 2000, "perf", "perf", "main" }, 368 { 0, 1000, "bash", "[kernel]", "page_fault" }, 369 { 0, 1000, "bash", "bash", "main" }, 370 { 0, 1000, "bash", "bash", "xmalloc" }, 371 { 0, 1000, "perf", "[kernel]", "page_fault" }, 372 { 0, 1000, "perf", "[kernel]", "schedule" }, 373 { 0, 1000, "perf", "libc", "free" }, 374 { 0, 1000, "perf", "libc", "malloc" }, 375 { 0, 1000, "perf", "perf", "cmd_record" }, 376 }; 377 struct callchain_result expected_callchain[] = { 378 { 379 1, { { "perf", "main" }, }, 380 }, 381 { 382 3, { { "[kernel]", "page_fault" }, 383 { "libc", "malloc" }, 384 { "bash", "main" }, }, 385 }, 386 { 387 1, { { "bash", "main" }, }, 388 }, 389 { 390 6, { { "bash", "xmalloc" }, 391 { "libc", "malloc" }, 392 { "bash", "xmalloc" }, 393 { "libc", "malloc" }, 394 { "bash", "xmalloc" }, 395 { "bash", "main" }, }, 396 }, 397 { 398 4, { { "[kernel]", "page_fault" }, 399 { "[kernel]", "sys_perf_event_open" }, 400 { "perf", "run_command" }, 401 { "perf", "main" }, }, 402 }, 403 { 404 3, { { "[kernel]", "schedule" }, 405 { "perf", "run_command" }, 406 { "perf", "main" }, }, 407 }, 408 { 409 4, { { "libc", "free" }, 410 { "perf", "cmd_record" }, 411 { "perf", "run_command" }, 412 { "perf", "main" }, }, 413 }, 414 { 415 4, { { "libc", "malloc" }, 416 { "perf", "cmd_record" }, 417 { "perf", "run_command" }, 418 { "perf", "main" }, }, 419 }, 420 { 421 3, { { "perf", "cmd_record" }, 422 { "perf", "run_command" }, 423 { "perf", "main" }, }, 424 }, 425 }; 426 427 symbol_conf.use_callchain = true; 428 symbol_conf.cumulate_callchain = false; 429 perf_evsel__set_sample_bit(evsel, CALLCHAIN); 430 431 setup_sorting(); 432 callchain_register_param(&callchain_param); 433 434 err = add_hist_entries(hists, machine); 435 if (err < 0) 436 goto out; 437 438 err = do_test(hists, expected, ARRAY_SIZE(expected), 439 expected_callchain, ARRAY_SIZE(expected_callchain)); 440 441 out: 442 del_hist_entries(hists); 443 reset_output_field(); 444 return err; 445 } 446 447 /* NO callchain + children */ 448 static int test3(struct perf_evsel *evsel, struct machine *machine) 449 { 450 int err; 451 struct hists *hists = evsel__hists(evsel); 452 /* 453 * expected output: 454 * 455 * Children Self Command Shared Object Symbol 456 * ======== ======== ======= ============= ======================= 457 * 70.00% 20.00% perf perf [.] main 458 * 50.00% 0.00% perf perf [.] run_command 459 * 30.00% 10.00% bash bash [.] main 460 * 30.00% 10.00% perf perf [.] cmd_record 461 * 20.00% 0.00% bash libc [.] malloc 462 * 10.00% 10.00% bash [kernel] [k] page_fault 463 * 10.00% 10.00% bash bash [.] xmalloc 464 * 10.00% 10.00% perf [kernel] [k] page_fault 465 * 10.00% 10.00% perf libc [.] malloc 466 * 10.00% 10.00% perf [kernel] [k] schedule 467 * 10.00% 10.00% perf libc [.] free 468 * 10.00% 0.00% perf [kernel] [k] sys_perf_event_open 469 */ 470 struct result expected[] = { 471 { 7000, 2000, "perf", "perf", "main" }, 472 { 5000, 0, "perf", "perf", "run_command" }, 473 { 3000, 1000, "bash", "bash", "main" }, 474 { 3000, 1000, "perf", "perf", "cmd_record" }, 475 { 2000, 0, "bash", "libc", "malloc" }, 476 { 1000, 1000, "bash", "[kernel]", "page_fault" }, 477 { 1000, 1000, "bash", "bash", "xmalloc" }, 478 { 1000, 1000, "perf", "[kernel]", "page_fault" }, 479 { 1000, 1000, "perf", "[kernel]", "schedule" }, 480 { 1000, 1000, "perf", "libc", "free" }, 481 { 1000, 1000, "perf", "libc", "malloc" }, 482 { 1000, 0, "perf", "[kernel]", "sys_perf_event_open" }, 483 }; 484 485 symbol_conf.use_callchain = false; 486 symbol_conf.cumulate_callchain = true; 487 perf_evsel__reset_sample_bit(evsel, CALLCHAIN); 488 489 setup_sorting(); 490 callchain_register_param(&callchain_param); 491 492 err = add_hist_entries(hists, machine); 493 if (err < 0) 494 goto out; 495 496 err = do_test(hists, expected, ARRAY_SIZE(expected), NULL, 0); 497 498 out: 499 del_hist_entries(hists); 500 reset_output_field(); 501 return err; 502 } 503 504 /* callchain + children */ 505 static int test4(struct perf_evsel *evsel, struct machine *machine) 506 { 507 int err; 508 struct hists *hists = evsel__hists(evsel); 509 /* 510 * expected output: 511 * 512 * Children Self Command Shared Object Symbol 513 * ======== ======== ======= ============= ======================= 514 * 70.00% 20.00% perf perf [.] main 515 * | 516 * --- main 517 * 518 * 50.00% 0.00% perf perf [.] run_command 519 * | 520 * --- run_command 521 * main 522 * 523 * 30.00% 10.00% bash bash [.] main 524 * | 525 * --- main 526 * 527 * 30.00% 10.00% perf perf [.] cmd_record 528 * | 529 * --- cmd_record 530 * run_command 531 * main 532 * 533 * 20.00% 0.00% bash libc [.] malloc 534 * | 535 * --- malloc 536 * | 537 * |--50.00%-- xmalloc 538 * | main 539 * --50.00%-- main 540 * 541 * 10.00% 10.00% bash [kernel] [k] page_fault 542 * | 543 * --- page_fault 544 * malloc 545 * main 546 * 547 * 10.00% 10.00% bash bash [.] xmalloc 548 * | 549 * --- xmalloc 550 * malloc 551 * xmalloc <--- NOTE: there's a cycle 552 * malloc 553 * xmalloc 554 * main 555 * 556 * 10.00% 0.00% perf [kernel] [k] sys_perf_event_open 557 * | 558 * --- sys_perf_event_open 559 * run_command 560 * main 561 * 562 * 10.00% 10.00% perf [kernel] [k] page_fault 563 * | 564 * --- page_fault 565 * sys_perf_event_open 566 * run_command 567 * main 568 * 569 * 10.00% 10.00% perf [kernel] [k] schedule 570 * | 571 * --- schedule 572 * run_command 573 * main 574 * 575 * 10.00% 10.00% perf libc [.] free 576 * | 577 * --- free 578 * cmd_record 579 * run_command 580 * main 581 * 582 * 10.00% 10.00% perf libc [.] malloc 583 * | 584 * --- malloc 585 * cmd_record 586 * run_command 587 * main 588 * 589 */ 590 struct result expected[] = { 591 { 7000, 2000, "perf", "perf", "main" }, 592 { 5000, 0, "perf", "perf", "run_command" }, 593 { 3000, 1000, "bash", "bash", "main" }, 594 { 3000, 1000, "perf", "perf", "cmd_record" }, 595 { 2000, 0, "bash", "libc", "malloc" }, 596 { 1000, 1000, "bash", "[kernel]", "page_fault" }, 597 { 1000, 1000, "bash", "bash", "xmalloc" }, 598 { 1000, 0, "perf", "[kernel]", "sys_perf_event_open" }, 599 { 1000, 1000, "perf", "[kernel]", "page_fault" }, 600 { 1000, 1000, "perf", "[kernel]", "schedule" }, 601 { 1000, 1000, "perf", "libc", "free" }, 602 { 1000, 1000, "perf", "libc", "malloc" }, 603 }; 604 struct callchain_result expected_callchain[] = { 605 { 606 1, { { "perf", "main" }, }, 607 }, 608 { 609 2, { { "perf", "run_command" }, 610 { "perf", "main" }, }, 611 }, 612 { 613 1, { { "bash", "main" }, }, 614 }, 615 { 616 3, { { "perf", "cmd_record" }, 617 { "perf", "run_command" }, 618 { "perf", "main" }, }, 619 }, 620 { 621 4, { { "libc", "malloc" }, 622 { "bash", "xmalloc" }, 623 { "bash", "main" }, 624 { "bash", "main" }, }, 625 }, 626 { 627 3, { { "[kernel]", "page_fault" }, 628 { "libc", "malloc" }, 629 { "bash", "main" }, }, 630 }, 631 { 632 6, { { "bash", "xmalloc" }, 633 { "libc", "malloc" }, 634 { "bash", "xmalloc" }, 635 { "libc", "malloc" }, 636 { "bash", "xmalloc" }, 637 { "bash", "main" }, }, 638 }, 639 { 640 3, { { "[kernel]", "sys_perf_event_open" }, 641 { "perf", "run_command" }, 642 { "perf", "main" }, }, 643 }, 644 { 645 4, { { "[kernel]", "page_fault" }, 646 { "[kernel]", "sys_perf_event_open" }, 647 { "perf", "run_command" }, 648 { "perf", "main" }, }, 649 }, 650 { 651 3, { { "[kernel]", "schedule" }, 652 { "perf", "run_command" }, 653 { "perf", "main" }, }, 654 }, 655 { 656 4, { { "libc", "free" }, 657 { "perf", "cmd_record" }, 658 { "perf", "run_command" }, 659 { "perf", "main" }, }, 660 }, 661 { 662 4, { { "libc", "malloc" }, 663 { "perf", "cmd_record" }, 664 { "perf", "run_command" }, 665 { "perf", "main" }, }, 666 }, 667 }; 668 669 symbol_conf.use_callchain = true; 670 symbol_conf.cumulate_callchain = true; 671 perf_evsel__set_sample_bit(evsel, CALLCHAIN); 672 673 setup_sorting(); 674 callchain_register_param(&callchain_param); 675 676 err = add_hist_entries(hists, machine); 677 if (err < 0) 678 goto out; 679 680 err = do_test(hists, expected, ARRAY_SIZE(expected), 681 expected_callchain, ARRAY_SIZE(expected_callchain)); 682 683 out: 684 del_hist_entries(hists); 685 reset_output_field(); 686 return err; 687 } 688 689 int test__hists_cumulate(void) 690 { 691 int err = TEST_FAIL; 692 struct machines machines; 693 struct machine *machine; 694 struct perf_evsel *evsel; 695 struct perf_evlist *evlist = perf_evlist__new(); 696 size_t i; 697 test_fn_t testcases[] = { 698 test1, 699 test2, 700 test3, 701 test4, 702 }; 703 704 TEST_ASSERT_VAL("No memory", evlist); 705 706 err = parse_events(evlist, "cpu-clock", NULL); 707 if (err) 708 goto out; 709 710 machines__init(&machines); 711 712 /* setup threads/dso/map/symbols also */ 713 machine = setup_fake_machine(&machines); 714 if (!machine) 715 goto out; 716 717 if (verbose > 1) 718 machine__fprintf(machine, stderr); 719 720 evsel = perf_evlist__first(evlist); 721 722 for (i = 0; i < ARRAY_SIZE(testcases); i++) { 723 err = testcases[i](evsel, machine); 724 if (err < 0) 725 break; 726 } 727 728 out: 729 /* tear down everything */ 730 perf_evlist__delete(evlist); 731 machines__exit(&machines); 732 733 return err; 734 } 735