| #!/bin/bash | |
| # SPDX-License-Identifier: GPL-2.0 | |
| test_begin() { | |
| # Count tests to allow the test harness to double-check if all were | |
| # included correctly. | |
| ctr=0 | |
| # Set test directory to the directory of the script | |
| scriptfile=$(realpath "$0") | |
| testdir=$(dirname "$scriptfile") | |
| [ -z "$RTLA" ] && RTLA="./rtla" | |
| [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" | |
| } | |
| reset_osnoise() { | |
| # Reset osnoise options to default and remove any dangling instances created | |
| # by improperly exited rtla runs. | |
| pushd /sys/kernel/tracing >/dev/null || return 1 | |
| # Remove dangling instances created by previous rtla run | |
| echo 0 > tracing_thresh | |
| cd instances | |
| for i in osnoise_top osnoise_hist timerlat_top timerlat_hist | |
| do | |
| [ ! -d "$i" ] && continue | |
| rmdir "$i" | |
| done | |
| # Reset options to default | |
| # Note: those are copied from the default values of osnoise_data | |
| # in kernel/trace/trace_osnoise.c | |
| cd ../osnoise | |
| echo all > cpus | |
| echo DEFAULTS > options | |
| echo 1000000 > period_us | |
| echo 0 > print_stack | |
| echo 1000000 > runtime_us | |
| echo 0 > stop_tracing_total_us | |
| echo 0 > stop_tracing_us | |
| echo 1000 > timerlat_period_us | |
| popd >/dev/null | |
| } | |
| check() { | |
| test_name=$0 | |
| tested_command=$1 | |
| expected_exitcode=${3:-0} | |
| expected_output=$4 | |
| unexpected_output=$5 | |
| # Simple check: run rtla with given arguments and test exit code. | |
| # If TEST_COUNT is set, run the test. Otherwise, just count. | |
| ctr=$(($ctr + 1)) | |
| if [ -n "$TEST_COUNT" ] | |
| then | |
| # Reset osnoise options before running test. | |
| [ "$NO_RESET_OSNOISE" == 1 ] || reset_osnoise | |
| # Create a temporary directory to contain rtla output | |
| tmpdir=$(mktemp -d) | |
| pushd $tmpdir >/dev/null | |
| # Run rtla; in case of failure, include its output as comment | |
| # in the test results. | |
| result=$(eval stdbuf -oL $TIMEOUT "$RTLA" $2 2>&1); exitcode=$? | |
| failbuf='' | |
| fail=0 | |
| # Test if the results matches if requested | |
| if [ -n "$expected_output" ] && ! grep -qE "$expected_output" <<< "$result" | |
| then | |
| fail=1 | |
| failbuf+=$(printf "# Output match failed: \"%s\"" "$expected_output") | |
| failbuf+=$'\n' | |
| fi | |
| if [ -n "$unexpected_output" ] && grep -qE "$unexpected_output" <<< "$result" | |
| then | |
| fail=1 | |
| failbuf+=$(printf "# Output non-match failed: \"%s\"" "$unexpected_output") | |
| failbuf+=$'\n' | |
| fi | |
| if [ $exitcode -eq $expected_exitcode ] && [ $fail -eq 0 ] | |
| then | |
| echo "ok $ctr - $1" | |
| else | |
| # Add rtla output and exit code as comments in case of failure | |
| echo "not ok $ctr - $1" | |
| echo -n "$failbuf" | |
| echo "$result" | col -b | while read line; do echo "# $line"; done | |
| printf "#\n# exit code %s\n" $exitcode | |
| fi | |
| # Remove temporary directory | |
| popd >/dev/null | |
| rm -r $tmpdir | |
| fi | |
| } | |
| check_with_osnoise_options() { | |
| # Do the same as "check", but with pre-set osnoise options. | |
| # Note: rtla should reset the osnoise options, this is used to test | |
| # if it indeed does so. | |
| # Save original arguments | |
| arg1=$1 | |
| arg2=$2 | |
| arg3=$3 | |
| # Apply osnoise options (if not dry run) | |
| if [ -n "$TEST_COUNT" ] | |
| then | |
| [ "$NO_RESET_OSNOISE" == 1 ] || reset_osnoise | |
| shift | |
| shift | |
| while shift | |
| do | |
| [ "$1" == "" ] && continue | |
| option=$(echo $1 | cut -d '=' -f 1) | |
| value=$(echo $1 | cut -d '=' -f 2) | |
| echo "$value" > "/sys/kernel/tracing/osnoise/$option" || return 1 | |
| done | |
| fi | |
| NO_RESET_OSNOISE=1 check "$arg1" "$arg2" "$arg3" | |
| } | |
| check_top_hist() { | |
| # Test one command with both "top" and "hist" tools, replacing "TOOL" in | |
| # command with either "top" or "hist" respectively, and prefixing the test | |
| # names with "top " and "hist ". | |
| check "top $1" "$(echo "$2" | sed 's/TOOL/top/g')" "${@:3}" | |
| check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}" | |
| } | |
| check_top_q_hist() { | |
| # Same as above, but pass "-q" to top so that strings printed in main | |
| # loop are on their own line for top too, not only for hist. | |
| check "top $1" "$(echo "$2" | sed 's/TOOL/top -q/g')" "${@:3}" | |
| check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}" | |
| } | |
| set_timeout() { | |
| TIMEOUT="timeout -v -k 15s $1" | |
| } | |
| unset_timeout() { | |
| unset TIMEOUT | |
| } | |
| set_no_reset_osnoise() { | |
| NO_RESET_OSNOISE=1 | |
| } | |
| unset_no_reset_osnoise() { | |
| unset NO_RESET_OSNOISE | |
| } | |
| test_end() { | |
| # If running without TEST_COUNT, tests are not actually run, just | |
| # counted. In that case, re-run the test with the correct count. | |
| [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash $0 || true | |
| } | |
| # Avoid any environmental discrepancies | |
| export LC_ALL=C | |
| unset_timeout |