xref: /linux/tools/tracing/rtla/tests/engine.sh (revision ad5b50a0959fb67100ddb93aeb0ea40201272cb2)
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 osnoise options.
102	# Note: rtla should reset the osnoise options, this is used to test
103	# if it indeed does so.
104	# Save original arguments
105	arg1=$1
106	arg2=$2
107	arg3=$3
108
109	# Apply osnoise options (if not dry run)
110	if [ -n "$TEST_COUNT" ]
111	then
112		[ "$NO_RESET_OSNOISE" == 1 ] || reset_osnoise
113		shift
114		shift
115		while shift
116		do
117			[ "$1" == "" ] && continue
118			option=$(echo $1 | cut -d '=' -f 1)
119			value=$(echo $1 | cut -d '=' -f 2)
120			echo "$value" > "/sys/kernel/tracing/osnoise/$option" || return 1
121		done
122	fi
123
124	NO_RESET_OSNOISE=1 check "$arg1" "$arg2" "$arg3"
125}
126
127check_top_hist() {
128	# Test one command with both "top" and "hist" tools, replacing "TOOL" in
129	# command with either "top" or "hist" respectively, and prefixing the test
130	# names with "top " and "hist ".
131	check "top $1" "$(echo "$2" | sed 's/TOOL/top/g')" "${@:3}"
132	check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}"
133}
134
135check_top_q_hist() {
136	# Same as above, but pass "-q" to top so that strings printed in main
137	# loop are on their own line for top too, not only for hist.
138	check "top $1" "$(echo "$2" | sed 's/TOOL/top -q/g')" "${@:3}"
139	check "hist $1" "$(echo "$2" | sed 's/TOOL/hist/g')" "${@:3}"
140}
141
142set_timeout() {
143	TIMEOUT="timeout -v -k 15s $1"
144}
145
146unset_timeout() {
147	unset TIMEOUT
148}
149
150set_no_reset_osnoise() {
151	NO_RESET_OSNOISE=1
152}
153
154unset_no_reset_osnoise() {
155	unset NO_RESET_OSNOISE
156}
157
158test_end() {
159	# If running without TEST_COUNT, tests are not actually run, just
160	# counted. In that case, re-run the test with the correct count.
161	[ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash $0 || true
162}
163
164# Avoid any environmental discrepancies
165export LC_ALL=C
166unset_timeout
167