diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-05-21 03:12:49 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-05-22 10:19:16 -0400 |
commit | f50246e2e2e33aacc68ac3ec41cf2d6a08860bc4 (patch) | |
tree | 68421df5c4808a0163d59a47c91e8fe4fe09f894 /tools | |
parent | 73787190d04a34e6da745da893b3ae8bedde418f (diff) |
perf test: Move parse event automated tests to separated object
Moving event parsing specific tests into separated file:
util/parse-events-test.c
Also changing the code a bit to ease running separate tests.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1337584373-2741-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 1 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 552 | ||||
-rw-r--r-- | tools/perf/util/parse-events-test.c | 600 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 3 |
4 files changed, 605 insertions, 551 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index fa37cd53e9b..91840e17181 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -332,6 +332,7 @@ LIB_OBJS += $(OUTPUT)util/help.o | |||
332 | LIB_OBJS += $(OUTPUT)util/levenshtein.o | 332 | LIB_OBJS += $(OUTPUT)util/levenshtein.o |
333 | LIB_OBJS += $(OUTPUT)util/parse-options.o | 333 | LIB_OBJS += $(OUTPUT)util/parse-options.o |
334 | LIB_OBJS += $(OUTPUT)util/parse-events.o | 334 | LIB_OBJS += $(OUTPUT)util/parse-events.o |
335 | LIB_OBJS += $(OUTPUT)util/parse-events-test.o | ||
335 | LIB_OBJS += $(OUTPUT)util/path.o | 336 | LIB_OBJS += $(OUTPUT)util/path.o |
336 | LIB_OBJS += $(OUTPUT)util/rbtree.o | 337 | LIB_OBJS += $(OUTPUT)util/rbtree.o |
337 | LIB_OBJS += $(OUTPUT)util/bitmap.o | 338 | LIB_OBJS += $(OUTPUT)util/bitmap.o |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 6c47376e29d..5a8727c0875 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -604,556 +604,6 @@ out_free_threads: | |||
604 | #undef nsyscalls | 604 | #undef nsyscalls |
605 | } | 605 | } |
606 | 606 | ||
607 | #define TEST_ASSERT_VAL(text, cond) \ | ||
608 | do { \ | ||
609 | if (!(cond)) { \ | ||
610 | pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ | ||
611 | return -1; \ | ||
612 | } \ | ||
613 | } while (0) | ||
614 | |||
615 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) | ||
616 | { | ||
617 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
618 | struct perf_evsel, node); | ||
619 | |||
620 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
621 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
622 | TEST_ASSERT_VAL("wrong sample_type", | ||
623 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | ||
624 | evsel->attr.sample_type); | ||
625 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) | ||
630 | { | ||
631 | struct perf_evsel *evsel; | ||
632 | |||
633 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | ||
634 | |||
635 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
636 | TEST_ASSERT_VAL("wrong type", | ||
637 | PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
638 | TEST_ASSERT_VAL("wrong sample_type", | ||
639 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) | ||
640 | == evsel->attr.sample_type); | ||
641 | TEST_ASSERT_VAL("wrong sample_period", | ||
642 | 1 == evsel->attr.sample_period); | ||
643 | } | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static int test__checkevent_raw(struct perf_evlist *evlist) | ||
648 | { | ||
649 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
650 | struct perf_evsel, node); | ||
651 | |||
652 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
653 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
654 | TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); | ||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | static int test__checkevent_numeric(struct perf_evlist *evlist) | ||
659 | { | ||
660 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
661 | struct perf_evsel, node); | ||
662 | |||
663 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
664 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | ||
665 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | static int test__checkevent_symbolic_name(struct perf_evlist *evlist) | ||
670 | { | ||
671 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
672 | struct perf_evsel, node); | ||
673 | |||
674 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
675 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | ||
676 | TEST_ASSERT_VAL("wrong config", | ||
677 | PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) | ||
682 | { | ||
683 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
684 | struct perf_evsel, node); | ||
685 | |||
686 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
687 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | ||
688 | TEST_ASSERT_VAL("wrong config", | ||
689 | PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); | ||
690 | TEST_ASSERT_VAL("wrong period", | ||
691 | 100000 == evsel->attr.sample_period); | ||
692 | TEST_ASSERT_VAL("wrong config1", | ||
693 | 0 == evsel->attr.config1); | ||
694 | TEST_ASSERT_VAL("wrong config2", | ||
695 | 1 == evsel->attr.config2); | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) | ||
700 | { | ||
701 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
702 | struct perf_evsel, node); | ||
703 | |||
704 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
705 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); | ||
706 | TEST_ASSERT_VAL("wrong config", | ||
707 | PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static int test__checkevent_genhw(struct perf_evlist *evlist) | ||
712 | { | ||
713 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
714 | struct perf_evsel, node); | ||
715 | |||
716 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
717 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); | ||
718 | TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | static int test__checkevent_breakpoint(struct perf_evlist *evlist) | ||
723 | { | ||
724 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
725 | struct perf_evsel, node); | ||
726 | |||
727 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
728 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
729 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
730 | TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == | ||
731 | evsel->attr.bp_type); | ||
732 | TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == | ||
733 | evsel->attr.bp_len); | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) | ||
738 | { | ||
739 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
740 | struct perf_evsel, node); | ||
741 | |||
742 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
743 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
744 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
745 | TEST_ASSERT_VAL("wrong bp_type", | ||
746 | HW_BREAKPOINT_X == evsel->attr.bp_type); | ||
747 | TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) | ||
752 | { | ||
753 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
754 | struct perf_evsel, node); | ||
755 | |||
756 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
757 | TEST_ASSERT_VAL("wrong type", | ||
758 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
759 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
760 | TEST_ASSERT_VAL("wrong bp_type", | ||
761 | HW_BREAKPOINT_R == evsel->attr.bp_type); | ||
762 | TEST_ASSERT_VAL("wrong bp_len", | ||
763 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) | ||
768 | { | ||
769 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
770 | struct perf_evsel, node); | ||
771 | |||
772 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
773 | TEST_ASSERT_VAL("wrong type", | ||
774 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
775 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
776 | TEST_ASSERT_VAL("wrong bp_type", | ||
777 | HW_BREAKPOINT_W == evsel->attr.bp_type); | ||
778 | TEST_ASSERT_VAL("wrong bp_len", | ||
779 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) | ||
784 | { | ||
785 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
786 | struct perf_evsel, node); | ||
787 | |||
788 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
789 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
790 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
791 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
792 | |||
793 | return test__checkevent_tracepoint(evlist); | ||
794 | } | ||
795 | |||
796 | static int | ||
797 | test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) | ||
798 | { | ||
799 | struct perf_evsel *evsel; | ||
800 | |||
801 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | ||
802 | |||
803 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
804 | TEST_ASSERT_VAL("wrong exclude_user", | ||
805 | !evsel->attr.exclude_user); | ||
806 | TEST_ASSERT_VAL("wrong exclude_kernel", | ||
807 | evsel->attr.exclude_kernel); | ||
808 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
809 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
810 | } | ||
811 | |||
812 | return test__checkevent_tracepoint_multi(evlist); | ||
813 | } | ||
814 | |||
815 | static int test__checkevent_raw_modifier(struct perf_evlist *evlist) | ||
816 | { | ||
817 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
818 | struct perf_evsel, node); | ||
819 | |||
820 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
821 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
822 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
823 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
824 | |||
825 | return test__checkevent_raw(evlist); | ||
826 | } | ||
827 | |||
828 | static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) | ||
829 | { | ||
830 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
831 | struct perf_evsel, node); | ||
832 | |||
833 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
834 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
835 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
836 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
837 | |||
838 | return test__checkevent_numeric(evlist); | ||
839 | } | ||
840 | |||
841 | static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) | ||
842 | { | ||
843 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
844 | struct perf_evsel, node); | ||
845 | |||
846 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
847 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
848 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
849 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
850 | |||
851 | return test__checkevent_symbolic_name(evlist); | ||
852 | } | ||
853 | |||
854 | static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) | ||
855 | { | ||
856 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
857 | struct perf_evsel, node); | ||
858 | |||
859 | TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); | ||
860 | TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); | ||
861 | |||
862 | return test__checkevent_symbolic_name(evlist); | ||
863 | } | ||
864 | |||
865 | static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) | ||
866 | { | ||
867 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
868 | struct perf_evsel, node); | ||
869 | |||
870 | TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); | ||
871 | TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); | ||
872 | |||
873 | return test__checkevent_symbolic_name(evlist); | ||
874 | } | ||
875 | |||
876 | static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) | ||
877 | { | ||
878 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
879 | struct perf_evsel, node); | ||
880 | |||
881 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
882 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
883 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
884 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
885 | |||
886 | return test__checkevent_symbolic_alias(evlist); | ||
887 | } | ||
888 | |||
889 | static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) | ||
890 | { | ||
891 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
892 | struct perf_evsel, node); | ||
893 | |||
894 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
895 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
896 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
897 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
898 | |||
899 | return test__checkevent_genhw(evlist); | ||
900 | } | ||
901 | |||
902 | static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) | ||
903 | { | ||
904 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
905 | struct perf_evsel, node); | ||
906 | |||
907 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
908 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
909 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
910 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
911 | |||
912 | return test__checkevent_breakpoint(evlist); | ||
913 | } | ||
914 | |||
915 | static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) | ||
916 | { | ||
917 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
918 | struct perf_evsel, node); | ||
919 | |||
920 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
921 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
922 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
923 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
924 | |||
925 | return test__checkevent_breakpoint_x(evlist); | ||
926 | } | ||
927 | |||
928 | static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) | ||
929 | { | ||
930 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
931 | struct perf_evsel, node); | ||
932 | |||
933 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
934 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
935 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
936 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
937 | |||
938 | return test__checkevent_breakpoint_r(evlist); | ||
939 | } | ||
940 | |||
941 | static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | ||
942 | { | ||
943 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
944 | struct perf_evsel, node); | ||
945 | |||
946 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
947 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
948 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
949 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
950 | |||
951 | return test__checkevent_breakpoint_w(evlist); | ||
952 | } | ||
953 | |||
954 | static int test__checkevent_pmu(struct perf_evlist *evlist) | ||
955 | { | ||
956 | |||
957 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
958 | struct perf_evsel, node); | ||
959 | |||
960 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
961 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
962 | TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); | ||
963 | TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); | ||
964 | TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); | ||
965 | TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); | ||
966 | |||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static int test__checkevent_list(struct perf_evlist *evlist) | ||
971 | { | ||
972 | struct perf_evsel *evsel; | ||
973 | |||
974 | TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); | ||
975 | |||
976 | /* r1 */ | ||
977 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
978 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
979 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
980 | TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); | ||
981 | TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); | ||
982 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
983 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
984 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
985 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
986 | |||
987 | /* syscalls:sys_enter_open:k */ | ||
988 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | ||
989 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
990 | TEST_ASSERT_VAL("wrong sample_type", | ||
991 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | ||
992 | evsel->attr.sample_type); | ||
993 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | ||
994 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
995 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
996 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
997 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
998 | |||
999 | /* 1:1:hp */ | ||
1000 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | ||
1001 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | ||
1002 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
1003 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
1004 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
1005 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
1006 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | static struct test__event_st { | ||
1012 | const char *name; | ||
1013 | __u32 type; | ||
1014 | int (*check)(struct perf_evlist *evlist); | ||
1015 | } test__events[] = { | ||
1016 | { | ||
1017 | .name = "syscalls:sys_enter_open", | ||
1018 | .check = test__checkevent_tracepoint, | ||
1019 | }, | ||
1020 | { | ||
1021 | .name = "syscalls:*", | ||
1022 | .check = test__checkevent_tracepoint_multi, | ||
1023 | }, | ||
1024 | { | ||
1025 | .name = "r1a", | ||
1026 | .check = test__checkevent_raw, | ||
1027 | }, | ||
1028 | { | ||
1029 | .name = "1:1", | ||
1030 | .check = test__checkevent_numeric, | ||
1031 | }, | ||
1032 | { | ||
1033 | .name = "instructions", | ||
1034 | .check = test__checkevent_symbolic_name, | ||
1035 | }, | ||
1036 | { | ||
1037 | .name = "cycles/period=100000,config2/", | ||
1038 | .check = test__checkevent_symbolic_name_config, | ||
1039 | }, | ||
1040 | { | ||
1041 | .name = "faults", | ||
1042 | .check = test__checkevent_symbolic_alias, | ||
1043 | }, | ||
1044 | { | ||
1045 | .name = "L1-dcache-load-miss", | ||
1046 | .check = test__checkevent_genhw, | ||
1047 | }, | ||
1048 | { | ||
1049 | .name = "mem:0", | ||
1050 | .check = test__checkevent_breakpoint, | ||
1051 | }, | ||
1052 | { | ||
1053 | .name = "mem:0:x", | ||
1054 | .check = test__checkevent_breakpoint_x, | ||
1055 | }, | ||
1056 | { | ||
1057 | .name = "mem:0:r", | ||
1058 | .check = test__checkevent_breakpoint_r, | ||
1059 | }, | ||
1060 | { | ||
1061 | .name = "mem:0:w", | ||
1062 | .check = test__checkevent_breakpoint_w, | ||
1063 | }, | ||
1064 | { | ||
1065 | .name = "syscalls:sys_enter_open:k", | ||
1066 | .check = test__checkevent_tracepoint_modifier, | ||
1067 | }, | ||
1068 | { | ||
1069 | .name = "syscalls:*:u", | ||
1070 | .check = test__checkevent_tracepoint_multi_modifier, | ||
1071 | }, | ||
1072 | { | ||
1073 | .name = "r1a:kp", | ||
1074 | .check = test__checkevent_raw_modifier, | ||
1075 | }, | ||
1076 | { | ||
1077 | .name = "1:1:hp", | ||
1078 | .check = test__checkevent_numeric_modifier, | ||
1079 | }, | ||
1080 | { | ||
1081 | .name = "instructions:h", | ||
1082 | .check = test__checkevent_symbolic_name_modifier, | ||
1083 | }, | ||
1084 | { | ||
1085 | .name = "faults:u", | ||
1086 | .check = test__checkevent_symbolic_alias_modifier, | ||
1087 | }, | ||
1088 | { | ||
1089 | .name = "L1-dcache-load-miss:kp", | ||
1090 | .check = test__checkevent_genhw_modifier, | ||
1091 | }, | ||
1092 | { | ||
1093 | .name = "mem:0:u", | ||
1094 | .check = test__checkevent_breakpoint_modifier, | ||
1095 | }, | ||
1096 | { | ||
1097 | .name = "mem:0:x:k", | ||
1098 | .check = test__checkevent_breakpoint_x_modifier, | ||
1099 | }, | ||
1100 | { | ||
1101 | .name = "mem:0:r:hp", | ||
1102 | .check = test__checkevent_breakpoint_r_modifier, | ||
1103 | }, | ||
1104 | { | ||
1105 | .name = "mem:0:w:up", | ||
1106 | .check = test__checkevent_breakpoint_w_modifier, | ||
1107 | }, | ||
1108 | { | ||
1109 | .name = "cpu/config=10,config1,config2=3,period=1000/u", | ||
1110 | .check = test__checkevent_pmu, | ||
1111 | }, | ||
1112 | { | ||
1113 | .name = "r1,syscalls:sys_enter_open:k,1:1:hp", | ||
1114 | .check = test__checkevent_list, | ||
1115 | }, | ||
1116 | { | ||
1117 | .name = "instructions:G", | ||
1118 | .check = test__checkevent_exclude_host_modifier, | ||
1119 | }, | ||
1120 | { | ||
1121 | .name = "instructions:H", | ||
1122 | .check = test__checkevent_exclude_guest_modifier, | ||
1123 | }, | ||
1124 | }; | ||
1125 | |||
1126 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) | ||
1127 | |||
1128 | static int test__parse_events(void) | ||
1129 | { | ||
1130 | struct perf_evlist *evlist; | ||
1131 | u_int i; | ||
1132 | int ret = 0; | ||
1133 | |||
1134 | for (i = 0; i < TEST__EVENTS_CNT; i++) { | ||
1135 | struct test__event_st *e = &test__events[i]; | ||
1136 | |||
1137 | evlist = perf_evlist__new(NULL, NULL); | ||
1138 | if (evlist == NULL) | ||
1139 | break; | ||
1140 | |||
1141 | ret = parse_events(evlist, e->name, 0); | ||
1142 | if (ret) { | ||
1143 | pr_debug("failed to parse event '%s', err %d\n", | ||
1144 | e->name, ret); | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | ret = e->check(evlist); | ||
1149 | perf_evlist__delete(evlist); | ||
1150 | if (ret) | ||
1151 | break; | ||
1152 | } | ||
1153 | |||
1154 | return ret; | ||
1155 | } | ||
1156 | |||
1157 | static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, | 607 | static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, |
1158 | size_t *sizep) | 608 | size_t *sizep) |
1159 | { | 609 | { |
@@ -1675,7 +1125,7 @@ static struct test { | |||
1675 | }, | 1125 | }, |
1676 | { | 1126 | { |
1677 | .desc = "parse events tests", | 1127 | .desc = "parse events tests", |
1678 | .func = test__parse_events, | 1128 | .func = parse_events__test, |
1679 | }, | 1129 | }, |
1680 | #if defined(__x86_64__) || defined(__i386__) | 1130 | #if defined(__x86_64__) || defined(__i386__) |
1681 | { | 1131 | { |
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c new file mode 100644 index 00000000000..2e8f435384a --- /dev/null +++ b/tools/perf/util/parse-events-test.c | |||
@@ -0,0 +1,600 @@ | |||
1 | |||
2 | #include "parse-events.h" | ||
3 | #include "evsel.h" | ||
4 | #include "evlist.h" | ||
5 | #include "sysfs.h" | ||
6 | #include "../../../include/linux/hw_breakpoint.h" | ||
7 | |||
8 | #define TEST_ASSERT_VAL(text, cond) \ | ||
9 | do { \ | ||
10 | if (!(cond)) { \ | ||
11 | pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ | ||
12 | return -1; \ | ||
13 | } \ | ||
14 | } while (0) | ||
15 | |||
16 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) | ||
17 | { | ||
18 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
19 | struct perf_evsel, node); | ||
20 | |||
21 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
22 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
23 | TEST_ASSERT_VAL("wrong sample_type", | ||
24 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | ||
25 | evsel->attr.sample_type); | ||
26 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) | ||
31 | { | ||
32 | struct perf_evsel *evsel; | ||
33 | |||
34 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | ||
35 | |||
36 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
37 | TEST_ASSERT_VAL("wrong type", | ||
38 | PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
39 | TEST_ASSERT_VAL("wrong sample_type", | ||
40 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) | ||
41 | == evsel->attr.sample_type); | ||
42 | TEST_ASSERT_VAL("wrong sample_period", | ||
43 | 1 == evsel->attr.sample_period); | ||
44 | } | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static int test__checkevent_raw(struct perf_evlist *evlist) | ||
49 | { | ||
50 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
51 | struct perf_evsel, node); | ||
52 | |||
53 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
54 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
55 | TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int test__checkevent_numeric(struct perf_evlist *evlist) | ||
60 | { | ||
61 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
62 | struct perf_evsel, node); | ||
63 | |||
64 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
65 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | ||
66 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int test__checkevent_symbolic_name(struct perf_evlist *evlist) | ||
71 | { | ||
72 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
73 | struct perf_evsel, node); | ||
74 | |||
75 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
76 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | ||
77 | TEST_ASSERT_VAL("wrong config", | ||
78 | PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) | ||
83 | { | ||
84 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
85 | struct perf_evsel, node); | ||
86 | |||
87 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
88 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | ||
89 | TEST_ASSERT_VAL("wrong config", | ||
90 | PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); | ||
91 | TEST_ASSERT_VAL("wrong period", | ||
92 | 100000 == evsel->attr.sample_period); | ||
93 | TEST_ASSERT_VAL("wrong config1", | ||
94 | 0 == evsel->attr.config1); | ||
95 | TEST_ASSERT_VAL("wrong config2", | ||
96 | 1 == evsel->attr.config2); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) | ||
101 | { | ||
102 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
103 | struct perf_evsel, node); | ||
104 | |||
105 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
106 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); | ||
107 | TEST_ASSERT_VAL("wrong config", | ||
108 | PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int test__checkevent_genhw(struct perf_evlist *evlist) | ||
113 | { | ||
114 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
115 | struct perf_evsel, node); | ||
116 | |||
117 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
118 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); | ||
119 | TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int test__checkevent_breakpoint(struct perf_evlist *evlist) | ||
124 | { | ||
125 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
126 | struct perf_evsel, node); | ||
127 | |||
128 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
129 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
130 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
131 | TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == | ||
132 | evsel->attr.bp_type); | ||
133 | TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == | ||
134 | evsel->attr.bp_len); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) | ||
139 | { | ||
140 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
141 | struct perf_evsel, node); | ||
142 | |||
143 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
144 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
145 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
146 | TEST_ASSERT_VAL("wrong bp_type", | ||
147 | HW_BREAKPOINT_X == evsel->attr.bp_type); | ||
148 | TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) | ||
153 | { | ||
154 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
155 | struct perf_evsel, node); | ||
156 | |||
157 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
158 | TEST_ASSERT_VAL("wrong type", | ||
159 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
160 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
161 | TEST_ASSERT_VAL("wrong bp_type", | ||
162 | HW_BREAKPOINT_R == evsel->attr.bp_type); | ||
163 | TEST_ASSERT_VAL("wrong bp_len", | ||
164 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) | ||
169 | { | ||
170 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
171 | struct perf_evsel, node); | ||
172 | |||
173 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
174 | TEST_ASSERT_VAL("wrong type", | ||
175 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
176 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
177 | TEST_ASSERT_VAL("wrong bp_type", | ||
178 | HW_BREAKPOINT_W == evsel->attr.bp_type); | ||
179 | TEST_ASSERT_VAL("wrong bp_len", | ||
180 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) | ||
185 | { | ||
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
187 | struct perf_evsel, node); | ||
188 | |||
189 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
190 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
191 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
192 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
193 | |||
194 | return test__checkevent_tracepoint(evlist); | ||
195 | } | ||
196 | |||
197 | static int | ||
198 | test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) | ||
199 | { | ||
200 | struct perf_evsel *evsel; | ||
201 | |||
202 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | ||
203 | |||
204 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
205 | TEST_ASSERT_VAL("wrong exclude_user", | ||
206 | !evsel->attr.exclude_user); | ||
207 | TEST_ASSERT_VAL("wrong exclude_kernel", | ||
208 | evsel->attr.exclude_kernel); | ||
209 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
210 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
211 | } | ||
212 | |||
213 | return test__checkevent_tracepoint_multi(evlist); | ||
214 | } | ||
215 | |||
216 | static int test__checkevent_raw_modifier(struct perf_evlist *evlist) | ||
217 | { | ||
218 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
219 | struct perf_evsel, node); | ||
220 | |||
221 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
222 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
223 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
224 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
225 | |||
226 | return test__checkevent_raw(evlist); | ||
227 | } | ||
228 | |||
229 | static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) | ||
230 | { | ||
231 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
232 | struct perf_evsel, node); | ||
233 | |||
234 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
235 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
236 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
237 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
238 | |||
239 | return test__checkevent_numeric(evlist); | ||
240 | } | ||
241 | |||
242 | static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) | ||
243 | { | ||
244 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
245 | struct perf_evsel, node); | ||
246 | |||
247 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
248 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
249 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
250 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
251 | |||
252 | return test__checkevent_symbolic_name(evlist); | ||
253 | } | ||
254 | |||
255 | static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) | ||
256 | { | ||
257 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
258 | struct perf_evsel, node); | ||
259 | |||
260 | TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); | ||
261 | TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); | ||
262 | |||
263 | return test__checkevent_symbolic_name(evlist); | ||
264 | } | ||
265 | |||
266 | static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) | ||
267 | { | ||
268 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
269 | struct perf_evsel, node); | ||
270 | |||
271 | TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); | ||
272 | TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); | ||
273 | |||
274 | return test__checkevent_symbolic_name(evlist); | ||
275 | } | ||
276 | |||
277 | static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) | ||
278 | { | ||
279 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
280 | struct perf_evsel, node); | ||
281 | |||
282 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
283 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
284 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
285 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
286 | |||
287 | return test__checkevent_symbolic_alias(evlist); | ||
288 | } | ||
289 | |||
290 | static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) | ||
291 | { | ||
292 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
293 | struct perf_evsel, node); | ||
294 | |||
295 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
296 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
297 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
298 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
299 | |||
300 | return test__checkevent_genhw(evlist); | ||
301 | } | ||
302 | |||
303 | static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) | ||
304 | { | ||
305 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
306 | struct perf_evsel, node); | ||
307 | |||
308 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
309 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
310 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
311 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
312 | |||
313 | return test__checkevent_breakpoint(evlist); | ||
314 | } | ||
315 | |||
316 | static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) | ||
317 | { | ||
318 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
319 | struct perf_evsel, node); | ||
320 | |||
321 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
322 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
323 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
324 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
325 | |||
326 | return test__checkevent_breakpoint_x(evlist); | ||
327 | } | ||
328 | |||
329 | static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) | ||
330 | { | ||
331 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
332 | struct perf_evsel, node); | ||
333 | |||
334 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
335 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
336 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
337 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
338 | |||
339 | return test__checkevent_breakpoint_r(evlist); | ||
340 | } | ||
341 | |||
342 | static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | ||
343 | { | ||
344 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
345 | struct perf_evsel, node); | ||
346 | |||
347 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
348 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
349 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
350 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
351 | |||
352 | return test__checkevent_breakpoint_w(evlist); | ||
353 | } | ||
354 | |||
355 | static int test__checkevent_pmu(struct perf_evlist *evlist) | ||
356 | { | ||
357 | |||
358 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
359 | struct perf_evsel, node); | ||
360 | |||
361 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
362 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
363 | TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); | ||
364 | TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); | ||
365 | TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); | ||
366 | TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int test__checkevent_list(struct perf_evlist *evlist) | ||
372 | { | ||
373 | struct perf_evsel *evsel; | ||
374 | |||
375 | TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); | ||
376 | |||
377 | /* r1 */ | ||
378 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
379 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
380 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
381 | TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); | ||
382 | TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); | ||
383 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | ||
384 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
385 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
386 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
387 | |||
388 | /* syscalls:sys_enter_open:k */ | ||
389 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | ||
390 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | ||
391 | TEST_ASSERT_VAL("wrong sample_type", | ||
392 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | ||
393 | evsel->attr.sample_type); | ||
394 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | ||
395 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
396 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
397 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
398 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
399 | |||
400 | /* 1:1:hp */ | ||
401 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | ||
402 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | ||
403 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | ||
404 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
405 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | ||
406 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | ||
407 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | struct test__event_st { | ||
413 | const char *name; | ||
414 | __u32 type; | ||
415 | int (*check)(struct perf_evlist *evlist); | ||
416 | }; | ||
417 | |||
418 | static struct test__event_st test__events[] = { | ||
419 | [0] = { | ||
420 | .name = "syscalls:sys_enter_open", | ||
421 | .check = test__checkevent_tracepoint, | ||
422 | }, | ||
423 | [1] = { | ||
424 | .name = "syscalls:*", | ||
425 | .check = test__checkevent_tracepoint_multi, | ||
426 | }, | ||
427 | [2] = { | ||
428 | .name = "r1a", | ||
429 | .check = test__checkevent_raw, | ||
430 | }, | ||
431 | [3] = { | ||
432 | .name = "1:1", | ||
433 | .check = test__checkevent_numeric, | ||
434 | }, | ||
435 | [4] = { | ||
436 | .name = "instructions", | ||
437 | .check = test__checkevent_symbolic_name, | ||
438 | }, | ||
439 | [5] = { | ||
440 | .name = "cycles/period=100000,config2/", | ||
441 | .check = test__checkevent_symbolic_name_config, | ||
442 | }, | ||
443 | [6] = { | ||
444 | .name = "faults", | ||
445 | .check = test__checkevent_symbolic_alias, | ||
446 | }, | ||
447 | [7] = { | ||
448 | .name = "L1-dcache-load-miss", | ||
449 | .check = test__checkevent_genhw, | ||
450 | }, | ||
451 | [8] = { | ||
452 | .name = "mem:0", | ||
453 | .check = test__checkevent_breakpoint, | ||
454 | }, | ||
455 | [9] = { | ||
456 | .name = "mem:0:x", | ||
457 | .check = test__checkevent_breakpoint_x, | ||
458 | }, | ||
459 | [10] = { | ||
460 | .name = "mem:0:r", | ||
461 | .check = test__checkevent_breakpoint_r, | ||
462 | }, | ||
463 | [11] = { | ||
464 | .name = "mem:0:w", | ||
465 | .check = test__checkevent_breakpoint_w, | ||
466 | }, | ||
467 | [12] = { | ||
468 | .name = "syscalls:sys_enter_open:k", | ||
469 | .check = test__checkevent_tracepoint_modifier, | ||
470 | }, | ||
471 | [13] = { | ||
472 | .name = "syscalls:*:u", | ||
473 | .check = test__checkevent_tracepoint_multi_modifier, | ||
474 | }, | ||
475 | [14] = { | ||
476 | .name = "r1a:kp", | ||
477 | .check = test__checkevent_raw_modifier, | ||
478 | }, | ||
479 | [15] = { | ||
480 | .name = "1:1:hp", | ||
481 | .check = test__checkevent_numeric_modifier, | ||
482 | }, | ||
483 | [16] = { | ||
484 | .name = "instructions:h", | ||
485 | .check = test__checkevent_symbolic_name_modifier, | ||
486 | }, | ||
487 | [17] = { | ||
488 | .name = "faults:u", | ||
489 | .check = test__checkevent_symbolic_alias_modifier, | ||
490 | }, | ||
491 | [18] = { | ||
492 | .name = "L1-dcache-load-miss:kp", | ||
493 | .check = test__checkevent_genhw_modifier, | ||
494 | }, | ||
495 | [19] = { | ||
496 | .name = "mem:0:u", | ||
497 | .check = test__checkevent_breakpoint_modifier, | ||
498 | }, | ||
499 | [20] = { | ||
500 | .name = "mem:0:x:k", | ||
501 | .check = test__checkevent_breakpoint_x_modifier, | ||
502 | }, | ||
503 | [21] = { | ||
504 | .name = "mem:0:r:hp", | ||
505 | .check = test__checkevent_breakpoint_r_modifier, | ||
506 | }, | ||
507 | [22] = { | ||
508 | .name = "mem:0:w:up", | ||
509 | .check = test__checkevent_breakpoint_w_modifier, | ||
510 | }, | ||
511 | [23] = { | ||
512 | .name = "r1,syscalls:sys_enter_open:k,1:1:hp", | ||
513 | .check = test__checkevent_list, | ||
514 | }, | ||
515 | [24] = { | ||
516 | .name = "instructions:G", | ||
517 | .check = test__checkevent_exclude_host_modifier, | ||
518 | }, | ||
519 | [25] = { | ||
520 | .name = "instructions:H", | ||
521 | .check = test__checkevent_exclude_guest_modifier, | ||
522 | }, | ||
523 | }; | ||
524 | |||
525 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) | ||
526 | |||
527 | static struct test__event_st test__events_pmu[] = { | ||
528 | [0] = { | ||
529 | .name = "cpu/config=10,config1,config2=3,period=1000/u", | ||
530 | .check = test__checkevent_pmu, | ||
531 | }, | ||
532 | }; | ||
533 | |||
534 | #define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ | ||
535 | sizeof(struct test__event_st)) | ||
536 | |||
537 | static int test(struct test__event_st *e) | ||
538 | { | ||
539 | struct perf_evlist *evlist; | ||
540 | int ret; | ||
541 | |||
542 | evlist = perf_evlist__new(NULL, NULL); | ||
543 | if (evlist == NULL) | ||
544 | return -ENOMEM; | ||
545 | |||
546 | ret = parse_events(evlist, e->name, 0); | ||
547 | if (ret) { | ||
548 | pr_debug("failed to parse event '%s', err %d\n", | ||
549 | e->name, ret); | ||
550 | return ret; | ||
551 | } | ||
552 | |||
553 | ret = e->check(evlist); | ||
554 | perf_evlist__delete(evlist); | ||
555 | |||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | static int test_events(struct test__event_st *events, unsigned cnt) | ||
560 | { | ||
561 | int ret = 0; | ||
562 | unsigned i; | ||
563 | |||
564 | for (i = 0; i < cnt; i++) { | ||
565 | struct test__event_st *e = &events[i]; | ||
566 | |||
567 | pr_debug("running test %d '%s'\n", i, e->name); | ||
568 | ret = test(e); | ||
569 | if (ret) | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | return ret; | ||
574 | } | ||
575 | |||
576 | static int test_pmu(void) | ||
577 | { | ||
578 | struct stat st; | ||
579 | char path[PATH_MAX]; | ||
580 | int ret; | ||
581 | |||
582 | snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/", | ||
583 | sysfs_find_mountpoint()); | ||
584 | |||
585 | ret = stat(path, &st); | ||
586 | if (ret) | ||
587 | pr_debug("ommiting PMU cpu tests\n"); | ||
588 | return !ret; | ||
589 | } | ||
590 | |||
591 | int parse_events__test(void) | ||
592 | { | ||
593 | int ret; | ||
594 | |||
595 | ret = test_events(test__events, TEST__EVENTS_CNT); | ||
596 | if (!ret && test_pmu()) | ||
597 | ret = test_events(test__events_pmu, TEST__EVENTS_PMU_CNT); | ||
598 | |||
599 | return ret; | ||
600 | } | ||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 3fddd610d35..d287adc2bb6 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -4,7 +4,9 @@ | |||
4 | * Parse symbolic events/counts passed in as options: | 4 | * Parse symbolic events/counts passed in as options: |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/list.h> | ||
7 | #include <stdbool.h> | 8 | #include <stdbool.h> |
9 | #include "types.h" | ||
8 | #include "../../../include/linux/perf_event.h" | 10 | #include "../../../include/linux/perf_event.h" |
9 | #include "types.h" | 11 | #include "types.h" |
10 | 12 | ||
@@ -86,6 +88,7 @@ void parse_events_update_lists(struct list_head *list_event, | |||
86 | void parse_events_error(struct list_head *list_all, | 88 | void parse_events_error(struct list_head *list_all, |
87 | struct list_head *list_event, | 89 | struct list_head *list_event, |
88 | int *idx, char const *msg); | 90 | int *idx, char const *msg); |
91 | int parse_events__test(void); | ||
89 | 92 | ||
90 | void print_events(const char *event_glob); | 93 | void print_events(const char *event_glob); |
91 | void print_events_type(u8 type); | 94 | void print_events_type(u8 type); |