162306a36Sopenharmony_ci#!/bin/bash
262306a36Sopenharmony_ci# perf stat STD output linter
362306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
462306a36Sopenharmony_ci# Tests various perf stat STD output commands for
562306a36Sopenharmony_ci# default event and metricgroup
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciset -e
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci. "$(dirname $0)"/lib/stat_output.sh
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistat_output=$(mktemp /tmp/__perf_test.stat_output.std.XXXXX)
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cievent_name=(cpu-clock task-clock context-switches cpu-migrations page-faults stalled-cycles-frontend stalled-cycles-backend cycles instructions branches branch-misses)
1462306a36Sopenharmony_cievent_metric=("CPUs utilized" "CPUs utilized" "/sec" "/sec" "/sec" "frontend cycles idle" "backend cycles idle" "GHz" "insn per cycle" "/sec" "of all branches")
1562306a36Sopenharmony_ciskip_metric=("stalled cycles per insn" "tma_")
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cicleanup() {
1862306a36Sopenharmony_ci  rm -f "${stat_output}"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci  trap - EXIT TERM INT
2162306a36Sopenharmony_ci}
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_citrap_cleanup() {
2462306a36Sopenharmony_ci  cleanup
2562306a36Sopenharmony_ci  exit 1
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_citrap trap_cleanup EXIT TERM INT
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cifunction commachecker()
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	local prefix=1
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	case "$1"
3462306a36Sopenharmony_ci	in "--interval")	prefix=2
3562306a36Sopenharmony_ci	;; "--per-thread")	prefix=2
3662306a36Sopenharmony_ci	;; "--system-wide-no-aggr")	prefix=2
3762306a36Sopenharmony_ci	;; "--per-core")	prefix=3
3862306a36Sopenharmony_ci	;; "--per-socket")	prefix=3
3962306a36Sopenharmony_ci	;; "--per-node")	prefix=3
4062306a36Sopenharmony_ci	;; "--per-die")		prefix=3
4162306a36Sopenharmony_ci	;; "--per-cache")	prefix=3
4262306a36Sopenharmony_ci	esac
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	while read line
4562306a36Sopenharmony_ci	do
4662306a36Sopenharmony_ci		# Ignore initial "started on" comment.
4762306a36Sopenharmony_ci		x=${line:0:1}
4862306a36Sopenharmony_ci		[ "$x" = "#" ] && continue
4962306a36Sopenharmony_ci		# Ignore initial blank line.
5062306a36Sopenharmony_ci		[ "$line" = "" ] && continue
5162306a36Sopenharmony_ci		# Ignore "Performance counter stats"
5262306a36Sopenharmony_ci		x=${line:0:25}
5362306a36Sopenharmony_ci		[ "$x" = "Performance counter stats" ] && continue
5462306a36Sopenharmony_ci		# Ignore "seconds time elapsed" and break
5562306a36Sopenharmony_ci		[[ "$line" == *"time elapsed"* ]] && break
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci		main_body=$(echo $line | cut -d' ' -f$prefix-)
5862306a36Sopenharmony_ci		x=${main_body%#*}
5962306a36Sopenharmony_ci		[ "$x" = "" ] && continue
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci		# Skip metrics without event name
6262306a36Sopenharmony_ci		y=${main_body#*#}
6362306a36Sopenharmony_ci		for i in "${!skip_metric[@]}"; do
6462306a36Sopenharmony_ci			[[ "$y" == *"${skip_metric[$i]}"* ]] && break
6562306a36Sopenharmony_ci		done
6662306a36Sopenharmony_ci		[[ "$y" == *"${skip_metric[$i]}"* ]] && continue
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci		# Check default event
6962306a36Sopenharmony_ci		for i in "${!event_name[@]}"; do
7062306a36Sopenharmony_ci			[[ "$x" == *"${event_name[$i]}"* ]] && break
7162306a36Sopenharmony_ci		done
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci		[[ ! "$x" == *"${event_name[$i]}"* ]] && {
7462306a36Sopenharmony_ci			echo "Unknown event name in $line" 1>&2
7562306a36Sopenharmony_ci			exit 1;
7662306a36Sopenharmony_ci		}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci		# Check event metric if it exists
7962306a36Sopenharmony_ci		[[ ! "$main_body" == *"#"* ]] && continue
8062306a36Sopenharmony_ci		[[ ! "$main_body" == *"${event_metric[$i]}"* ]] && {
8162306a36Sopenharmony_ci			echo "wrong event metric. expected ${event_metric[$i]} in $line" 1>&2
8262306a36Sopenharmony_ci			exit 1;
8362306a36Sopenharmony_ci		}
8462306a36Sopenharmony_ci	done < "${stat_output}"
8562306a36Sopenharmony_ci	return 0
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciperf_cmd="-o ${stat_output}"
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciskip_test=$(check_for_topology)
9162306a36Sopenharmony_cicheck_no_args "STD" "$perf_cmd"
9262306a36Sopenharmony_cicheck_system_wide "STD" "$perf_cmd"
9362306a36Sopenharmony_cicheck_interval "STD" "$perf_cmd"
9462306a36Sopenharmony_cicheck_per_thread "STD" "$perf_cmd"
9562306a36Sopenharmony_cicheck_per_node "STD" "$perf_cmd"
9662306a36Sopenharmony_ciif [ $skip_test -ne 1 ]
9762306a36Sopenharmony_cithen
9862306a36Sopenharmony_ci	check_system_wide_no_aggr "STD" "$perf_cmd"
9962306a36Sopenharmony_ci	check_per_core "STD" "$perf_cmd"
10062306a36Sopenharmony_ci	check_per_cache_instance "STD" "$perf_cmd"
10162306a36Sopenharmony_ci	check_per_die "STD" "$perf_cmd"
10262306a36Sopenharmony_ci	check_per_socket "STD" "$perf_cmd"
10362306a36Sopenharmony_cielse
10462306a36Sopenharmony_ci	echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
10562306a36Sopenharmony_cifi
10662306a36Sopenharmony_cicleanup
10762306a36Sopenharmony_ciexit 0
108