linux/tools/perf/tests/hists_output.c
<<
>>
Prefs
   1#include "perf.h"
   2#include "util/debug.h"
   3#include "util/event.h"
   4#include "util/symbol.h"
   5#include "util/sort.h"
   6#include "util/evsel.h"
   7#include "util/evlist.h"
   8#include "util/machine.h"
   9#include "util/thread.h"
  10#include "util/parse-events.h"
  11#include "tests/tests.h"
  12#include "tests/hists_common.h"
  13#include <linux/kernel.h>
  14
  15struct sample {
  16        u32 cpu;
  17        u32 pid;
  18        u64 ip;
  19        struct thread *thread;
  20        struct map *map;
  21        struct symbol *sym;
  22};
  23
  24/* For the numbers, see hists_common.c */
  25static struct sample fake_samples[] = {
  26        /* perf [kernel] schedule() */
  27        { .cpu = 0, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
  28        /* perf [perf]   main() */
  29        { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, },
  30        /* perf [perf]   cmd_record() */
  31        { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_CMD_RECORD, },
  32        /* perf [libc]   malloc() */
  33        { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
  34        /* perf [libc]   free() */
  35        { .cpu = 2, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_FREE, },
  36        /* perf [perf]   main() */
  37        { .cpu = 2, .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },
  38        /* perf [kernel] page_fault() */
  39        { .cpu = 2, .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
  40        /* bash [bash]   main() */
  41        { .cpu = 3, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_MAIN, },
  42        /* bash [bash]   xmalloc() */
  43        { .cpu = 0, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_XMALLOC, },
  44        /* bash [kernel] page_fault() */
  45        { .cpu = 1, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
  46};
  47
  48static int add_hist_entries(struct hists *hists, struct machine *machine)
  49{
  50        struct addr_location al;
  51        struct perf_evsel *evsel = hists_to_evsel(hists);
  52        struct perf_sample sample = { .period = 100, };
  53        size_t i;
  54
  55        for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
  56                struct hist_entry_iter iter = {
  57                        .evsel = evsel,
  58                        .sample = &sample,
  59                        .ops = &hist_iter_normal,
  60                        .hide_unresolved = false,
  61                };
  62
  63                sample.cpumode = PERF_RECORD_MISC_USER;
  64                sample.cpu = fake_samples[i].cpu;
  65                sample.pid = fake_samples[i].pid;
  66                sample.tid = fake_samples[i].pid;
  67                sample.ip = fake_samples[i].ip;
  68
  69                if (machine__resolve(machine, &al, &sample) < 0)
  70                        goto out;
  71
  72                if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack,
  73                                         NULL) < 0) {
  74                        addr_location__put(&al);
  75                        goto out;
  76                }
  77
  78                fake_samples[i].thread = al.thread;
  79                fake_samples[i].map = al.map;
  80                fake_samples[i].sym = al.sym;
  81        }
  82
  83        return TEST_OK;
  84
  85out:
  86        pr_debug("Not enough memory for adding a hist entry\n");
  87        return TEST_FAIL;
  88}
  89
  90static void del_hist_entries(struct hists *hists)
  91{
  92        struct hist_entry *he;
  93        struct rb_root *root_in;
  94        struct rb_root *root_out;
  95        struct rb_node *node;
  96
  97        if (hists__has(hists, need_collapse))
  98                root_in = &hists->entries_collapsed;
  99        else
 100                root_in = hists->entries_in;
 101
 102        root_out = &hists->entries;
 103
 104        while (!RB_EMPTY_ROOT(root_out)) {
 105                node = rb_first(root_out);
 106
 107                he = rb_entry(node, struct hist_entry, rb_node);
 108                rb_erase(node, root_out);
 109                rb_erase(&he->rb_node_in, root_in);
 110                hist_entry__delete(he);
 111        }
 112}
 113
 114typedef int (*test_fn_t)(struct perf_evsel *, struct machine *);
 115
 116#define COMM(he)  (thread__comm_str(he->thread))
 117#define DSO(he)   (he->ms.map->dso->short_name)
 118#define SYM(he)   (he->ms.sym->name)
 119#define CPU(he)   (he->cpu)
 120#define PID(he)   (he->thread->tid)
 121
 122/* default sort keys (no field) */
 123static int test1(struct perf_evsel *evsel, struct machine *machine)
 124{
 125        int err;
 126        struct hists *hists = evsel__hists(evsel);
 127        struct hist_entry *he;
 128        struct rb_root *root;
 129        struct rb_node *node;
 130
 131        field_order = NULL;
 132        sort_order = NULL; /* equivalent to sort_order = "comm,dso,sym" */
 133
 134        setup_sorting(NULL);
 135
 136        /*
 137         * expected output:
 138         *
 139         * Overhead  Command  Shared Object          Symbol
 140         * ========  =======  =============  ==============
 141         *   20.00%     perf  perf           [.] main
 142         *   10.00%     bash  [kernel]       [k] page_fault
 143         *   10.00%     bash  bash           [.] main
 144         *   10.00%     bash  bash           [.] xmalloc
 145         *   10.00%     perf  [kernel]       [k] page_fault
 146         *   10.00%     perf  [kernel]       [k] schedule
 147         *   10.00%     perf  libc           [.] free
 148         *   10.00%     perf  libc           [.] malloc
 149         *   10.00%     perf  perf           [.] cmd_record
 150         */
 151        err = add_hist_entries(hists, machine);
 152        if (err < 0)
 153                goto out;
 154
 155        hists__collapse_resort(hists, NULL);
 156        perf_evsel__output_resort(evsel, NULL);
 157
 158        if (verbose > 2) {
 159                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
 160                print_hists_out(hists);
 161        }
 162
 163        root = &hists->entries;
 164        node = rb_first(root);
 165        he = rb_entry(node, struct hist_entry, rb_node);
 166        TEST_ASSERT_VAL("Invalid hist entry",
 167                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 168                        !strcmp(SYM(he), "main") && he->stat.period == 200);
 169
 170        node = rb_next(node);
 171        he = rb_entry(node, struct hist_entry, rb_node);
 172        TEST_ASSERT_VAL("Invalid hist entry",
 173                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
 174                        !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
 175
 176        node = rb_next(node);
 177        he = rb_entry(node, struct hist_entry, rb_node);
 178        TEST_ASSERT_VAL("Invalid hist entry",
 179                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
 180                        !strcmp(SYM(he), "main") && he->stat.period == 100);
 181
 182        node = rb_next(node);
 183        he = rb_entry(node, struct hist_entry, rb_node);
 184        TEST_ASSERT_VAL("Invalid hist entry",
 185                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
 186                        !strcmp(SYM(he), "xmalloc") && he->stat.period == 100);
 187
 188        node = rb_next(node);
 189        he = rb_entry(node, struct hist_entry, rb_node);
 190        TEST_ASSERT_VAL("Invalid hist entry",
 191                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
 192                        !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
 193
 194        node = rb_next(node);
 195        he = rb_entry(node, struct hist_entry, rb_node);
 196        TEST_ASSERT_VAL("Invalid hist entry",
 197                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
 198                        !strcmp(SYM(he), "schedule") && he->stat.period == 100);
 199
 200        node = rb_next(node);
 201        he = rb_entry(node, struct hist_entry, rb_node);
 202        TEST_ASSERT_VAL("Invalid hist entry",
 203                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
 204                        !strcmp(SYM(he), "free") && he->stat.period == 100);
 205
 206        node = rb_next(node);
 207        he = rb_entry(node, struct hist_entry, rb_node);
 208        TEST_ASSERT_VAL("Invalid hist entry",
 209                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
 210                        !strcmp(SYM(he), "malloc") && he->stat.period == 100);
 211
 212        node = rb_next(node);
 213        he = rb_entry(node, struct hist_entry, rb_node);
 214        TEST_ASSERT_VAL("Invalid hist entry",
 215                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 216                        !strcmp(SYM(he), "cmd_record") && he->stat.period == 100);
 217
 218out:
 219        del_hist_entries(hists);
 220        reset_output_field();
 221        return err;
 222}
 223
 224/* mixed fields and sort keys */
 225static int test2(struct perf_evsel *evsel, struct machine *machine)
 226{
 227        int err;
 228        struct hists *hists = evsel__hists(evsel);
 229        struct hist_entry *he;
 230        struct rb_root *root;
 231        struct rb_node *node;
 232
 233        field_order = "overhead,cpu";
 234        sort_order = "pid";
 235
 236        setup_sorting(NULL);
 237
 238        /*
 239         * expected output:
 240         *
 241         * Overhead  CPU  Command:  Pid
 242         * ========  ===  =============
 243         *   30.00%    1  perf   :  100
 244         *   10.00%    0  perf   :  100
 245         *   10.00%    2  perf   :  100
 246         *   20.00%    2  perf   :  200
 247         *   10.00%    0  bash   :  300
 248         *   10.00%    1  bash   :  300
 249         *   10.00%    3  bash   :  300
 250         */
 251        err = add_hist_entries(hists, machine);
 252        if (err < 0)
 253                goto out;
 254
 255        hists__collapse_resort(hists, NULL);
 256        perf_evsel__output_resort(evsel, NULL);
 257
 258        if (verbose > 2) {
 259                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
 260                print_hists_out(hists);
 261        }
 262
 263        root = &hists->entries;
 264        node = rb_first(root);
 265        he = rb_entry(node, struct hist_entry, rb_node);
 266        TEST_ASSERT_VAL("Invalid hist entry",
 267                        CPU(he) == 1 && PID(he) == 100 && he->stat.period == 300);
 268
 269        node = rb_next(node);
 270        he = rb_entry(node, struct hist_entry, rb_node);
 271        TEST_ASSERT_VAL("Invalid hist entry",
 272                        CPU(he) == 0 && PID(he) == 100 && he->stat.period == 100);
 273
 274out:
 275        del_hist_entries(hists);
 276        reset_output_field();
 277        return err;
 278}
 279
 280/* fields only (no sort key) */
 281static int test3(struct perf_evsel *evsel, struct machine *machine)
 282{
 283        int err;
 284        struct hists *hists = evsel__hists(evsel);
 285        struct hist_entry *he;
 286        struct rb_root *root;
 287        struct rb_node *node;
 288
 289        field_order = "comm,overhead,dso";
 290        sort_order = NULL;
 291
 292        setup_sorting(NULL);
 293
 294        /*
 295         * expected output:
 296         *
 297         * Command  Overhead  Shared Object
 298         * =======  ========  =============
 299         *    bash    20.00%  bash
 300         *    bash    10.00%  [kernel]
 301         *    perf    30.00%  perf
 302         *    perf    20.00%  [kernel]
 303         *    perf    20.00%  libc
 304         */
 305        err = add_hist_entries(hists, machine);
 306        if (err < 0)
 307                goto out;
 308
 309        hists__collapse_resort(hists, NULL);
 310        perf_evsel__output_resort(evsel, NULL);
 311
 312        if (verbose > 2) {
 313                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
 314                print_hists_out(hists);
 315        }
 316
 317        root = &hists->entries;
 318        node = rb_first(root);
 319        he = rb_entry(node, struct hist_entry, rb_node);
 320        TEST_ASSERT_VAL("Invalid hist entry",
 321                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
 322                        he->stat.period == 200);
 323
 324        node = rb_next(node);
 325        he = rb_entry(node, struct hist_entry, rb_node);
 326        TEST_ASSERT_VAL("Invalid hist entry",
 327                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
 328                        he->stat.period == 100);
 329
 330        node = rb_next(node);
 331        he = rb_entry(node, struct hist_entry, rb_node);
 332        TEST_ASSERT_VAL("Invalid hist entry",
 333                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 334                        he->stat.period == 300);
 335
 336        node = rb_next(node);
 337        he = rb_entry(node, struct hist_entry, rb_node);
 338        TEST_ASSERT_VAL("Invalid hist entry",
 339                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
 340                        he->stat.period == 200);
 341
 342        node = rb_next(node);
 343        he = rb_entry(node, struct hist_entry, rb_node);
 344        TEST_ASSERT_VAL("Invalid hist entry",
 345                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
 346                        he->stat.period == 200);
 347
 348out:
 349        del_hist_entries(hists);
 350        reset_output_field();
 351        return err;
 352}
 353
 354/* handle duplicate 'dso' field */
 355static int test4(struct perf_evsel *evsel, struct machine *machine)
 356{
 357        int err;
 358        struct hists *hists = evsel__hists(evsel);
 359        struct hist_entry *he;
 360        struct rb_root *root;
 361        struct rb_node *node;
 362
 363        field_order = "dso,sym,comm,overhead,dso";
 364        sort_order = "sym";
 365
 366        setup_sorting(NULL);
 367
 368        /*
 369         * expected output:
 370         *
 371         * Shared Object          Symbol  Command  Overhead
 372         * =============  ==============  =======  ========
 373         *          perf  [.] cmd_record     perf    10.00%
 374         *          libc  [.] free           perf    10.00%
 375         *          bash  [.] main           bash    10.00%
 376         *          perf  [.] main           perf    20.00%
 377         *          libc  [.] malloc         perf    10.00%
 378         *      [kernel]  [k] page_fault     bash    10.00%
 379         *      [kernel]  [k] page_fault     perf    10.00%
 380         *      [kernel]  [k] schedule       perf    10.00%
 381         *          bash  [.] xmalloc        bash    10.00%
 382         */
 383        err = add_hist_entries(hists, machine);
 384        if (err < 0)
 385                goto out;
 386
 387        hists__collapse_resort(hists, NULL);
 388        perf_evsel__output_resort(evsel, NULL);
 389
 390        if (verbose > 2) {
 391                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
 392                print_hists_out(hists);
 393        }
 394
 395        root = &hists->entries;
 396        node = rb_first(root);
 397        he = rb_entry(node, struct hist_entry, rb_node);
 398        TEST_ASSERT_VAL("Invalid hist entry",
 399                        !strcmp(DSO(he), "perf") && !strcmp(SYM(he), "cmd_record") &&
 400                        !strcmp(COMM(he), "perf") && he->stat.period == 100);
 401
 402        node = rb_next(node);
 403        he = rb_entry(node, struct hist_entry, rb_node);
 404        TEST_ASSERT_VAL("Invalid hist entry",
 405                        !strcmp(DSO(he), "libc") && !strcmp(SYM(he), "free") &&
 406                        !strcmp(COMM(he), "perf") && he->stat.period == 100);
 407
 408        node = rb_next(node);
 409        he = rb_entry(node, struct hist_entry, rb_node);
 410        TEST_ASSERT_VAL("Invalid hist entry",
 411                        !strcmp(DSO(he), "bash") && !strcmp(SYM(he), "main") &&
 412                        !strcmp(COMM(he), "bash") && he->stat.period == 100);
 413
 414        node = rb_next(node);
 415        he = rb_entry(node, struct hist_entry, rb_node);
 416        TEST_ASSERT_VAL("Invalid hist entry",
 417                        !strcmp(DSO(he), "perf") && !strcmp(SYM(he), "main") &&
 418                        !strcmp(COMM(he), "perf") && he->stat.period == 200);
 419
 420        node = rb_next(node);
 421        he = rb_entry(node, struct hist_entry, rb_node);
 422        TEST_ASSERT_VAL("Invalid hist entry",
 423                        !strcmp(DSO(he), "libc") && !strcmp(SYM(he), "malloc") &&
 424                        !strcmp(COMM(he), "perf") && he->stat.period == 100);
 425
 426        node = rb_next(node);
 427        he = rb_entry(node, struct hist_entry, rb_node);
 428        TEST_ASSERT_VAL("Invalid hist entry",
 429                        !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "page_fault") &&
 430                        !strcmp(COMM(he), "bash") && he->stat.period == 100);
 431
 432        node = rb_next(node);
 433        he = rb_entry(node, struct hist_entry, rb_node);
 434        TEST_ASSERT_VAL("Invalid hist entry",
 435                        !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "page_fault") &&
 436                        !strcmp(COMM(he), "perf") && he->stat.period == 100);
 437
 438        node = rb_next(node);
 439        he = rb_entry(node, struct hist_entry, rb_node);
 440        TEST_ASSERT_VAL("Invalid hist entry",
 441                        !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "schedule") &&
 442                        !strcmp(COMM(he), "perf") && he->stat.period == 100);
 443
 444        node = rb_next(node);
 445        he = rb_entry(node, struct hist_entry, rb_node);
 446        TEST_ASSERT_VAL("Invalid hist entry",
 447                        !strcmp(DSO(he), "bash") && !strcmp(SYM(he), "xmalloc") &&
 448                        !strcmp(COMM(he), "bash") && he->stat.period == 100);
 449
 450out:
 451        del_hist_entries(hists);
 452        reset_output_field();
 453        return err;
 454}
 455
 456/* full sort keys w/o overhead field */
 457static int test5(struct perf_evsel *evsel, struct machine *machine)
 458{
 459        int err;
 460        struct hists *hists = evsel__hists(evsel);
 461        struct hist_entry *he;
 462        struct rb_root *root;
 463        struct rb_node *node;
 464
 465        field_order = "cpu,pid,comm,dso,sym";
 466        sort_order = "dso,pid";
 467
 468        setup_sorting(NULL);
 469
 470        /*
 471         * expected output:
 472         *
 473         * CPU  Command:  Pid  Command  Shared Object          Symbol
 474         * ===  =============  =======  =============  ==============
 475         *   0     perf:  100     perf       [kernel]  [k] schedule
 476         *   2     perf:  200     perf       [kernel]  [k] page_fault
 477         *   1     bash:  300     bash       [kernel]  [k] page_fault
 478         *   0     bash:  300     bash           bash  [.] xmalloc
 479         *   3     bash:  300     bash           bash  [.] main
 480         *   1     perf:  100     perf           libc  [.] malloc
 481         *   2     perf:  100     perf           libc  [.] free
 482         *   1     perf:  100     perf           perf  [.] cmd_record
 483         *   1     perf:  100     perf           perf  [.] main
 484         *   2     perf:  200     perf           perf  [.] main
 485         */
 486        err = add_hist_entries(hists, machine);
 487        if (err < 0)
 488                goto out;
 489
 490        hists__collapse_resort(hists, NULL);
 491        perf_evsel__output_resort(evsel, NULL);
 492
 493        if (verbose > 2) {
 494                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
 495                print_hists_out(hists);
 496        }
 497
 498        root = &hists->entries;
 499        node = rb_first(root);
 500        he = rb_entry(node, struct hist_entry, rb_node);
 501
 502        TEST_ASSERT_VAL("Invalid hist entry",
 503                        CPU(he) == 0 && PID(he) == 100 &&
 504                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
 505                        !strcmp(SYM(he), "schedule") && he->stat.period == 100);
 506
 507        node = rb_next(node);
 508        he = rb_entry(node, struct hist_entry, rb_node);
 509        TEST_ASSERT_VAL("Invalid hist entry",
 510                        CPU(he) == 2 && PID(he) == 200 &&
 511                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
 512                        !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
 513
 514        node = rb_next(node);
 515        he = rb_entry(node, struct hist_entry, rb_node);
 516        TEST_ASSERT_VAL("Invalid hist entry",
 517                        CPU(he) == 1 && PID(he) == 300 &&
 518                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
 519                        !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
 520
 521        node = rb_next(node);
 522        he = rb_entry(node, struct hist_entry, rb_node);
 523        TEST_ASSERT_VAL("Invalid hist entry",
 524                        CPU(he) == 0 && PID(he) == 300 &&
 525                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
 526                        !strcmp(SYM(he), "xmalloc") && he->stat.period == 100);
 527
 528        node = rb_next(node);
 529        he = rb_entry(node, struct hist_entry, rb_node);
 530        TEST_ASSERT_VAL("Invalid hist entry",
 531                        CPU(he) == 3 && PID(he) == 300 &&
 532                        !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
 533                        !strcmp(SYM(he), "main") && he->stat.period == 100);
 534
 535        node = rb_next(node);
 536        he = rb_entry(node, struct hist_entry, rb_node);
 537        TEST_ASSERT_VAL("Invalid hist entry",
 538                        CPU(he) == 1 && PID(he) == 100 &&
 539                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
 540                        !strcmp(SYM(he), "malloc") && he->stat.period == 100);
 541
 542        node = rb_next(node);
 543        he = rb_entry(node, struct hist_entry, rb_node);
 544        TEST_ASSERT_VAL("Invalid hist entry",
 545                        CPU(he) == 2 && PID(he) == 100 &&
 546                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
 547                        !strcmp(SYM(he), "free") && he->stat.period == 100);
 548
 549        node = rb_next(node);
 550        he = rb_entry(node, struct hist_entry, rb_node);
 551        TEST_ASSERT_VAL("Invalid hist entry",
 552                        CPU(he) == 1 && PID(he) == 100 &&
 553                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 554                        !strcmp(SYM(he), "cmd_record") && he->stat.period == 100);
 555
 556        node = rb_next(node);
 557        he = rb_entry(node, struct hist_entry, rb_node);
 558        TEST_ASSERT_VAL("Invalid hist entry",
 559                        CPU(he) == 1 && PID(he) == 100 &&
 560                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 561                        !strcmp(SYM(he), "main") && he->stat.period == 100);
 562
 563        node = rb_next(node);
 564        he = rb_entry(node, struct hist_entry, rb_node);
 565        TEST_ASSERT_VAL("Invalid hist entry",
 566                        CPU(he) == 2 && PID(he) == 200 &&
 567                        !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
 568                        !strcmp(SYM(he), "main") && he->stat.period == 100);
 569
 570out:
 571        del_hist_entries(hists);
 572        reset_output_field();
 573        return err;
 574}
 575
 576int test__hists_output(int subtest __maybe_unused)
 577{
 578        int err = TEST_FAIL;
 579        struct machines machines;
 580        struct machine *machine;
 581        struct perf_evsel *evsel;
 582        struct perf_evlist *evlist = perf_evlist__new();
 583        size_t i;
 584        test_fn_t testcases[] = {
 585                test1,
 586                test2,
 587                test3,
 588                test4,
 589                test5,
 590        };
 591
 592        TEST_ASSERT_VAL("No memory", evlist);
 593
 594        err = parse_events(evlist, "cpu-clock", NULL);
 595        if (err)
 596                goto out;
 597        err = TEST_FAIL;
 598
 599        machines__init(&machines);
 600
 601        /* setup threads/dso/map/symbols also */
 602        machine = setup_fake_machine(&machines);
 603        if (!machine)
 604                goto out;
 605
 606        if (verbose > 1)
 607                machine__fprintf(machine, stderr);
 608
 609        evsel = perf_evlist__first(evlist);
 610
 611        for (i = 0; i < ARRAY_SIZE(testcases); i++) {
 612                err = testcases[i](evsel, machine);
 613                if (err < 0)
 614                        break;
 615        }
 616
 617out:
 618        /* tear down everything */
 619        perf_evlist__delete(evlist);
 620        machines__exit(&machines);
 621
 622        return err;
 623}
 624