diff options
Diffstat (limited to 'tools/perf/tests/shell/test_flamegraph_python.sh')
| -rwxr-xr-x | tools/perf/tests/shell/test_flamegraph_python.sh | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/tools/perf/tests/shell/test_flamegraph_python.sh b/tools/perf/tests/shell/test_flamegraph_python.sh new file mode 100755 index 000000000000..787d6bbdf04a --- /dev/null +++ b/tools/perf/tests/shell/test_flamegraph_python.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# flamegraph python test + +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" + exit 2 +fi + +script_dir="$(dirname "$0")/../../python" +script_path="${script_dir}/flamegraph.py" + +if [ ! -f "$script_path" ]; then + echo "Skipping test, flamegraph.py not found at $script_path" + exit 2 +fi + +err=0 +temp_data="" +temp_json="" +temp_html="" +temp_tpl="" + +cleanup() { + rm -f "${temp_data}" "${temp_json}" "${temp_html}" "${temp_tpl}" +} + +trap 'cleanup' EXIT TERM INT + +temp_data=$(mktemp /tmp/perf.data.XXXXXX) +temp_json=$(mktemp /tmp/perf.flamegraph.json.XXXXXX) +temp_html=$(mktemp /tmp/perf.flamegraph.html.XXXXXX) +temp_tpl=$(mktemp /tmp/perf.flamegraph.tpl.XXXXXX) + +validate_json() { + local json_file="$1" + local label="$2" + + if ! "$PYTHON" -m json.tool "${json_file}" /dev/null >/dev/null 2>&1; then + echo "${label} JSON validation failed." + err=1 + elif ! "$PYTHON" -c "import json, sys +d = json.load(open(sys.argv[1])) +assert d.get('v', 0) > 0 or len(d.get('c', [])) > 0" "${json_file}" >/dev/null 2>&1; then + echo "${label} JSON flamegraph structure is empty." + err=1 + else + echo "${label} JSON test passed." + fi +} + +test_file_mode() { + echo "Testing flamegraph.py..." + + # Generate some events with callchains + if ! perf record -B -N --no-bpf-event -g -o "${temp_data}" \ + -- perf test -w noploop >/dev/null 2>&1; then + echo "Skipping test, perf record -g failed (permissions or lack of support)" + exit 2 + fi + + # Run the script in file mode and validate JSON output + if ! perf script flamegraph -i "${temp_data}" -f json -o "${temp_json}" >/dev/null; then + echo "File mode JSON test failed." + err=1 + else + validate_json "${temp_json}" "File mode" + fi + + # Run the script in pipe ('-') mode and validate JSON output + rm -f "${temp_json}" + if ! perf record -B -N --no-bpf-event -g -o - -- perf test -w noploop 2>/dev/null | \ + perf script flamegraph -i - -f json -o "${temp_json}" >/dev/null; then + echo "Pipe stdin JSON mode test failed." + err=1 + else + validate_json "${temp_json}" "Pipe mode" + fi + + # Run the script, dump as html to temp_html using MINIMAL_HTML fallback + if ! perf script flamegraph -i "${temp_data}" -f html \ + --template /nonexistent/template.html -o "${temp_html}" >/dev/null 2>&1; then + echo "File mode HTML test failed." + err=1 + else + if ! grep -q "<head>" "${temp_html}" || \ + ! grep -q 'crossorigin="anonymous"' "${temp_html}"; then + echo "HTML validation failed." + err=1 + else + echo "File mode HTML test passed." + fi + fi + + # Test custom local HTML template and --colorscheme option + cat << 'EOF' > "${temp_tpl}" +<html><body><script> +const opts = /** @options_json **/; +const data = /** @flamegraph_json **/; +</script></body></html> +EOF + if ! perf script flamegraph -i "${temp_data}" -f html --template "${temp_tpl}" \ + --colorscheme blue-green -o "${temp_html}" >/dev/null 2>&1; then + echo "Custom template HTML test failed." + err=1 + elif ! grep -q "blue-green" "${temp_html}"; then + echo "Custom template colorscheme substitution failed." + err=1 + else + echo "Custom template HTML test passed." + fi +} + +test_file_mode + +exit $err |
