1#!/bin/bash
2# perf stat CSV output linter
3# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4# Tests various perf stat CSV output commands for the
5# correct number of fields and the CSV separator set to ','.
6
7set -e
8
9function commachecker()
10{
11	local -i cnt=0 exp=0
12
13	case "$1"
14	in "--no-args")		exp=6
15	;; "--system-wide")	exp=6
16	;; "--event")		exp=6
17	;; "--interval")	exp=7
18	;; "--per-thread")	exp=7
19	;; "--system-wide-no-aggr")	exp=7
20				[ $(uname -m) = "s390x" ] && exp=6
21	;; "--per-core")	exp=8
22	;; "--per-socket")	exp=8
23	;; "--per-node")	exp=8
24	;; "--per-die")		exp=8
25	esac
26
27	while read line
28	do
29		# Check for lines beginning with Failed
30		x=${line:0:6}
31		[ "$x" = "Failed" ] && continue
32
33		# Count the number of commas
34		x=$(echo $line | tr -d -c ',')
35		cnt="${#x}"
36		# echo $line $cnt
37		[ "$cnt" -ne "$exp" ] && {
38			echo "wrong number of fields. expected $exp in $line" 1>&2
39			exit 1;
40		}
41	done
42	return 0
43}
44
45# Return true if perf_event_paranoid is > $1 and not running as root.
46function ParanoidAndNotRoot()
47{
48	 [ $(id -u) != 0 ] && [ $(cat /proc/sys/kernel/perf_event_paranoid) -gt $1 ]
49}
50
51check_no_args()
52{
53	echo -n "Checking CSV output: no args "
54	perf stat -x, true 2>&1 | commachecker --no-args
55	echo "[Success]"
56}
57
58check_system_wide()
59{
60	echo -n "Checking CSV output: system wide "
61	if ParanoidAndNotRoot 0
62	then
63		echo "[Skip] paranoid and not root"
64		return
65	fi
66	perf stat -x, -a true 2>&1 | commachecker --system-wide
67	echo "[Success]"
68}
69
70check_system_wide_no_aggr()
71{
72	echo -n "Checking CSV output: system wide "
73	if ParanoidAndNotRoot 0
74	then
75		echo "[Skip] paranoid and not root"
76		return
77	fi
78	echo -n "Checking CSV output: system wide no aggregation "
79	perf stat -x, -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr
80	echo "[Success]"
81}
82
83check_interval()
84{
85	echo -n "Checking CSV output: interval "
86	perf stat -x, -I 1000 true 2>&1 | commachecker --interval
87	echo "[Success]"
88}
89
90
91check_event()
92{
93	echo -n "Checking CSV output: event "
94	perf stat -x, -e cpu-clock true 2>&1 | commachecker --event
95	echo "[Success]"
96}
97
98check_per_core()
99{
100	echo -n "Checking CSV output: per core "
101	if ParanoidAndNotRoot 0
102	then
103		echo "[Skip] paranoid and not root"
104		return
105	fi
106	perf stat -x, --per-core -a true 2>&1 | commachecker --per-core
107	echo "[Success]"
108}
109
110check_per_thread()
111{
112	echo -n "Checking CSV output: per thread "
113	if ParanoidAndNotRoot 0
114	then
115		echo "[Skip] paranoid and not root"
116		return
117	fi
118	perf stat -x, --per-thread -a true 2>&1 | commachecker --per-thread
119	echo "[Success]"
120}
121
122check_per_die()
123{
124	echo -n "Checking CSV output: per die "
125	if ParanoidAndNotRoot 0
126	then
127		echo "[Skip] paranoid and not root"
128		return
129	fi
130	perf stat -x, --per-die -a true 2>&1 | commachecker --per-die
131	echo "[Success]"
132}
133
134check_per_node()
135{
136	echo -n "Checking CSV output: per node "
137	if ParanoidAndNotRoot 0
138	then
139		echo "[Skip] paranoid and not root"
140		return
141	fi
142	perf stat -x, --per-node -a true 2>&1 | commachecker --per-node
143	echo "[Success]"
144}
145
146check_per_socket()
147{
148	echo -n "Checking CSV output: per socket "
149	if ParanoidAndNotRoot 0
150	then
151		echo "[Skip] paranoid and not root"
152		return
153	fi
154	perf stat -x, --per-socket -a true 2>&1 | commachecker --per-socket
155	echo "[Success]"
156}
157
158check_no_args
159check_system_wide
160check_system_wide_no_aggr
161check_interval
162check_event
163check_per_core
164check_per_thread
165check_per_die
166check_per_node
167check_per_socket
168exit 0
169