projects/linux·blob master · refs

173 lines · 4.6 KiB

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