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