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