1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3test_begin() { 4 # Count tests to allow the test harness to double-check if all were 5 # included correctly. 6 ctr=0 7 # Set test directory to the directory of the script 8 scriptfile=$(realpath "$0") 9 testdir=$(dirname "$scriptfile") 10 [ -z "$RTLA" ] && RTLA="./rtla" 11 [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" 12} 13 14reset_osnoise() { 15 # Reset osnoise options to default and remove any dangling instances created 16 # by improperly exited rtla runs. 17 pushd /sys/kernel/tracing >/dev/null || return 1 18 19 # Remove dangling instances created by previous rtla run 20 echo 0 > tracing_thresh 21 cd instances 22 for i in osnoise_top osnoise_hist timerlat_top timerlat_hist 23 do 24 [ ! -d "$i" ] && continue 25 rmdir "$i" 26 done 27 28 # Reset options to default 29 # Note: those are copied from the default values of osnoise_data 30 # in kernel/trace/trace_osnoise.c 31 cd ../osnoise 32 echo all > cpus 33 echo DEFAULTS > options 34 echo 1000000 > period_us 35 echo 0 > print_stack 36 echo 1000000 > runtime_us 37 echo 0 > stop_tracing_total_us 38 echo 0 > stop_tracing_us 39 echo 1000 > timerlat_period_us 40 41 popd >/dev/null 42} 43 44check() { 45 test_name=$0 46 tested_command=$1 47 expected_exitcode=${3:-0} 48 expected_output=$4 49 unexpected_output=$5 50 # Simple check: run rtla with given arguments and test exit code. 51 # If TEST_COUNT is set, run the test. Otherwise, just count. 52 ctr=$(($ctr + 1)) 53 if [ -n "$TEST_COUNT" ] 54 then 55 # Reset osnoise options before running test. 56 [ "$NO_RESET_OSNOISE" == 1 ] || reset_osnoise 57 58 # Create a temporary directory to contain rtla output 59 tmpdir=$(mktemp -d) 60 pushd $tmpdir >/dev/null 61 62 # Run rtla; in case of failure, include its output as comment 63 # in the test results. 64 result=$(eval stdbuf -oL $TIMEOUT "$RTLA" $2 2>&1); exitcode=$? 65 failbuf='' 66 fail=0 67 68 # Test if the results matches if requested 69 if [ -n "$expected_output" ] && ! grep -qE "$expected_output" <<< "$result" 70 then 71 fail=1 72 failbuf+=$(printf "# Output match failed: \"%s\"" "$expected_output") 73 failbuf+=$'\n' 74 fi 75 76 if [ -n "$unexpected_output" ] && grep -qE "$unexpected_output" <<< "$result" 77 then 78 fail=1 79 failbuf+=$(printf "# Output non-match failed: \"%s\"" "$unexpected_output") 80 failbuf+=$'\n' 81 fi 82 83 if [ $exitcode -eq $expected_exitcode ] && [ $fail -eq 0 ] 84 then 85 echo "ok $ctr - $1" 86 else 87 # Add rtla output and exit code as comments in case of failure 88 echo "not ok $ctr - $1" 89 echo -n "$failbuf" 90 echo "$result" | col -b | while read line; do echo "# $line"; done 91 printf "#\n# exit code %s\n" $exitcode 92 fi 93 94 # Remove temporary directory 95 popd >/dev/null 96 rm -r $tmpdir 97 fi 98} 99 100check_with_osnoise_options() { 101 # Do the same as "check", but with pre-set tracefs options. 102 # Resets osnoise first, then writes the given tracefs option=value 103 # pairs before running the check with NO_RESET_OSNOISE=1. 104 # Arguments: test_name command exit_code expected_output [path=value ...] 105 # Each path is relative to /sys/kernel/tracing/ 106 local arg1=$1 107 local arg2=$2 108 local arg3=$3 109 local arg4=$4 110 local opt option value 111 112 # Apply tracefs options (if not dry run) 113 if [ -n "$TEST_COUNT" ] 114 then 115 [ "$NO_RESET_OSNOISE" == 1 ] || reset_osnoise 116 shift 4 117 for opt in "$@" 118 do 119 [ -z "$opt" ] && continue 120 option="${opt%%=*}" 121 value="${opt#*=}" 122 # Try to apply the option, ignore errors: when pre-setting fails 123 # (e.g. kernel does not know the option), the test itself will likely 124 # also fail. 125 # Throwing an error here would cause the test to be incorrectly 126 # skipped. 127 echo "$value" > "/sys/kernel/tracing/$option" 128 done 129 fi 130 131 NO_RESET_OSNOISE=1 check "$arg1" "$arg2" "$arg3" "$arg4" 132} 133 134check_top_hist() { 135 # Test one command with both "top" and "hist" tools, replacing "TOOL" in 136 # command with either "top" or "hist" respectively, and prefixing the test 137 # names with "top " and "hist ". 138 check "top $1" "$(echo "$2" | sed 's/TOOL/top/g')" "${@:3}" 139 check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}" 140} 141 142check_top_q_hist() { 143 # Same as above, but pass "-q" to top so that strings printed in main 144 # loop are on their own line for top too, not only for hist. 145 check "top $1" "$(echo "$2" | sed 's/TOOL/top -q/g')" "${@:3}" 146 check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}" 147} 148 149set_timeout() { 150 TIMEOUT="timeout -v -k 15s $1" 151} 152 153unset_timeout() { 154 unset TIMEOUT 155} 156 157set_no_reset_osnoise() { 158 NO_RESET_OSNOISE=1 159} 160 161unset_no_reset_osnoise() { 162 unset NO_RESET_OSNOISE 163} 164 165test_end() { 166 # If running without TEST_COUNT, tests are not actually run, just 167 # counted. In that case, re-run the test with the correct count. 168 [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash $0 || true 169} 170 171# Avoid any environmental discrepancies 172export LC_ALL=C 173unset_timeout 174