summaryrefslogtreecommitdiff
path: root/tools/perf/tests/shell/test_stat_cpi_python.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/tests/shell/test_stat_cpi_python.sh')
-rwxr-xr-xtools/perf/tests/shell/test_stat_cpi_python.sh121
1 files changed, 121 insertions, 0 deletions
diff --git a/tools/perf/tests/shell/test_stat_cpi_python.sh b/tools/perf/tests/shell/test_stat_cpi_python.sh
new file mode 100755
index 000000000000..d1571a20f468
--- /dev/null
+++ b/tools/perf/tests/shell/test_stat_cpi_python.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# stat-cpi python test (no_mlock)
+
+set -e
+
+shelldir=$(dirname "$0")
+# shellcheck source=lib/setup_python.sh
+. "${shelldir}"/lib/setup_python.sh
+
+# If we don't have the perf python module, we can't test
+if ! "$PYTHON" -c 'import perf' > /dev/null 2>&1; then
+ echo "Skipping test, perf python module not found"
+ return 2 2>/dev/null || exit 2
+fi
+
+script_dir="$(dirname "$0")/../../python"
+script_path="${script_dir}/stat-cpi.py"
+
+if [ ! -f "$script_path" ]; then
+ echo "Skipping test, stat-cpi.py not found at $script_path"
+ return 2 2>/dev/null || exit 2
+fi
+
+err=0
+ran=0
+temp_data=""
+temp_out=""
+
+cleanup() {
+ [ -n "${pid}" ] && kill "$pid" 2>/dev/null || true
+ [ -n "${workload_pid}" ] && kill "$workload_pid" 2>/dev/null || true
+ rm -f "${temp_data}" "${temp_out}"
+ trap - exit term int
+}
+
+trap_cleanup() {
+ cleanup
+ exit 1
+}
+trap trap_cleanup exit term int
+
+temp_data=$(mktemp /tmp/perf.data.XXXXXX)
+temp_out=$(mktemp /tmp/perf.out.XXXXXX)
+
+test_live_mode() {
+ echo "Testing stat-cpi.py live mode..."
+ if ! perf stat -e cycles,instructions -- sleep 0.1 2>/dev/null && \
+ ! perf stat -e cycles:u,instructions:u -- sleep 0.1 2>/dev/null; then
+ echo "perf stat failed (permissions?), skipping live mode test."
+ return 0
+ fi
+ perf test -w noploop 60 &
+ workload_pid=$!
+ if ! perf stat -e cycles,instructions -p "$workload_pid" -- sleep 0.05 2>/dev/null && \
+ ! perf stat -e cycles:u,instructions:u -p "$workload_pid" -- sleep 0.05 2>/dev/null; then
+ kill "$workload_pid" 2>/dev/null || true
+ workload_pid=""
+ echo "perf stat -p failed (ptrace_scope?), skipping live mode test."
+ return 0
+ fi
+ ran=1
+
+ # Run live mode in the background, wait until at least one interval is
+ # printed, then interrupt.
+ perf script stat-cpi -I 0.1 -p "$workload_pid" > "${temp_out}" &
+ pid=$!
+ for _ in $(seq 1 50); do
+ if grep -q "cpi" "${temp_out}"; then
+ break
+ fi
+ sleep 0.1
+ done
+ kill -INT "$pid" 2>/dev/null || true
+ set +e
+ wait "$pid"
+ res=$?
+ set -e
+ pid=""
+ kill "$workload_pid" 2>/dev/null || true
+ workload_pid=""
+ if [ $res -ne 0 ] && [ $res -ne 130 ] && [ $res -ne 143 ]; then
+ echo "Live mode failed or crashed"
+ err=1
+ elif ! grep -q "cpi" "${temp_out}"; then
+ echo "Live mode produced no cpi output"
+ err=1
+ else
+ echo "Live mode test passed."
+ fi
+}
+
+test_file_mode() {
+ echo "Testing stat-cpi.py file mode..."
+ # Generate some stat events - perf stat -I represents interval reporting
+ if ! perf stat -e cycles,instructions -I 100 record -o "${temp_data}" \
+ -- sleep 0.5 2>/dev/null && \
+ ! perf stat -e cycles:u,instructions:u -I 100 record -o "${temp_data}" \
+ -- sleep 0.5 2>/dev/null; then
+ echo "perf stat failed (permissions?), skipping file mode test."
+ return
+ fi
+ ran=1
+
+ out=$(perf script stat-cpi -i "${temp_data}")
+ if ! echo "$out" | grep -q "cpi"; then
+ echo "File mode test failed."
+ err=1
+ else
+ echo "File mode test passed."
+ fi
+}
+
+test_live_mode
+test_file_mode
+
+cleanup
+if [ $ran -eq 0 ]; then
+ exit 2
+fi
+exit $err