xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/sysctl/sysctl.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# This program is free software; you can redistribute it and/or modify it
5*4882a593Smuzhiyun# under the terms of the GNU General Public License as published by the Free
6*4882a593Smuzhiyun# Software Foundation; either version 2 of the License, or at your option any
7*4882a593Smuzhiyun# later version; or, when distributed separately from the Linux kernel or
8*4882a593Smuzhiyun# when incorporated into other software packages, subject to the following
9*4882a593Smuzhiyun# license:
10*4882a593Smuzhiyun#
11*4882a593Smuzhiyun# This program is free software; you can redistribute it and/or modify it
12*4882a593Smuzhiyun# under the terms of copyleft-next (version 0.3.1 or later) as published
13*4882a593Smuzhiyun# at http://copyleft-next.org/.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun# This performs a series tests against the proc sysctl interface.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4.
18*4882a593Smuzhiyunksft_skip=4
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunTEST_NAME="sysctl"
21*4882a593SmuzhiyunTEST_DRIVER="test_${TEST_NAME}"
22*4882a593SmuzhiyunTEST_DIR=$(dirname $0)
23*4882a593SmuzhiyunTEST_FILE=$(mktemp)
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun# This represents
26*4882a593Smuzhiyun#
27*4882a593Smuzhiyun# TEST_ID:TEST_COUNT:ENABLED:TARGET
28*4882a593Smuzhiyun#
29*4882a593Smuzhiyun# TEST_ID: is the test id number
30*4882a593Smuzhiyun# TEST_COUNT: number of times we should run the test
31*4882a593Smuzhiyun# ENABLED: 1 if enabled, 0 otherwise
32*4882a593Smuzhiyun# TARGET: test target file required on the test_sysctl module
33*4882a593Smuzhiyun#
34*4882a593Smuzhiyun# Once these are enabled please leave them as-is. Write your own test,
35*4882a593Smuzhiyun# we have tons of space.
36*4882a593SmuzhiyunALL_TESTS="0001:1:1:int_0001"
37*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0002:1:1:string_0001"
38*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0003:1:1:int_0002"
39*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0004:1:1:uint_0001"
40*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0005:3:1:int_0003"
41*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001"
42*4882a593SmuzhiyunALL_TESTS="$ALL_TESTS 0007:1:1:boot_int"
43*4882a593Smuzhiyun
44*4882a593Smuzhiyunfunction allow_user_defaults()
45*4882a593Smuzhiyun{
46*4882a593Smuzhiyun	if [ -z $DIR ]; then
47*4882a593Smuzhiyun		DIR="/sys/module/test_sysctl/"
48*4882a593Smuzhiyun	fi
49*4882a593Smuzhiyun	if [ -z $DEFAULT_NUM_TESTS ]; then
50*4882a593Smuzhiyun		DEFAULT_NUM_TESTS=50
51*4882a593Smuzhiyun	fi
52*4882a593Smuzhiyun	if [ -z $SYSCTL ]; then
53*4882a593Smuzhiyun		SYSCTL="/proc/sys/debug/test_sysctl"
54*4882a593Smuzhiyun	fi
55*4882a593Smuzhiyun	if [ -z $PROD_SYSCTL ]; then
56*4882a593Smuzhiyun		PROD_SYSCTL="/proc/sys"
57*4882a593Smuzhiyun	fi
58*4882a593Smuzhiyun	if [ -z $WRITES_STRICT ]; then
59*4882a593Smuzhiyun		WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict"
60*4882a593Smuzhiyun	fi
61*4882a593Smuzhiyun}
62*4882a593Smuzhiyun
63*4882a593Smuzhiyunfunction check_production_sysctl_writes_strict()
64*4882a593Smuzhiyun{
65*4882a593Smuzhiyun	echo -n "Checking production write strict setting ... "
66*4882a593Smuzhiyun	if [ ! -e ${WRITES_STRICT} ]; then
67*4882a593Smuzhiyun		echo "FAIL, but skip in case of old kernel" >&2
68*4882a593Smuzhiyun	else
69*4882a593Smuzhiyun		old_strict=$(cat ${WRITES_STRICT})
70*4882a593Smuzhiyun		if [ "$old_strict" = "1" ]; then
71*4882a593Smuzhiyun			echo "ok"
72*4882a593Smuzhiyun		else
73*4882a593Smuzhiyun			echo "FAIL, strict value is 0 but force to 1 to continue" >&2
74*4882a593Smuzhiyun			echo "1" > ${WRITES_STRICT}
75*4882a593Smuzhiyun		fi
76*4882a593Smuzhiyun	fi
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun	if [ -z $PAGE_SIZE ]; then
79*4882a593Smuzhiyun		PAGE_SIZE=$(getconf PAGESIZE)
80*4882a593Smuzhiyun	fi
81*4882a593Smuzhiyun	if [ -z $MAX_DIGITS ]; then
82*4882a593Smuzhiyun		MAX_DIGITS=$(($PAGE_SIZE/8))
83*4882a593Smuzhiyun	fi
84*4882a593Smuzhiyun	if [ -z $INT_MAX ]; then
85*4882a593Smuzhiyun		INT_MAX=$(getconf INT_MAX)
86*4882a593Smuzhiyun	fi
87*4882a593Smuzhiyun	if [ -z $UINT_MAX ]; then
88*4882a593Smuzhiyun		UINT_MAX=$(getconf UINT_MAX)
89*4882a593Smuzhiyun	fi
90*4882a593Smuzhiyun}
91*4882a593Smuzhiyun
92*4882a593Smuzhiyuntest_reqs()
93*4882a593Smuzhiyun{
94*4882a593Smuzhiyun	uid=$(id -u)
95*4882a593Smuzhiyun	if [ $uid -ne 0 ]; then
96*4882a593Smuzhiyun		echo $msg must be run as root >&2
97*4882a593Smuzhiyun		exit $ksft_skip
98*4882a593Smuzhiyun	fi
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun	if ! which perl 2> /dev/null > /dev/null; then
101*4882a593Smuzhiyun		echo "$0: You need perl installed"
102*4882a593Smuzhiyun		exit $ksft_skip
103*4882a593Smuzhiyun	fi
104*4882a593Smuzhiyun	if ! which getconf 2> /dev/null > /dev/null; then
105*4882a593Smuzhiyun		echo "$0: You need getconf installed"
106*4882a593Smuzhiyun		exit $ksft_skip
107*4882a593Smuzhiyun	fi
108*4882a593Smuzhiyun	if ! which diff 2> /dev/null > /dev/null; then
109*4882a593Smuzhiyun		echo "$0: You need diff installed"
110*4882a593Smuzhiyun		exit $ksft_skip
111*4882a593Smuzhiyun	fi
112*4882a593Smuzhiyun}
113*4882a593Smuzhiyun
114*4882a593Smuzhiyunfunction load_req_mod()
115*4882a593Smuzhiyun{
116*4882a593Smuzhiyun	if [ ! -d $SYSCTL ]; then
117*4882a593Smuzhiyun		if ! modprobe -q -n $TEST_DRIVER; then
118*4882a593Smuzhiyun			echo "$0: module $TEST_DRIVER not found [SKIP]"
119*4882a593Smuzhiyun			echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2
120*4882a593Smuzhiyun			exit $ksft_skip
121*4882a593Smuzhiyun		fi
122*4882a593Smuzhiyun		modprobe $TEST_DRIVER
123*4882a593Smuzhiyun		if [ $? -ne 0 ]; then
124*4882a593Smuzhiyun			echo "$0: modprobe $TEST_DRIVER failed."
125*4882a593Smuzhiyun			exit
126*4882a593Smuzhiyun		fi
127*4882a593Smuzhiyun	fi
128*4882a593Smuzhiyun}
129*4882a593Smuzhiyun
130*4882a593Smuzhiyunreset_vals()
131*4882a593Smuzhiyun{
132*4882a593Smuzhiyun	VAL=""
133*4882a593Smuzhiyun	TRIGGER=$(basename ${TARGET})
134*4882a593Smuzhiyun	case "$TRIGGER" in
135*4882a593Smuzhiyun		int_0001)
136*4882a593Smuzhiyun			VAL="60"
137*4882a593Smuzhiyun			;;
138*4882a593Smuzhiyun		int_0002)
139*4882a593Smuzhiyun			VAL="1"
140*4882a593Smuzhiyun			;;
141*4882a593Smuzhiyun		uint_0001)
142*4882a593Smuzhiyun			VAL="314"
143*4882a593Smuzhiyun			;;
144*4882a593Smuzhiyun		string_0001)
145*4882a593Smuzhiyun			VAL="(none)"
146*4882a593Smuzhiyun			;;
147*4882a593Smuzhiyun		bitmap_0001)
148*4882a593Smuzhiyun			VAL=""
149*4882a593Smuzhiyun			;;
150*4882a593Smuzhiyun		*)
151*4882a593Smuzhiyun			;;
152*4882a593Smuzhiyun	esac
153*4882a593Smuzhiyun	echo -n $VAL > $TARGET
154*4882a593Smuzhiyun}
155*4882a593Smuzhiyun
156*4882a593Smuzhiyunset_orig()
157*4882a593Smuzhiyun{
158*4882a593Smuzhiyun	if [ ! -z $TARGET ] && [ ! -z $ORIG ]; then
159*4882a593Smuzhiyun		if [ -f ${TARGET} ]; then
160*4882a593Smuzhiyun			echo "${ORIG}" > "${TARGET}"
161*4882a593Smuzhiyun		fi
162*4882a593Smuzhiyun	fi
163*4882a593Smuzhiyun}
164*4882a593Smuzhiyun
165*4882a593Smuzhiyunset_test()
166*4882a593Smuzhiyun{
167*4882a593Smuzhiyun	echo "${TEST_STR}" > "${TARGET}"
168*4882a593Smuzhiyun}
169*4882a593Smuzhiyun
170*4882a593Smuzhiyunverify()
171*4882a593Smuzhiyun{
172*4882a593Smuzhiyun	local seen
173*4882a593Smuzhiyun	seen=$(cat "$1")
174*4882a593Smuzhiyun	if [ "${seen}" != "${TEST_STR}" ]; then
175*4882a593Smuzhiyun		return 1
176*4882a593Smuzhiyun	fi
177*4882a593Smuzhiyun	return 0
178*4882a593Smuzhiyun}
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun# proc files get read a page at a time, which can confuse diff,
181*4882a593Smuzhiyun# and get you incorrect results on proc files with long data. To use
182*4882a593Smuzhiyun# diff against them you must first extract the output to a file, and
183*4882a593Smuzhiyun# then compare against that file.
184*4882a593Smuzhiyunverify_diff_proc_file()
185*4882a593Smuzhiyun{
186*4882a593Smuzhiyun	TMP_DUMP_FILE=$(mktemp)
187*4882a593Smuzhiyun	cat $1 > $TMP_DUMP_FILE
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun	if ! diff -w -q $TMP_DUMP_FILE $2; then
190*4882a593Smuzhiyun		return 1
191*4882a593Smuzhiyun	else
192*4882a593Smuzhiyun		return 0
193*4882a593Smuzhiyun	fi
194*4882a593Smuzhiyun}
195*4882a593Smuzhiyun
196*4882a593Smuzhiyunverify_diff_w()
197*4882a593Smuzhiyun{
198*4882a593Smuzhiyun	echo "$TEST_STR" | diff -q -w -u - $1 > /dev/null
199*4882a593Smuzhiyun	return $?
200*4882a593Smuzhiyun}
201*4882a593Smuzhiyun
202*4882a593Smuzhiyuntest_rc()
203*4882a593Smuzhiyun{
204*4882a593Smuzhiyun	if [[ $rc != 0 ]]; then
205*4882a593Smuzhiyun		echo "Failed test, return value: $rc" >&2
206*4882a593Smuzhiyun		exit $rc
207*4882a593Smuzhiyun	fi
208*4882a593Smuzhiyun}
209*4882a593Smuzhiyun
210*4882a593Smuzhiyuntest_finish()
211*4882a593Smuzhiyun{
212*4882a593Smuzhiyun	set_orig
213*4882a593Smuzhiyun	rm -f "${TEST_FILE}"
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun	if [ ! -z ${old_strict} ]; then
216*4882a593Smuzhiyun		echo ${old_strict} > ${WRITES_STRICT}
217*4882a593Smuzhiyun	fi
218*4882a593Smuzhiyun	exit $rc
219*4882a593Smuzhiyun}
220*4882a593Smuzhiyun
221*4882a593Smuzhiyunrun_numerictests()
222*4882a593Smuzhiyun{
223*4882a593Smuzhiyun	echo "== Testing sysctl behavior against ${TARGET} =="
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun	rc=0
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun	echo -n "Writing test file ... "
228*4882a593Smuzhiyun	echo "${TEST_STR}" > "${TEST_FILE}"
229*4882a593Smuzhiyun	if ! verify "${TEST_FILE}"; then
230*4882a593Smuzhiyun		echo "FAIL" >&2
231*4882a593Smuzhiyun		exit 1
232*4882a593Smuzhiyun	else
233*4882a593Smuzhiyun		echo "ok"
234*4882a593Smuzhiyun	fi
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun	echo -n "Checking sysctl is not set to test value ... "
237*4882a593Smuzhiyun	if verify "${TARGET}"; then
238*4882a593Smuzhiyun		echo "FAIL" >&2
239*4882a593Smuzhiyun		exit 1
240*4882a593Smuzhiyun	else
241*4882a593Smuzhiyun		echo "ok"
242*4882a593Smuzhiyun	fi
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun	echo -n "Writing sysctl from shell ... "
245*4882a593Smuzhiyun	set_test
246*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
247*4882a593Smuzhiyun		echo "FAIL" >&2
248*4882a593Smuzhiyun		exit 1
249*4882a593Smuzhiyun	else
250*4882a593Smuzhiyun		echo "ok"
251*4882a593Smuzhiyun	fi
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun	echo -n "Resetting sysctl to original value ... "
254*4882a593Smuzhiyun	set_orig
255*4882a593Smuzhiyun	if verify "${TARGET}"; then
256*4882a593Smuzhiyun		echo "FAIL" >&2
257*4882a593Smuzhiyun		exit 1
258*4882a593Smuzhiyun	else
259*4882a593Smuzhiyun		echo "ok"
260*4882a593Smuzhiyun	fi
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun	# Now that we've validated the sanity of "set_test" and "set_orig",
263*4882a593Smuzhiyun	# we can use those functions to set starting states before running
264*4882a593Smuzhiyun	# specific behavioral tests.
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun	echo -n "Writing entire sysctl in single write ... "
267*4882a593Smuzhiyun	set_orig
268*4882a593Smuzhiyun	dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null
269*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
270*4882a593Smuzhiyun		echo "FAIL" >&2
271*4882a593Smuzhiyun		rc=1
272*4882a593Smuzhiyun	else
273*4882a593Smuzhiyun		echo "ok"
274*4882a593Smuzhiyun	fi
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun	echo -n "Writing middle of sysctl after synchronized seek ... "
277*4882a593Smuzhiyun	set_test
278*4882a593Smuzhiyun	dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null
279*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
280*4882a593Smuzhiyun		echo "FAIL" >&2
281*4882a593Smuzhiyun		rc=1
282*4882a593Smuzhiyun	else
283*4882a593Smuzhiyun		echo "ok"
284*4882a593Smuzhiyun	fi
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun	echo -n "Writing beyond end of sysctl ... "
287*4882a593Smuzhiyun	set_orig
288*4882a593Smuzhiyun	dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null
289*4882a593Smuzhiyun	if verify "${TARGET}"; then
290*4882a593Smuzhiyun		echo "FAIL" >&2
291*4882a593Smuzhiyun		rc=1
292*4882a593Smuzhiyun	else
293*4882a593Smuzhiyun		echo "ok"
294*4882a593Smuzhiyun	fi
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun	echo -n "Writing sysctl with multiple long writes ... "
297*4882a593Smuzhiyun	set_orig
298*4882a593Smuzhiyun	(perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \
299*4882a593Smuzhiyun		dd of="${TARGET}" bs=50 2>/dev/null
300*4882a593Smuzhiyun	if verify "${TARGET}"; then
301*4882a593Smuzhiyun		echo "FAIL" >&2
302*4882a593Smuzhiyun		rc=1
303*4882a593Smuzhiyun	else
304*4882a593Smuzhiyun		echo "ok"
305*4882a593Smuzhiyun	fi
306*4882a593Smuzhiyun	test_rc
307*4882a593Smuzhiyun}
308*4882a593Smuzhiyun
309*4882a593Smuzhiyuncheck_failure()
310*4882a593Smuzhiyun{
311*4882a593Smuzhiyun	echo -n "Testing that $1 fails as expected..."
312*4882a593Smuzhiyun	reset_vals
313*4882a593Smuzhiyun	TEST_STR="$1"
314*4882a593Smuzhiyun	orig="$(cat $TARGET)"
315*4882a593Smuzhiyun	echo -n "$TEST_STR" > $TARGET 2> /dev/null
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun	# write should fail and $TARGET should retain its original value
318*4882a593Smuzhiyun	if [ $? = 0 ] || [ "$(cat $TARGET)" != "$orig" ]; then
319*4882a593Smuzhiyun		echo "FAIL" >&2
320*4882a593Smuzhiyun		rc=1
321*4882a593Smuzhiyun	else
322*4882a593Smuzhiyun		echo "ok"
323*4882a593Smuzhiyun	fi
324*4882a593Smuzhiyun	test_rc
325*4882a593Smuzhiyun}
326*4882a593Smuzhiyun
327*4882a593Smuzhiyunrun_wideint_tests()
328*4882a593Smuzhiyun{
329*4882a593Smuzhiyun	# sysctl conversion functions receive a boolean sign and ulong
330*4882a593Smuzhiyun	# magnitude; here we list the magnitudes we want to test (each of
331*4882a593Smuzhiyun	# which will be tested in both positive and negative forms).  Since
332*4882a593Smuzhiyun	# none of these values fit in 32 bits, writing them to an int- or
333*4882a593Smuzhiyun	# uint-typed sysctl should fail.
334*4882a593Smuzhiyun	local magnitudes=(
335*4882a593Smuzhiyun		# common boundary-condition values (zero, +1, -1, INT_MIN,
336*4882a593Smuzhiyun		# and INT_MAX respectively) if truncated to lower 32 bits
337*4882a593Smuzhiyun		# (potential for being falsely deemed in range)
338*4882a593Smuzhiyun		0x0000000100000000
339*4882a593Smuzhiyun		0x0000000100000001
340*4882a593Smuzhiyun		0x00000001ffffffff
341*4882a593Smuzhiyun		0x0000000180000000
342*4882a593Smuzhiyun		0x000000017fffffff
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun		# these look like negatives, but without a leading '-' are
345*4882a593Smuzhiyun		# actually large positives (should be rejected as above
346*4882a593Smuzhiyun		# despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32)
347*4882a593Smuzhiyun		0xffffffff00000000
348*4882a593Smuzhiyun		0xffffffff00000001
349*4882a593Smuzhiyun		0xffffffffffffffff
350*4882a593Smuzhiyun		0xffffffff80000000
351*4882a593Smuzhiyun		0xffffffff7fffffff
352*4882a593Smuzhiyun	)
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun	for sign in '' '-'; do
355*4882a593Smuzhiyun		for mag in "${magnitudes[@]}"; do
356*4882a593Smuzhiyun			check_failure "${sign}${mag}"
357*4882a593Smuzhiyun		done
358*4882a593Smuzhiyun	done
359*4882a593Smuzhiyun}
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun# Your test must accept digits 3 and 4 to use this
362*4882a593Smuzhiyunrun_limit_digit()
363*4882a593Smuzhiyun{
364*4882a593Smuzhiyun	echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ..."
365*4882a593Smuzhiyun	reset_vals
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun	LIMIT=$((MAX_DIGITS -1))
368*4882a593Smuzhiyun	TEST_STR="3"
369*4882a593Smuzhiyun	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
370*4882a593Smuzhiyun		dd of="${TARGET}" 2>/dev/null
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
373*4882a593Smuzhiyun		echo "FAIL" >&2
374*4882a593Smuzhiyun		rc=1
375*4882a593Smuzhiyun	else
376*4882a593Smuzhiyun		echo "ok"
377*4882a593Smuzhiyun	fi
378*4882a593Smuzhiyun	test_rc
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun	echo -n "Checking passing PAGE_SIZE of spaces fails on write ..."
381*4882a593Smuzhiyun	reset_vals
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun	LIMIT=$((MAX_DIGITS))
384*4882a593Smuzhiyun	TEST_STR="4"
385*4882a593Smuzhiyun	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
386*4882a593Smuzhiyun		dd of="${TARGET}" 2>/dev/null
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun	if verify "${TARGET}"; then
389*4882a593Smuzhiyun		echo "FAIL" >&2
390*4882a593Smuzhiyun		rc=1
391*4882a593Smuzhiyun	else
392*4882a593Smuzhiyun		echo "ok"
393*4882a593Smuzhiyun	fi
394*4882a593Smuzhiyun	test_rc
395*4882a593Smuzhiyun}
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun# You are using an int
398*4882a593Smuzhiyunrun_limit_digit_int()
399*4882a593Smuzhiyun{
400*4882a593Smuzhiyun	echo -n "Testing INT_MAX works ..."
401*4882a593Smuzhiyun	reset_vals
402*4882a593Smuzhiyun	TEST_STR="$INT_MAX"
403*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
406*4882a593Smuzhiyun		echo "FAIL" >&2
407*4882a593Smuzhiyun		rc=1
408*4882a593Smuzhiyun	else
409*4882a593Smuzhiyun		echo "ok"
410*4882a593Smuzhiyun	fi
411*4882a593Smuzhiyun	test_rc
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun	echo -n "Testing INT_MAX + 1 will fail as expected..."
414*4882a593Smuzhiyun	reset_vals
415*4882a593Smuzhiyun	let TEST_STR=$INT_MAX+1
416*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET 2> /dev/null
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun	if verify "${TARGET}"; then
419*4882a593Smuzhiyun		echo "FAIL" >&2
420*4882a593Smuzhiyun		rc=1
421*4882a593Smuzhiyun	else
422*4882a593Smuzhiyun		echo "ok"
423*4882a593Smuzhiyun	fi
424*4882a593Smuzhiyun	test_rc
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun	echo -n "Testing negative values will work as expected..."
427*4882a593Smuzhiyun	reset_vals
428*4882a593Smuzhiyun	TEST_STR="-3"
429*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET 2> /dev/null
430*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
431*4882a593Smuzhiyun		echo "FAIL" >&2
432*4882a593Smuzhiyun		rc=1
433*4882a593Smuzhiyun	else
434*4882a593Smuzhiyun		echo "ok"
435*4882a593Smuzhiyun	fi
436*4882a593Smuzhiyun	test_rc
437*4882a593Smuzhiyun}
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun# You used an int array
440*4882a593Smuzhiyunrun_limit_digit_int_array()
441*4882a593Smuzhiyun{
442*4882a593Smuzhiyun	echo -n "Testing array works as expected ... "
443*4882a593Smuzhiyun	TEST_STR="4 3 2 1"
444*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun	if ! verify_diff_w "${TARGET}"; then
447*4882a593Smuzhiyun		echo "FAIL" >&2
448*4882a593Smuzhiyun		rc=1
449*4882a593Smuzhiyun	else
450*4882a593Smuzhiyun		echo "ok"
451*4882a593Smuzhiyun	fi
452*4882a593Smuzhiyun	test_rc
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun	echo -n "Testing skipping trailing array elements works ... "
455*4882a593Smuzhiyun	# Do not reset_vals, carry on the values from the last test.
456*4882a593Smuzhiyun	# If we only echo in two digits the last two are left intact
457*4882a593Smuzhiyun	TEST_STR="100 101"
458*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET
459*4882a593Smuzhiyun	# After we echo in, to help diff we need to set on TEST_STR what
460*4882a593Smuzhiyun	# we expect the result to be.
461*4882a593Smuzhiyun	TEST_STR="100 101 2 1"
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun	if ! verify_diff_w "${TARGET}"; then
464*4882a593Smuzhiyun		echo "FAIL" >&2
465*4882a593Smuzhiyun		rc=1
466*4882a593Smuzhiyun	else
467*4882a593Smuzhiyun		echo "ok"
468*4882a593Smuzhiyun	fi
469*4882a593Smuzhiyun	test_rc
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun	echo -n "Testing PAGE_SIZE limit on array works ... "
472*4882a593Smuzhiyun	# Do not reset_vals, carry on the values from the last test.
473*4882a593Smuzhiyun	# Even if you use an int array, you are still restricted to
474*4882a593Smuzhiyun	# MAX_DIGITS, this is a known limitation. Test limit works.
475*4882a593Smuzhiyun	LIMIT=$((MAX_DIGITS -1))
476*4882a593Smuzhiyun	TEST_STR="9"
477*4882a593Smuzhiyun	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
478*4882a593Smuzhiyun		dd of="${TARGET}" 2>/dev/null
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun	TEST_STR="9 101 2 1"
481*4882a593Smuzhiyun	if ! verify_diff_w "${TARGET}"; then
482*4882a593Smuzhiyun		echo "FAIL" >&2
483*4882a593Smuzhiyun		rc=1
484*4882a593Smuzhiyun	else
485*4882a593Smuzhiyun		echo "ok"
486*4882a593Smuzhiyun	fi
487*4882a593Smuzhiyun	test_rc
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun	echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "
490*4882a593Smuzhiyun	# Do not reset_vals, carry on the values from the last test.
491*4882a593Smuzhiyun	# Now go over limit.
492*4882a593Smuzhiyun	LIMIT=$((MAX_DIGITS))
493*4882a593Smuzhiyun	TEST_STR="7"
494*4882a593Smuzhiyun	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
495*4882a593Smuzhiyun		dd of="${TARGET}" 2>/dev/null
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun	TEST_STR="7 101 2 1"
498*4882a593Smuzhiyun	if verify_diff_w "${TARGET}"; then
499*4882a593Smuzhiyun		echo "FAIL" >&2
500*4882a593Smuzhiyun		rc=1
501*4882a593Smuzhiyun	else
502*4882a593Smuzhiyun		echo "ok"
503*4882a593Smuzhiyun	fi
504*4882a593Smuzhiyun	test_rc
505*4882a593Smuzhiyun}
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun# You are using an unsigned int
508*4882a593Smuzhiyunrun_limit_digit_uint()
509*4882a593Smuzhiyun{
510*4882a593Smuzhiyun	echo -n "Testing UINT_MAX works ..."
511*4882a593Smuzhiyun	reset_vals
512*4882a593Smuzhiyun	TEST_STR="$UINT_MAX"
513*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
516*4882a593Smuzhiyun		echo "FAIL" >&2
517*4882a593Smuzhiyun		rc=1
518*4882a593Smuzhiyun	else
519*4882a593Smuzhiyun		echo "ok"
520*4882a593Smuzhiyun	fi
521*4882a593Smuzhiyun	test_rc
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun	echo -n "Testing UINT_MAX + 1 will fail as expected..."
524*4882a593Smuzhiyun	reset_vals
525*4882a593Smuzhiyun	TEST_STR=$(($UINT_MAX+1))
526*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET 2> /dev/null
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun	if verify "${TARGET}"; then
529*4882a593Smuzhiyun		echo "FAIL" >&2
530*4882a593Smuzhiyun		rc=1
531*4882a593Smuzhiyun	else
532*4882a593Smuzhiyun		echo "ok"
533*4882a593Smuzhiyun	fi
534*4882a593Smuzhiyun	test_rc
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun	echo -n "Testing negative values will not work as expected ..."
537*4882a593Smuzhiyun	reset_vals
538*4882a593Smuzhiyun	TEST_STR="-3"
539*4882a593Smuzhiyun	echo -n $TEST_STR > $TARGET 2> /dev/null
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun	if verify "${TARGET}"; then
542*4882a593Smuzhiyun		echo "FAIL" >&2
543*4882a593Smuzhiyun		rc=1
544*4882a593Smuzhiyun	else
545*4882a593Smuzhiyun		echo "ok"
546*4882a593Smuzhiyun	fi
547*4882a593Smuzhiyun	test_rc
548*4882a593Smuzhiyun}
549*4882a593Smuzhiyun
550*4882a593Smuzhiyunrun_stringtests()
551*4882a593Smuzhiyun{
552*4882a593Smuzhiyun	echo -n "Writing entire sysctl in short writes ... "
553*4882a593Smuzhiyun	set_orig
554*4882a593Smuzhiyun	dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null
555*4882a593Smuzhiyun	if ! verify "${TARGET}"; then
556*4882a593Smuzhiyun		echo "FAIL" >&2
557*4882a593Smuzhiyun		rc=1
558*4882a593Smuzhiyun	else
559*4882a593Smuzhiyun		echo "ok"
560*4882a593Smuzhiyun	fi
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun	echo -n "Writing middle of sysctl after unsynchronized seek ... "
563*4882a593Smuzhiyun	set_test
564*4882a593Smuzhiyun	dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null
565*4882a593Smuzhiyun	if verify "${TARGET}"; then
566*4882a593Smuzhiyun		echo "FAIL" >&2
567*4882a593Smuzhiyun		rc=1
568*4882a593Smuzhiyun	else
569*4882a593Smuzhiyun		echo "ok"
570*4882a593Smuzhiyun	fi
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun	echo -n "Checking sysctl maxlen is at least $MAXLEN ... "
573*4882a593Smuzhiyun	set_orig
574*4882a593Smuzhiyun	perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \
575*4882a593Smuzhiyun		dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
576*4882a593Smuzhiyun	if ! grep -q B "${TARGET}"; then
577*4882a593Smuzhiyun		echo "FAIL" >&2
578*4882a593Smuzhiyun		rc=1
579*4882a593Smuzhiyun	else
580*4882a593Smuzhiyun		echo "ok"
581*4882a593Smuzhiyun	fi
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun	echo -n "Checking sysctl keeps original string on overflow append ... "
584*4882a593Smuzhiyun	set_orig
585*4882a593Smuzhiyun	perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
586*4882a593Smuzhiyun		dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null
587*4882a593Smuzhiyun	if grep -q B "${TARGET}"; then
588*4882a593Smuzhiyun		echo "FAIL" >&2
589*4882a593Smuzhiyun		rc=1
590*4882a593Smuzhiyun	else
591*4882a593Smuzhiyun		echo "ok"
592*4882a593Smuzhiyun	fi
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun	echo -n "Checking sysctl stays NULL terminated on write ... "
595*4882a593Smuzhiyun	set_orig
596*4882a593Smuzhiyun	perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
597*4882a593Smuzhiyun		dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
598*4882a593Smuzhiyun	if grep -q B "${TARGET}"; then
599*4882a593Smuzhiyun		echo "FAIL" >&2
600*4882a593Smuzhiyun		rc=1
601*4882a593Smuzhiyun	else
602*4882a593Smuzhiyun		echo "ok"
603*4882a593Smuzhiyun	fi
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun	echo -n "Checking sysctl stays NULL terminated on overwrite ... "
606*4882a593Smuzhiyun	set_orig
607*4882a593Smuzhiyun	perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \
608*4882a593Smuzhiyun		dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null
609*4882a593Smuzhiyun	if grep -q B "${TARGET}"; then
610*4882a593Smuzhiyun		echo "FAIL" >&2
611*4882a593Smuzhiyun		rc=1
612*4882a593Smuzhiyun	else
613*4882a593Smuzhiyun		echo "ok"
614*4882a593Smuzhiyun	fi
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun	test_rc
617*4882a593Smuzhiyun}
618*4882a593Smuzhiyun
619*4882a593Smuzhiyuntarget_exists()
620*4882a593Smuzhiyun{
621*4882a593Smuzhiyun	TARGET="${SYSCTL}/$1"
622*4882a593Smuzhiyun	TEST_ID="$2"
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun	if [ ! -f ${TARGET} ] ; then
625*4882a593Smuzhiyun		echo "Target for test $TEST_ID: $TARGET not exist, skipping test ..."
626*4882a593Smuzhiyun		return 0
627*4882a593Smuzhiyun	fi
628*4882a593Smuzhiyun	return 1
629*4882a593Smuzhiyun}
630*4882a593Smuzhiyun
631*4882a593Smuzhiyunrun_bitmaptest() {
632*4882a593Smuzhiyun	# Total length of bitmaps string to use, a bit under
633*4882a593Smuzhiyun	# the maximum input size of the test node
634*4882a593Smuzhiyun	LENGTH=$((RANDOM % 65000))
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun	# First bit to set
637*4882a593Smuzhiyun	BIT=$((RANDOM % 1024))
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun	# String containing our list of bits to set
640*4882a593Smuzhiyun	TEST_STR=$BIT
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun	# build up the string
643*4882a593Smuzhiyun	while [ "${#TEST_STR}" -le "$LENGTH" ]; do
644*4882a593Smuzhiyun		# Make sure next entry is discontiguous,
645*4882a593Smuzhiyun		# skip ahead at least 2
646*4882a593Smuzhiyun		BIT=$((BIT + $((2 + RANDOM % 10))))
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun		# Add new bit to the list
649*4882a593Smuzhiyun		TEST_STR="${TEST_STR},${BIT}"
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun		# Randomly make it a range
652*4882a593Smuzhiyun		if [ "$((RANDOM % 2))" -eq "1" ]; then
653*4882a593Smuzhiyun			RANGE_END=$((BIT + $((1 + RANDOM % 10))))
654*4882a593Smuzhiyun			TEST_STR="${TEST_STR}-${RANGE_END}"
655*4882a593Smuzhiyun			BIT=$RANGE_END
656*4882a593Smuzhiyun		fi
657*4882a593Smuzhiyun	done
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun	echo -n "Checking bitmap handler... "
660*4882a593Smuzhiyun	TEST_FILE=$(mktemp)
661*4882a593Smuzhiyun	echo -n "$TEST_STR" > $TEST_FILE
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun	cat $TEST_FILE > $TARGET 2> /dev/null
664*4882a593Smuzhiyun	if [ $? -ne 0 ]; then
665*4882a593Smuzhiyun		echo "FAIL" >&2
666*4882a593Smuzhiyun		rc=1
667*4882a593Smuzhiyun		test_rc
668*4882a593Smuzhiyun	fi
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun	if ! verify_diff_proc_file "$TARGET" "$TEST_FILE"; then
671*4882a593Smuzhiyun		echo "FAIL" >&2
672*4882a593Smuzhiyun		rc=1
673*4882a593Smuzhiyun	else
674*4882a593Smuzhiyun		echo "ok"
675*4882a593Smuzhiyun		rc=0
676*4882a593Smuzhiyun	fi
677*4882a593Smuzhiyun	test_rc
678*4882a593Smuzhiyun}
679*4882a593Smuzhiyun
680*4882a593Smuzhiyunsysctl_test_0001()
681*4882a593Smuzhiyun{
682*4882a593Smuzhiyun	TARGET="${SYSCTL}/$(get_test_target 0001)"
683*4882a593Smuzhiyun	reset_vals
684*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
685*4882a593Smuzhiyun	TEST_STR=$(( $ORIG + 1 ))
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun	run_numerictests
688*4882a593Smuzhiyun	run_wideint_tests
689*4882a593Smuzhiyun	run_limit_digit
690*4882a593Smuzhiyun}
691*4882a593Smuzhiyun
692*4882a593Smuzhiyunsysctl_test_0002()
693*4882a593Smuzhiyun{
694*4882a593Smuzhiyun	TARGET="${SYSCTL}/$(get_test_target 0002)"
695*4882a593Smuzhiyun	reset_vals
696*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
697*4882a593Smuzhiyun	TEST_STR="Testing sysctl"
698*4882a593Smuzhiyun	# Only string sysctls support seeking/appending.
699*4882a593Smuzhiyun	MAXLEN=65
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun	run_numerictests
702*4882a593Smuzhiyun	run_stringtests
703*4882a593Smuzhiyun}
704*4882a593Smuzhiyun
705*4882a593Smuzhiyunsysctl_test_0003()
706*4882a593Smuzhiyun{
707*4882a593Smuzhiyun	TARGET="${SYSCTL}/$(get_test_target 0003)"
708*4882a593Smuzhiyun	reset_vals
709*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
710*4882a593Smuzhiyun	TEST_STR=$(( $ORIG + 1 ))
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun	run_numerictests
713*4882a593Smuzhiyun	run_wideint_tests
714*4882a593Smuzhiyun	run_limit_digit
715*4882a593Smuzhiyun	run_limit_digit_int
716*4882a593Smuzhiyun}
717*4882a593Smuzhiyun
718*4882a593Smuzhiyunsysctl_test_0004()
719*4882a593Smuzhiyun{
720*4882a593Smuzhiyun	TARGET="${SYSCTL}/$(get_test_target 0004)"
721*4882a593Smuzhiyun	reset_vals
722*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
723*4882a593Smuzhiyun	TEST_STR=$(( $ORIG + 1 ))
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun	run_numerictests
726*4882a593Smuzhiyun	run_wideint_tests
727*4882a593Smuzhiyun	run_limit_digit
728*4882a593Smuzhiyun	run_limit_digit_uint
729*4882a593Smuzhiyun}
730*4882a593Smuzhiyun
731*4882a593Smuzhiyunsysctl_test_0005()
732*4882a593Smuzhiyun{
733*4882a593Smuzhiyun	TARGET="${SYSCTL}/$(get_test_target 0005)"
734*4882a593Smuzhiyun	reset_vals
735*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun	run_limit_digit_int_array
738*4882a593Smuzhiyun}
739*4882a593Smuzhiyun
740*4882a593Smuzhiyunsysctl_test_0006()
741*4882a593Smuzhiyun{
742*4882a593Smuzhiyun	TARGET="${SYSCTL}/bitmap_0001"
743*4882a593Smuzhiyun	reset_vals
744*4882a593Smuzhiyun	ORIG=""
745*4882a593Smuzhiyun	run_bitmaptest
746*4882a593Smuzhiyun}
747*4882a593Smuzhiyun
748*4882a593Smuzhiyunsysctl_test_0007()
749*4882a593Smuzhiyun{
750*4882a593Smuzhiyun	TARGET="${SYSCTL}/boot_int"
751*4882a593Smuzhiyun	if [ ! -f $TARGET ]; then
752*4882a593Smuzhiyun		echo "Skipping test for $TARGET as it is not present ..."
753*4882a593Smuzhiyun		return $ksft_skip
754*4882a593Smuzhiyun	fi
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun	if [ -d $DIR ]; then
757*4882a593Smuzhiyun		echo "Boot param test only possible sysctl_test is built-in, not module:"
758*4882a593Smuzhiyun		cat $TEST_DIR/config >&2
759*4882a593Smuzhiyun		return $ksft_skip
760*4882a593Smuzhiyun	fi
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun	echo -n "Testing if $TARGET is set to 1 ..."
763*4882a593Smuzhiyun	ORIG=$(cat "${TARGET}")
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun	if [ x$ORIG = "x1" ]; then
766*4882a593Smuzhiyun		echo "ok"
767*4882a593Smuzhiyun		return 0
768*4882a593Smuzhiyun	fi
769*4882a593Smuzhiyun	echo "FAIL"
770*4882a593Smuzhiyun	echo "Checking if /proc/cmdline contains setting of the expected parameter ..."
771*4882a593Smuzhiyun	if [ ! -f /proc/cmdline ]; then
772*4882a593Smuzhiyun		echo "/proc/cmdline does not exist, test inconclusive"
773*4882a593Smuzhiyun		return 0
774*4882a593Smuzhiyun	fi
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun	FOUND=$(grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline)
777*4882a593Smuzhiyun	if [ $FOUND = "1" ]; then
778*4882a593Smuzhiyun		echo "Kernel param found but $TARGET is not 1, TEST FAILED"
779*4882a593Smuzhiyun		rc=1
780*4882a593Smuzhiyun		test_rc
781*4882a593Smuzhiyun	fi
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun	echo "Skipping test, expected kernel parameter missing."
784*4882a593Smuzhiyun	echo "To perform this test, make sure kernel is booted with parameter: sysctl.debug.test_sysctl.boot_int=1"
785*4882a593Smuzhiyun	return $ksft_skip
786*4882a593Smuzhiyun}
787*4882a593Smuzhiyun
788*4882a593Smuzhiyunlist_tests()
789*4882a593Smuzhiyun{
790*4882a593Smuzhiyun	echo "Test ID list:"
791*4882a593Smuzhiyun	echo
792*4882a593Smuzhiyun	echo "TEST_ID x NUM_TEST"
793*4882a593Smuzhiyun	echo "TEST_ID:   Test ID"
794*4882a593Smuzhiyun	echo "NUM_TESTS: Number of recommended times to run the test"
795*4882a593Smuzhiyun	echo
796*4882a593Smuzhiyun	echo "0001 x $(get_test_count 0001) - tests proc_dointvec_minmax()"
797*4882a593Smuzhiyun	echo "0002 x $(get_test_count 0002) - tests proc_dostring()"
798*4882a593Smuzhiyun	echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"
799*4882a593Smuzhiyun	echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"
800*4882a593Smuzhiyun	echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"
801*4882a593Smuzhiyun	echo "0006 x $(get_test_count 0006) - tests proc_do_large_bitmap()"
802*4882a593Smuzhiyun	echo "0007 x $(get_test_count 0007) - tests setting sysctl from kernel boot param"
803*4882a593Smuzhiyun}
804*4882a593Smuzhiyun
805*4882a593Smuzhiyunusage()
806*4882a593Smuzhiyun{
807*4882a593Smuzhiyun	NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)
808*4882a593Smuzhiyun	let NUM_TESTS=$NUM_TESTS+1
809*4882a593Smuzhiyun	MAX_TEST=$(printf "%04d\n" $NUM_TESTS)
810*4882a593Smuzhiyun	echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"
811*4882a593Smuzhiyun	echo "		 [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
812*4882a593Smuzhiyun	echo "           [ all ] [ -h | --help ] [ -l ]"
813*4882a593Smuzhiyun	echo ""
814*4882a593Smuzhiyun	echo "Valid tests: 0001-$MAX_TEST"
815*4882a593Smuzhiyun	echo ""
816*4882a593Smuzhiyun	echo "    all     Runs all tests (default)"
817*4882a593Smuzhiyun	echo "    -t      Run test ID the number amount of times is recommended"
818*4882a593Smuzhiyun	echo "    -w      Watch test ID run until it runs into an error"
819*4882a593Smuzhiyun	echo "    -c      Run test ID once"
820*4882a593Smuzhiyun	echo "    -s      Run test ID x test-count number of times"
821*4882a593Smuzhiyun	echo "    -l      List all test ID list"
822*4882a593Smuzhiyun	echo " -h|--help  Help"
823*4882a593Smuzhiyun	echo
824*4882a593Smuzhiyun	echo "If an error every occurs execution will immediately terminate."
825*4882a593Smuzhiyun	echo "If you are adding a new test try using -w <test-ID> first to"
826*4882a593Smuzhiyun	echo "make sure the test passes a series of tests."
827*4882a593Smuzhiyun	echo
828*4882a593Smuzhiyun	echo Example uses:
829*4882a593Smuzhiyun	echo
830*4882a593Smuzhiyun	echo "$TEST_NAME.sh            -- executes all tests"
831*4882a593Smuzhiyun	echo "$TEST_NAME.sh -t 0002    -- Executes test ID 0002 number of times is recomended"
832*4882a593Smuzhiyun	echo "$TEST_NAME.sh -w 0002    -- Watch test ID 0002 run until an error occurs"
833*4882a593Smuzhiyun	echo "$TEST_NAME.sh -s 0002    -- Run test ID 0002 once"
834*4882a593Smuzhiyun	echo "$TEST_NAME.sh -c 0002 3  -- Run test ID 0002 three times"
835*4882a593Smuzhiyun	echo
836*4882a593Smuzhiyun	list_tests
837*4882a593Smuzhiyun	exit 1
838*4882a593Smuzhiyun}
839*4882a593Smuzhiyun
840*4882a593Smuzhiyunfunction test_num()
841*4882a593Smuzhiyun{
842*4882a593Smuzhiyun	re='^[0-9]+$'
843*4882a593Smuzhiyun	if ! [[ $1 =~ $re ]]; then
844*4882a593Smuzhiyun		usage
845*4882a593Smuzhiyun	fi
846*4882a593Smuzhiyun}
847*4882a593Smuzhiyun
848*4882a593Smuzhiyunfunction get_test_count()
849*4882a593Smuzhiyun{
850*4882a593Smuzhiyun	test_num $1
851*4882a593Smuzhiyun	TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
852*4882a593Smuzhiyun	echo ${TEST_DATA} | awk -F":" '{print $2}'
853*4882a593Smuzhiyun}
854*4882a593Smuzhiyun
855*4882a593Smuzhiyunfunction get_test_enabled()
856*4882a593Smuzhiyun{
857*4882a593Smuzhiyun	test_num $1
858*4882a593Smuzhiyun	TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
859*4882a593Smuzhiyun	echo ${TEST_DATA} | awk -F":" '{print $3}'
860*4882a593Smuzhiyun}
861*4882a593Smuzhiyun
862*4882a593Smuzhiyunfunction get_test_target()
863*4882a593Smuzhiyun{
864*4882a593Smuzhiyun	test_num $1
865*4882a593Smuzhiyun	TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
866*4882a593Smuzhiyun	echo ${TEST_DATA} | awk -F":" '{print $4}'
867*4882a593Smuzhiyun}
868*4882a593Smuzhiyun
869*4882a593Smuzhiyunfunction run_all_tests()
870*4882a593Smuzhiyun{
871*4882a593Smuzhiyun	for i in $ALL_TESTS ; do
872*4882a593Smuzhiyun		TEST_ID=${i%:*:*:*}
873*4882a593Smuzhiyun		ENABLED=$(get_test_enabled $TEST_ID)
874*4882a593Smuzhiyun		TEST_COUNT=$(get_test_count $TEST_ID)
875*4882a593Smuzhiyun		TEST_TARGET=$(get_test_target $TEST_ID)
876*4882a593Smuzhiyun		if target_exists $TEST_TARGET $TEST_ID; then
877*4882a593Smuzhiyun			continue
878*4882a593Smuzhiyun		fi
879*4882a593Smuzhiyun		if [[ $ENABLED -eq "1" ]]; then
880*4882a593Smuzhiyun			test_case $TEST_ID $TEST_COUNT $TEST_TARGET
881*4882a593Smuzhiyun		fi
882*4882a593Smuzhiyun	done
883*4882a593Smuzhiyun}
884*4882a593Smuzhiyun
885*4882a593Smuzhiyunfunction watch_log()
886*4882a593Smuzhiyun{
887*4882a593Smuzhiyun	if [ $# -ne 3 ]; then
888*4882a593Smuzhiyun		clear
889*4882a593Smuzhiyun	fi
890*4882a593Smuzhiyun	date
891*4882a593Smuzhiyun	echo "Running test: $2 - run #$1"
892*4882a593Smuzhiyun}
893*4882a593Smuzhiyun
894*4882a593Smuzhiyunfunction watch_case()
895*4882a593Smuzhiyun{
896*4882a593Smuzhiyun	i=0
897*4882a593Smuzhiyun	while [ 1 ]; do
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun		if [ $# -eq 1 ]; then
900*4882a593Smuzhiyun			test_num $1
901*4882a593Smuzhiyun			watch_log $i ${TEST_NAME}_test_$1
902*4882a593Smuzhiyun			${TEST_NAME}_test_$1
903*4882a593Smuzhiyun		else
904*4882a593Smuzhiyun			watch_log $i all
905*4882a593Smuzhiyun			run_all_tests
906*4882a593Smuzhiyun		fi
907*4882a593Smuzhiyun		let i=$i+1
908*4882a593Smuzhiyun	done
909*4882a593Smuzhiyun}
910*4882a593Smuzhiyun
911*4882a593Smuzhiyunfunction test_case()
912*4882a593Smuzhiyun{
913*4882a593Smuzhiyun	NUM_TESTS=$2
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun	i=0
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun	if target_exists $3 $1; then
918*4882a593Smuzhiyun		continue
919*4882a593Smuzhiyun	fi
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun	while [ $i -lt $NUM_TESTS ]; do
922*4882a593Smuzhiyun		test_num $1
923*4882a593Smuzhiyun		watch_log $i ${TEST_NAME}_test_$1 noclear
924*4882a593Smuzhiyun		RUN_TEST=${TEST_NAME}_test_$1
925*4882a593Smuzhiyun		$RUN_TEST
926*4882a593Smuzhiyun		let i=$i+1
927*4882a593Smuzhiyun	done
928*4882a593Smuzhiyun}
929*4882a593Smuzhiyun
930*4882a593Smuzhiyunfunction parse_args()
931*4882a593Smuzhiyun{
932*4882a593Smuzhiyun	if [ $# -eq 0 ]; then
933*4882a593Smuzhiyun		run_all_tests
934*4882a593Smuzhiyun	else
935*4882a593Smuzhiyun		if [[ "$1" = "all" ]]; then
936*4882a593Smuzhiyun			run_all_tests
937*4882a593Smuzhiyun		elif [[ "$1" = "-w" ]]; then
938*4882a593Smuzhiyun			shift
939*4882a593Smuzhiyun			watch_case $@
940*4882a593Smuzhiyun		elif [[ "$1" = "-t" ]]; then
941*4882a593Smuzhiyun			shift
942*4882a593Smuzhiyun			test_num $1
943*4882a593Smuzhiyun			test_case $1 $(get_test_count $1) $(get_test_target $1)
944*4882a593Smuzhiyun		elif [[ "$1" = "-c" ]]; then
945*4882a593Smuzhiyun			shift
946*4882a593Smuzhiyun			test_num $1
947*4882a593Smuzhiyun			test_num $2
948*4882a593Smuzhiyun			test_case $1 $2 $(get_test_target $1)
949*4882a593Smuzhiyun		elif [[ "$1" = "-s" ]]; then
950*4882a593Smuzhiyun			shift
951*4882a593Smuzhiyun			test_case $1 1 $(get_test_target $1)
952*4882a593Smuzhiyun		elif [[ "$1" = "-l" ]]; then
953*4882a593Smuzhiyun			list_tests
954*4882a593Smuzhiyun		elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
955*4882a593Smuzhiyun			usage
956*4882a593Smuzhiyun		else
957*4882a593Smuzhiyun			usage
958*4882a593Smuzhiyun		fi
959*4882a593Smuzhiyun	fi
960*4882a593Smuzhiyun}
961*4882a593Smuzhiyun
962*4882a593Smuzhiyuntest_reqs
963*4882a593Smuzhiyunallow_user_defaults
964*4882a593Smuzhiyuncheck_production_sysctl_writes_strict
965*4882a593Smuzhiyunload_req_mod
966*4882a593Smuzhiyun
967*4882a593Smuzhiyuntrap "test_finish" EXIT
968*4882a593Smuzhiyun
969*4882a593Smuzhiyunparse_args $@
970*4882a593Smuzhiyun
971*4882a593Smuzhiyunexit 0
972