xref: /linux/tools/perf/tests/shell/script_python.sh (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1#!/bin/bash
2# perf script python tests
3# SPDX-License-Identifier: GPL-2.0
4
5set -e
6
7# set PERF_EXEC_PATH to find scripts in the source directory
8perfdir=$(dirname "$0")/../..
9if [ -e "$perfdir/scripts/python/Perf-Trace-Util" ]; then
10  export PERF_EXEC_PATH=$perfdir
11fi
12
13
14perfdata=$(mktemp /tmp/__perf_test_script_python.perf.data.XXXXX)
15generated_script=$(mktemp /tmp/__perf_test_script.XXXXX.py)
16
17cleanup() {
18  rm -f "${perfdata}"
19  rm -f "${generated_script}"
20  trap - EXIT TERM INT
21}
22
23trap_cleanup() {
24  echo "Unexpected signal in ${FUNCNAME[1]}"
25  cleanup
26  exit 1
27}
28trap trap_cleanup TERM INT
29trap cleanup EXIT
30
31check_python_support() {
32	if perf check feature -q libpython; then
33		return 0
34	fi
35	echo "perf script python test [Skipped: no libpython support]"
36	return 2
37}
38
39test_script() {
40	local event_name=$1
41	local expected_output=$2
42	local record_opts=$3
43
44	echo "Testing event: $event_name"
45
46	# Try to record. If this fails, it might be permissions or lack of
47	# support. Return 2 to indicate "skip this event" rather than "fail
48	# test".
49	if ! perf record -o "${perfdata}" -e "$event_name" $record_opts -- perf test -w thloop > /dev/null 2>&1; then
50		echo "perf script python test [Skipped: failed to record $event_name]"
51		return 2
52	fi
53
54	echo "Generating python script..."
55	if ! perf script -i "${perfdata}" -g "${generated_script}"; then
56		echo "perf script python test [Failed: script generation for $event_name]"
57		return 1
58	fi
59
60	if [ ! -f "${generated_script}" ]; then
61		echo "perf script python test [Failed: script not generated for $event_name]"
62		return 1
63	fi
64
65	# Perf script -g python doesn't generate process_event for generic
66	# events so append it manually to test that the callback works.
67	if ! grep -q "def process_event" "${generated_script}"; then
68		cat <<EOF >> "${generated_script}"
69
70def process_event(param_dict):
71	print("param_dict: %s" % param_dict)
72EOF
73	fi
74
75	echo "Executing python script..."
76	output=$(perf script -i "${perfdata}" -s "${generated_script}" 2>&1)
77
78	if echo "$output" | grep -q "$expected_output"; then
79		echo "perf script python test [Success: $event_name triggered $expected_output]"
80		return 0
81	else
82		echo "perf script python test [Failed: $event_name did not trigger $expected_output]"
83		echo "Output was:"
84		echo "$output" | head -n 20
85		return 1
86	fi
87}
88
89check_python_support || exit 2
90
91# Try tracepoint first
92test_script "sched:sched_switch" "sched__sched_switch" "-c 1" && res=0 || res=$?
93
94if [ $res -eq 0 ]; then
95	exit 0
96elif [ $res -eq 1 ]; then
97	exit 1
98fi
99
100# If tracepoint skipped (res=2), try task-clock
101# For generic events like task-clock, the generated script uses process_event()
102# which prints the param_dict.
103test_script "task-clock" "param_dict" "-c 100" && res=0 || res=$?
104
105if [ $res -eq 0 ]; then
106	exit 0
107elif [ $res -eq 1 ]; then
108	exit 1
109fi
110
111# If both skipped
112echo "perf script python test [Skipped: Could not record tracepoint or task-clock]"
113exit 2
114