Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include "util/debug.h"
0003 #include "util/dso.h"
0004 #include "util/event.h"
0005 #include "util/map.h"
0006 #include "util/symbol.h"
0007 #include "util/sort.h"
0008 #include "util/evsel.h"
0009 #include "util/evlist.h"
0010 #include "util/machine.h"
0011 #include "util/thread.h"
0012 #include "util/parse-events.h"
0013 #include "tests/tests.h"
0014 #include "tests/hists_common.h"
0015 #include <linux/kernel.h>
0016 
0017 struct sample {
0018     u32 cpu;
0019     u32 pid;
0020     u64 ip;
0021     struct thread *thread;
0022     struct map *map;
0023     struct symbol *sym;
0024 };
0025 
0026 /* For the numbers, see hists_common.c */
0027 static struct sample fake_samples[] = {
0028     /* perf [kernel] schedule() */
0029     { .cpu = 0, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
0030     /* perf [perf]   main() */
0031     { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, },
0032     /* perf [perf]   cmd_record() */
0033     { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_CMD_RECORD, },
0034     /* perf [libc]   malloc() */
0035     { .cpu = 1, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
0036     /* perf [libc]   free() */
0037     { .cpu = 2, .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_FREE, },
0038     /* perf [perf]   main() */
0039     { .cpu = 2, .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, },
0040     /* perf [kernel] page_fault() */
0041     { .cpu = 2, .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
0042     /* bash [bash]   main() */
0043     { .cpu = 3, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_MAIN, },
0044     /* bash [bash]   xmalloc() */
0045     { .cpu = 0, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_BASH_XMALLOC, },
0046     /* bash [kernel] page_fault() */
0047     { .cpu = 1, .pid = FAKE_PID_BASH,  .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
0048 };
0049 
0050 static int add_hist_entries(struct hists *hists, struct machine *machine)
0051 {
0052     struct addr_location al;
0053     struct evsel *evsel = hists_to_evsel(hists);
0054     struct perf_sample sample = { .period = 100, };
0055     size_t i;
0056 
0057     for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
0058         struct hist_entry_iter iter = {
0059             .evsel = evsel,
0060             .sample = &sample,
0061             .ops = &hist_iter_normal,
0062             .hide_unresolved = false,
0063         };
0064 
0065         sample.cpumode = PERF_RECORD_MISC_USER;
0066         sample.cpu = fake_samples[i].cpu;
0067         sample.pid = fake_samples[i].pid;
0068         sample.tid = fake_samples[i].pid;
0069         sample.ip = fake_samples[i].ip;
0070 
0071         if (machine__resolve(machine, &al, &sample) < 0)
0072             goto out;
0073 
0074         if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack,
0075                      NULL) < 0) {
0076             addr_location__put(&al);
0077             goto out;
0078         }
0079 
0080         fake_samples[i].thread = al.thread;
0081         fake_samples[i].map = al.map;
0082         fake_samples[i].sym = al.sym;
0083     }
0084 
0085     return TEST_OK;
0086 
0087 out:
0088     pr_debug("Not enough memory for adding a hist entry\n");
0089     return TEST_FAIL;
0090 }
0091 
0092 static void del_hist_entries(struct hists *hists)
0093 {
0094     struct hist_entry *he;
0095     struct rb_root_cached *root_in;
0096     struct rb_root_cached *root_out;
0097     struct rb_node *node;
0098 
0099     if (hists__has(hists, need_collapse))
0100         root_in = &hists->entries_collapsed;
0101     else
0102         root_in = hists->entries_in;
0103 
0104     root_out = &hists->entries;
0105 
0106     while (!RB_EMPTY_ROOT(&root_out->rb_root)) {
0107         node = rb_first_cached(root_out);
0108 
0109         he = rb_entry(node, struct hist_entry, rb_node);
0110         rb_erase_cached(node, root_out);
0111         rb_erase_cached(&he->rb_node_in, root_in);
0112         hist_entry__delete(he);
0113     }
0114 }
0115 
0116 typedef int (*test_fn_t)(struct evsel *, struct machine *);
0117 
0118 #define COMM(he)  (thread__comm_str(he->thread))
0119 #define DSO(he)   (he->ms.map->dso->short_name)
0120 #define SYM(he)   (he->ms.sym->name)
0121 #define CPU(he)   (he->cpu)
0122 #define PID(he)   (he->thread->tid)
0123 
0124 /* default sort keys (no field) */
0125 static int test1(struct evsel *evsel, struct machine *machine)
0126 {
0127     int err;
0128     struct hists *hists = evsel__hists(evsel);
0129     struct hist_entry *he;
0130     struct rb_root_cached *root;
0131     struct rb_node *node;
0132 
0133     field_order = NULL;
0134     sort_order = NULL; /* equivalent to sort_order = "comm,dso,sym" */
0135 
0136     setup_sorting(NULL);
0137 
0138     /*
0139      * expected output:
0140      *
0141      * Overhead  Command  Shared Object          Symbol
0142      * ========  =======  =============  ==============
0143      *   20.00%     perf  perf           [.] main
0144      *   10.00%     bash  [kernel]       [k] page_fault
0145      *   10.00%     bash  bash           [.] main
0146      *   10.00%     bash  bash           [.] xmalloc
0147      *   10.00%     perf  [kernel]       [k] page_fault
0148      *   10.00%     perf  [kernel]       [k] schedule
0149      *   10.00%     perf  libc           [.] free
0150      *   10.00%     perf  libc           [.] malloc
0151      *   10.00%     perf  perf           [.] cmd_record
0152      */
0153     err = add_hist_entries(hists, machine);
0154     if (err < 0)
0155         goto out;
0156 
0157     hists__collapse_resort(hists, NULL);
0158     evsel__output_resort(evsel, NULL);
0159 
0160     if (verbose > 2) {
0161         pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
0162         print_hists_out(hists);
0163     }
0164 
0165     root = &hists->entries;
0166     node = rb_first_cached(root);
0167     he = rb_entry(node, struct hist_entry, rb_node);
0168     TEST_ASSERT_VAL("Invalid hist entry",
0169             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0170             !strcmp(SYM(he), "main") && he->stat.period == 200);
0171 
0172     node = rb_next(node);
0173     he = rb_entry(node, struct hist_entry, rb_node);
0174     TEST_ASSERT_VAL("Invalid hist entry",
0175             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
0176             !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
0177 
0178     node = rb_next(node);
0179     he = rb_entry(node, struct hist_entry, rb_node);
0180     TEST_ASSERT_VAL("Invalid hist entry",
0181             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
0182             !strcmp(SYM(he), "main") && he->stat.period == 100);
0183 
0184     node = rb_next(node);
0185     he = rb_entry(node, struct hist_entry, rb_node);
0186     TEST_ASSERT_VAL("Invalid hist entry",
0187             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
0188             !strcmp(SYM(he), "xmalloc") && he->stat.period == 100);
0189 
0190     node = rb_next(node);
0191     he = rb_entry(node, struct hist_entry, rb_node);
0192     TEST_ASSERT_VAL("Invalid hist entry",
0193             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
0194             !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
0195 
0196     node = rb_next(node);
0197     he = rb_entry(node, struct hist_entry, rb_node);
0198     TEST_ASSERT_VAL("Invalid hist entry",
0199             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
0200             !strcmp(SYM(he), "schedule") && he->stat.period == 100);
0201 
0202     node = rb_next(node);
0203     he = rb_entry(node, struct hist_entry, rb_node);
0204     TEST_ASSERT_VAL("Invalid hist entry",
0205             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
0206             !strcmp(SYM(he), "free") && he->stat.period == 100);
0207 
0208     node = rb_next(node);
0209     he = rb_entry(node, struct hist_entry, rb_node);
0210     TEST_ASSERT_VAL("Invalid hist entry",
0211             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
0212             !strcmp(SYM(he), "malloc") && he->stat.period == 100);
0213 
0214     node = rb_next(node);
0215     he = rb_entry(node, struct hist_entry, rb_node);
0216     TEST_ASSERT_VAL("Invalid hist entry",
0217             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0218             !strcmp(SYM(he), "cmd_record") && he->stat.period == 100);
0219 
0220 out:
0221     del_hist_entries(hists);
0222     reset_output_field();
0223     return err;
0224 }
0225 
0226 /* mixed fields and sort keys */
0227 static int test2(struct evsel *evsel, struct machine *machine)
0228 {
0229     int err;
0230     struct hists *hists = evsel__hists(evsel);
0231     struct hist_entry *he;
0232     struct rb_root_cached *root;
0233     struct rb_node *node;
0234 
0235     field_order = "overhead,cpu";
0236     sort_order = "pid";
0237 
0238     setup_sorting(NULL);
0239 
0240     /*
0241      * expected output:
0242      *
0243      * Overhead  CPU  Command:  Pid
0244      * ========  ===  =============
0245      *   30.00%    1  perf   :  100
0246      *   10.00%    0  perf   :  100
0247      *   10.00%    2  perf   :  100
0248      *   20.00%    2  perf   :  200
0249      *   10.00%    0  bash   :  300
0250      *   10.00%    1  bash   :  300
0251      *   10.00%    3  bash   :  300
0252      */
0253     err = add_hist_entries(hists, machine);
0254     if (err < 0)
0255         goto out;
0256 
0257     hists__collapse_resort(hists, NULL);
0258     evsel__output_resort(evsel, NULL);
0259 
0260     if (verbose > 2) {
0261         pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
0262         print_hists_out(hists);
0263     }
0264 
0265     root = &hists->entries;
0266     node = rb_first_cached(root);
0267     he = rb_entry(node, struct hist_entry, rb_node);
0268     TEST_ASSERT_VAL("Invalid hist entry",
0269             CPU(he) == 1 && PID(he) == 100 && he->stat.period == 300);
0270 
0271     node = rb_next(node);
0272     he = rb_entry(node, struct hist_entry, rb_node);
0273     TEST_ASSERT_VAL("Invalid hist entry",
0274             CPU(he) == 0 && PID(he) == 100 && he->stat.period == 100);
0275 
0276 out:
0277     del_hist_entries(hists);
0278     reset_output_field();
0279     return err;
0280 }
0281 
0282 /* fields only (no sort key) */
0283 static int test3(struct evsel *evsel, struct machine *machine)
0284 {
0285     int err;
0286     struct hists *hists = evsel__hists(evsel);
0287     struct hist_entry *he;
0288     struct rb_root_cached *root;
0289     struct rb_node *node;
0290 
0291     field_order = "comm,overhead,dso";
0292     sort_order = NULL;
0293 
0294     setup_sorting(NULL);
0295 
0296     /*
0297      * expected output:
0298      *
0299      * Command  Overhead  Shared Object
0300      * =======  ========  =============
0301      *    bash    20.00%  bash
0302      *    bash    10.00%  [kernel]
0303      *    perf    30.00%  perf
0304      *    perf    20.00%  [kernel]
0305      *    perf    20.00%  libc
0306      */
0307     err = add_hist_entries(hists, machine);
0308     if (err < 0)
0309         goto out;
0310 
0311     hists__collapse_resort(hists, NULL);
0312     evsel__output_resort(evsel, NULL);
0313 
0314     if (verbose > 2) {
0315         pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
0316         print_hists_out(hists);
0317     }
0318 
0319     root = &hists->entries;
0320     node = rb_first_cached(root);
0321     he = rb_entry(node, struct hist_entry, rb_node);
0322     TEST_ASSERT_VAL("Invalid hist entry",
0323             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
0324             he->stat.period == 200);
0325 
0326     node = rb_next(node);
0327     he = rb_entry(node, struct hist_entry, rb_node);
0328     TEST_ASSERT_VAL("Invalid hist entry",
0329             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
0330             he->stat.period == 100);
0331 
0332     node = rb_next(node);
0333     he = rb_entry(node, struct hist_entry, rb_node);
0334     TEST_ASSERT_VAL("Invalid hist entry",
0335             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0336             he->stat.period == 300);
0337 
0338     node = rb_next(node);
0339     he = rb_entry(node, struct hist_entry, rb_node);
0340     TEST_ASSERT_VAL("Invalid hist entry",
0341             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
0342             he->stat.period == 200);
0343 
0344     node = rb_next(node);
0345     he = rb_entry(node, struct hist_entry, rb_node);
0346     TEST_ASSERT_VAL("Invalid hist entry",
0347             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
0348             he->stat.period == 200);
0349 
0350 out:
0351     del_hist_entries(hists);
0352     reset_output_field();
0353     return err;
0354 }
0355 
0356 /* handle duplicate 'dso' field */
0357 static int test4(struct evsel *evsel, struct machine *machine)
0358 {
0359     int err;
0360     struct hists *hists = evsel__hists(evsel);
0361     struct hist_entry *he;
0362     struct rb_root_cached *root;
0363     struct rb_node *node;
0364 
0365     field_order = "dso,sym,comm,overhead,dso";
0366     sort_order = "sym";
0367 
0368     setup_sorting(NULL);
0369 
0370     /*
0371      * expected output:
0372      *
0373      * Shared Object          Symbol  Command  Overhead
0374      * =============  ==============  =======  ========
0375      *          perf  [.] cmd_record     perf    10.00%
0376      *          libc  [.] free           perf    10.00%
0377      *          bash  [.] main           bash    10.00%
0378      *          perf  [.] main           perf    20.00%
0379      *          libc  [.] malloc         perf    10.00%
0380      *      [kernel]  [k] page_fault     bash    10.00%
0381      *      [kernel]  [k] page_fault     perf    10.00%
0382      *      [kernel]  [k] schedule       perf    10.00%
0383      *          bash  [.] xmalloc        bash    10.00%
0384      */
0385     err = add_hist_entries(hists, machine);
0386     if (err < 0)
0387         goto out;
0388 
0389     hists__collapse_resort(hists, NULL);
0390     evsel__output_resort(evsel, NULL);
0391 
0392     if (verbose > 2) {
0393         pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
0394         print_hists_out(hists);
0395     }
0396 
0397     root = &hists->entries;
0398     node = rb_first_cached(root);
0399     he = rb_entry(node, struct hist_entry, rb_node);
0400     TEST_ASSERT_VAL("Invalid hist entry",
0401             !strcmp(DSO(he), "perf") && !strcmp(SYM(he), "cmd_record") &&
0402             !strcmp(COMM(he), "perf") && he->stat.period == 100);
0403 
0404     node = rb_next(node);
0405     he = rb_entry(node, struct hist_entry, rb_node);
0406     TEST_ASSERT_VAL("Invalid hist entry",
0407             !strcmp(DSO(he), "libc") && !strcmp(SYM(he), "free") &&
0408             !strcmp(COMM(he), "perf") && he->stat.period == 100);
0409 
0410     node = rb_next(node);
0411     he = rb_entry(node, struct hist_entry, rb_node);
0412     TEST_ASSERT_VAL("Invalid hist entry",
0413             !strcmp(DSO(he), "bash") && !strcmp(SYM(he), "main") &&
0414             !strcmp(COMM(he), "bash") && he->stat.period == 100);
0415 
0416     node = rb_next(node);
0417     he = rb_entry(node, struct hist_entry, rb_node);
0418     TEST_ASSERT_VAL("Invalid hist entry",
0419             !strcmp(DSO(he), "perf") && !strcmp(SYM(he), "main") &&
0420             !strcmp(COMM(he), "perf") && he->stat.period == 200);
0421 
0422     node = rb_next(node);
0423     he = rb_entry(node, struct hist_entry, rb_node);
0424     TEST_ASSERT_VAL("Invalid hist entry",
0425             !strcmp(DSO(he), "libc") && !strcmp(SYM(he), "malloc") &&
0426             !strcmp(COMM(he), "perf") && he->stat.period == 100);
0427 
0428     node = rb_next(node);
0429     he = rb_entry(node, struct hist_entry, rb_node);
0430     TEST_ASSERT_VAL("Invalid hist entry",
0431             !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "page_fault") &&
0432             !strcmp(COMM(he), "bash") && he->stat.period == 100);
0433 
0434     node = rb_next(node);
0435     he = rb_entry(node, struct hist_entry, rb_node);
0436     TEST_ASSERT_VAL("Invalid hist entry",
0437             !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "page_fault") &&
0438             !strcmp(COMM(he), "perf") && he->stat.period == 100);
0439 
0440     node = rb_next(node);
0441     he = rb_entry(node, struct hist_entry, rb_node);
0442     TEST_ASSERT_VAL("Invalid hist entry",
0443             !strcmp(DSO(he), "[kernel]") && !strcmp(SYM(he), "schedule") &&
0444             !strcmp(COMM(he), "perf") && he->stat.period == 100);
0445 
0446     node = rb_next(node);
0447     he = rb_entry(node, struct hist_entry, rb_node);
0448     TEST_ASSERT_VAL("Invalid hist entry",
0449             !strcmp(DSO(he), "bash") && !strcmp(SYM(he), "xmalloc") &&
0450             !strcmp(COMM(he), "bash") && he->stat.period == 100);
0451 
0452 out:
0453     del_hist_entries(hists);
0454     reset_output_field();
0455     return err;
0456 }
0457 
0458 /* full sort keys w/o overhead field */
0459 static int test5(struct evsel *evsel, struct machine *machine)
0460 {
0461     int err;
0462     struct hists *hists = evsel__hists(evsel);
0463     struct hist_entry *he;
0464     struct rb_root_cached *root;
0465     struct rb_node *node;
0466 
0467     field_order = "cpu,pid,comm,dso,sym";
0468     sort_order = "dso,pid";
0469 
0470     setup_sorting(NULL);
0471 
0472     /*
0473      * expected output:
0474      *
0475      * CPU  Command:  Pid  Command  Shared Object          Symbol
0476      * ===  =============  =======  =============  ==============
0477      *   0     perf:  100     perf       [kernel]  [k] schedule
0478      *   2     perf:  200     perf       [kernel]  [k] page_fault
0479      *   1     bash:  300     bash       [kernel]  [k] page_fault
0480      *   0     bash:  300     bash           bash  [.] xmalloc
0481      *   3     bash:  300     bash           bash  [.] main
0482      *   1     perf:  100     perf           libc  [.] malloc
0483      *   2     perf:  100     perf           libc  [.] free
0484      *   1     perf:  100     perf           perf  [.] cmd_record
0485      *   1     perf:  100     perf           perf  [.] main
0486      *   2     perf:  200     perf           perf  [.] main
0487      */
0488     err = add_hist_entries(hists, machine);
0489     if (err < 0)
0490         goto out;
0491 
0492     hists__collapse_resort(hists, NULL);
0493     evsel__output_resort(evsel, NULL);
0494 
0495     if (verbose > 2) {
0496         pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
0497         print_hists_out(hists);
0498     }
0499 
0500     root = &hists->entries;
0501     node = rb_first_cached(root);
0502     he = rb_entry(node, struct hist_entry, rb_node);
0503 
0504     TEST_ASSERT_VAL("Invalid hist entry",
0505             CPU(he) == 0 && PID(he) == 100 &&
0506             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
0507             !strcmp(SYM(he), "schedule") && he->stat.period == 100);
0508 
0509     node = rb_next(node);
0510     he = rb_entry(node, struct hist_entry, rb_node);
0511     TEST_ASSERT_VAL("Invalid hist entry",
0512             CPU(he) == 2 && PID(he) == 200 &&
0513             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "[kernel]") &&
0514             !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
0515 
0516     node = rb_next(node);
0517     he = rb_entry(node, struct hist_entry, rb_node);
0518     TEST_ASSERT_VAL("Invalid hist entry",
0519             CPU(he) == 1 && PID(he) == 300 &&
0520             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "[kernel]") &&
0521             !strcmp(SYM(he), "page_fault") && he->stat.period == 100);
0522 
0523     node = rb_next(node);
0524     he = rb_entry(node, struct hist_entry, rb_node);
0525     TEST_ASSERT_VAL("Invalid hist entry",
0526             CPU(he) == 0 && PID(he) == 300 &&
0527             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
0528             !strcmp(SYM(he), "xmalloc") && he->stat.period == 100);
0529 
0530     node = rb_next(node);
0531     he = rb_entry(node, struct hist_entry, rb_node);
0532     TEST_ASSERT_VAL("Invalid hist entry",
0533             CPU(he) == 3 && PID(he) == 300 &&
0534             !strcmp(COMM(he), "bash") && !strcmp(DSO(he), "bash") &&
0535             !strcmp(SYM(he), "main") && he->stat.period == 100);
0536 
0537     node = rb_next(node);
0538     he = rb_entry(node, struct hist_entry, rb_node);
0539     TEST_ASSERT_VAL("Invalid hist entry",
0540             CPU(he) == 1 && PID(he) == 100 &&
0541             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
0542             !strcmp(SYM(he), "malloc") && he->stat.period == 100);
0543 
0544     node = rb_next(node);
0545     he = rb_entry(node, struct hist_entry, rb_node);
0546     TEST_ASSERT_VAL("Invalid hist entry",
0547             CPU(he) == 2 && PID(he) == 100 &&
0548             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "libc") &&
0549             !strcmp(SYM(he), "free") && he->stat.period == 100);
0550 
0551     node = rb_next(node);
0552     he = rb_entry(node, struct hist_entry, rb_node);
0553     TEST_ASSERT_VAL("Invalid hist entry",
0554             CPU(he) == 1 && PID(he) == 100 &&
0555             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0556             !strcmp(SYM(he), "cmd_record") && he->stat.period == 100);
0557 
0558     node = rb_next(node);
0559     he = rb_entry(node, struct hist_entry, rb_node);
0560     TEST_ASSERT_VAL("Invalid hist entry",
0561             CPU(he) == 1 && PID(he) == 100 &&
0562             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0563             !strcmp(SYM(he), "main") && he->stat.period == 100);
0564 
0565     node = rb_next(node);
0566     he = rb_entry(node, struct hist_entry, rb_node);
0567     TEST_ASSERT_VAL("Invalid hist entry",
0568             CPU(he) == 2 && PID(he) == 200 &&
0569             !strcmp(COMM(he), "perf") && !strcmp(DSO(he), "perf") &&
0570             !strcmp(SYM(he), "main") && he->stat.period == 100);
0571 
0572 out:
0573     del_hist_entries(hists);
0574     reset_output_field();
0575     return err;
0576 }
0577 
0578 static int test__hists_output(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
0579 {
0580     int err = TEST_FAIL;
0581     struct machines machines;
0582     struct machine *machine;
0583     struct evsel *evsel;
0584     struct evlist *evlist = evlist__new();
0585     size_t i;
0586     test_fn_t testcases[] = {
0587         test1,
0588         test2,
0589         test3,
0590         test4,
0591         test5,
0592     };
0593 
0594     TEST_ASSERT_VAL("No memory", evlist);
0595 
0596     err = parse_event(evlist, "cpu-clock");
0597     if (err)
0598         goto out;
0599     err = TEST_FAIL;
0600 
0601     machines__init(&machines);
0602 
0603     /* setup threads/dso/map/symbols also */
0604     machine = setup_fake_machine(&machines);
0605     if (!machine)
0606         goto out;
0607 
0608     if (verbose > 1)
0609         machine__fprintf(machine, stderr);
0610 
0611     evsel = evlist__first(evlist);
0612 
0613     for (i = 0; i < ARRAY_SIZE(testcases); i++) {
0614         err = testcases[i](evsel, machine);
0615         if (err < 0)
0616             break;
0617     }
0618 
0619 out:
0620     /* tear down everything */
0621     evlist__delete(evlist);
0622     machines__exit(&machines);
0623 
0624     return err;
0625 }
0626 
0627 DEFINE_SUITE("Sort output of hist entries", hists_output);