199a04a48SKan Liang#!/bin/bash
299a04a48SKan Liang# perf stat STD output linter
399a04a48SKan Liang# SPDX-License-Identifier: GPL-2.0
499a04a48SKan Liang# Tests various perf stat STD output commands for
599a04a48SKan Liang# default event and metricgroup
699a04a48SKan Liang
799a04a48SKan Liangset -e
899a04a48SKan Liang
9*35578a55SAthira Rajeev. "$(dirname $0)"/lib/stat_output.sh
1099a04a48SKan Liang
1199a04a48SKan Liangstat_output=$(mktemp /tmp/__perf_test.stat_output.std.XXXXX)
1299a04a48SKan Liang
138d3df7c3SNamhyung Kimevent_name=(cpu-clock task-clock context-switches cpu-migrations page-faults stalled-cycles-frontend stalled-cycles-backend cycles instructions branches branch-misses)
148d3df7c3SNamhyung Kimevent_metric=("CPUs utilized" "CPUs utilized" "/sec" "/sec" "/sec" "frontend cycles idle" "backend cycles idle" "GHz" "insn per cycle" "/sec" "of all branches")
154d60e83dSNamhyung Kimskip_metric=("stalled cycles per insn" "tma_")
1699a04a48SKan Liang
1799a04a48SKan Liangcleanup() {
1899a04a48SKan Liang  rm -f "${stat_output}"
1999a04a48SKan Liang
2099a04a48SKan Liang  trap - EXIT TERM INT
2199a04a48SKan Liang}
2299a04a48SKan Liang
2399a04a48SKan Liangtrap_cleanup() {
2499a04a48SKan Liang  cleanup
2599a04a48SKan Liang  exit 1
2699a04a48SKan Liang}
2799a04a48SKan Liangtrap trap_cleanup EXIT TERM INT
2899a04a48SKan Liang
2999a04a48SKan Liangfunction commachecker()
3099a04a48SKan Liang{
3199a04a48SKan Liang	local prefix=1
3299a04a48SKan Liang
3399a04a48SKan Liang	case "$1"
3499a04a48SKan Liang	in "--interval")	prefix=2
3599a04a48SKan Liang	;; "--per-thread")	prefix=2
3699a04a48SKan Liang	;; "--system-wide-no-aggr")	prefix=2
3799a04a48SKan Liang	;; "--per-core")	prefix=3
3899a04a48SKan Liang	;; "--per-socket")	prefix=3
3999a04a48SKan Liang	;; "--per-node")	prefix=3
4099a04a48SKan Liang	;; "--per-die")		prefix=3
4199a04a48SKan Liang	;; "--per-cache")	prefix=3
4299a04a48SKan Liang	esac
4399a04a48SKan Liang
4499a04a48SKan Liang	while read line
4599a04a48SKan Liang	do
4699a04a48SKan Liang		# Ignore initial "started on" comment.
4799a04a48SKan Liang		x=${line:0:1}
4899a04a48SKan Liang		[ "$x" = "#" ] && continue
4999a04a48SKan Liang		# Ignore initial blank line.
5099a04a48SKan Liang		[ "$line" = "" ] && continue
5199a04a48SKan Liang		# Ignore "Performance counter stats"
5299a04a48SKan Liang		x=${line:0:25}
5399a04a48SKan Liang		[ "$x" = "Performance counter stats" ] && continue
5499a04a48SKan Liang		# Ignore "seconds time elapsed" and break
5599a04a48SKan Liang		[[ "$line" == *"time elapsed"* ]] && break
5699a04a48SKan Liang
5799a04a48SKan Liang		main_body=$(echo $line | cut -d' ' -f$prefix-)
5899a04a48SKan Liang		x=${main_body%#*}
594d60e83dSNamhyung Kim		[ "$x" = "" ] && continue
604d60e83dSNamhyung Kim
614d60e83dSNamhyung Kim		# Skip metrics without event name
624d60e83dSNamhyung Kim		y=${main_body#*#}
634d60e83dSNamhyung Kim		for i in "${!skip_metric[@]}"; do
644d60e83dSNamhyung Kim			[[ "$y" == *"${skip_metric[$i]}"* ]] && break
6599a04a48SKan Liang		done
664d60e83dSNamhyung Kim		[[ "$y" == *"${skip_metric[$i]}"* ]] && continue
6799a04a48SKan Liang
6899a04a48SKan Liang		# Check default event
6999a04a48SKan Liang		for i in "${!event_name[@]}"; do
7099a04a48SKan Liang			[[ "$x" == *"${event_name[$i]}"* ]] && break
7199a04a48SKan Liang		done
7299a04a48SKan Liang
7399a04a48SKan Liang		[[ ! "$x" == *"${event_name[$i]}"* ]] && {
7499a04a48SKan Liang			echo "Unknown event name in $line" 1>&2
7599a04a48SKan Liang			exit 1;
7699a04a48SKan Liang		}
7799a04a48SKan Liang
7899a04a48SKan Liang		# Check event metric if it exists
7999a04a48SKan Liang		[[ ! "$main_body" == *"#"* ]] && continue
8099a04a48SKan Liang		[[ ! "$main_body" == *"${event_metric[$i]}"* ]] && {
8199a04a48SKan Liang			echo "wrong event metric. expected ${event_metric[$i]} in $line" 1>&2
8299a04a48SKan Liang			exit 1;
8399a04a48SKan Liang		}
8499a04a48SKan Liang	done < "${stat_output}"
8599a04a48SKan Liang	return 0
8699a04a48SKan Liang}
8799a04a48SKan Liang
8899a04a48SKan Liangperf_cmd="-o ${stat_output}"
8999a04a48SKan Liang
9099a04a48SKan Liangskip_test=$(check_for_topology)
9199a04a48SKan Liangcheck_no_args "STD" "$perf_cmd"
9299a04a48SKan Liangcheck_system_wide "STD" "$perf_cmd"
9399a04a48SKan Liangcheck_interval "STD" "$perf_cmd"
9499a04a48SKan Liangcheck_per_thread "STD" "$perf_cmd"
9599a04a48SKan Liangcheck_per_node "STD" "$perf_cmd"
9699a04a48SKan Liangif [ $skip_test -ne 1 ]
9799a04a48SKan Liangthen
9899a04a48SKan Liang	check_system_wide_no_aggr "STD" "$perf_cmd"
9999a04a48SKan Liang	check_per_core "STD" "$perf_cmd"
10099a04a48SKan Liang	check_per_cache_instance "STD" "$perf_cmd"
10199a04a48SKan Liang	check_per_die "STD" "$perf_cmd"
10299a04a48SKan Liang	check_per_socket "STD" "$perf_cmd"
10399a04a48SKan Liangelse
10499a04a48SKan Liang	echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
10599a04a48SKan Liangfi
10699a04a48SKan Liangcleanup
10799a04a48SKan Liangexit 0
108