2017-07-12 14:33:46 -07:00
#!/bin/bash
# Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or at your option any
# later version; or, when distributed separately from the Linux kernel or
# when incorporated into other software packages, subject to the following
# license:
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of copyleft-next (version 0.3.1 or later) as published
# at http://copyleft-next.org/.
# This performs a series tests against the proc sysctl interface.
2018-06-12 18:11:37 -06:00
# Kselftest framework requirement - SKIP code is 4.
ksft_skip = 4
2017-07-12 14:33:46 -07:00
TEST_NAME = "sysctl"
TEST_DRIVER = " test_ ${ TEST_NAME } "
TEST_DIR = $( dirname $0 )
TEST_FILE = $( mktemp)
# This represents
#
2019-05-14 15:45:07 -07:00
# TEST_ID:TEST_COUNT:ENABLED:TARGET
2017-07-12 14:33:46 -07:00
#
# TEST_ID: is the test id number
# TEST_COUNT: number of times we should run the test
# ENABLED: 1 if enabled, 0 otherwise
2019-05-14 15:45:07 -07:00
# TARGET: test target file required on the test_sysctl module
2017-07-12 14:33:46 -07:00
#
# Once these are enabled please leave them as-is. Write your own test,
# we have tons of space.
2019-05-14 15:45:07 -07:00
ALL_TESTS = "0001:1:1:int_0001"
ALL_TESTS = " $ALL_TESTS 0002:1:1:string_0001 "
ALL_TESTS = " $ALL_TESTS 0003:1:1:int_0002 "
ALL_TESTS = " $ALL_TESTS 0004:1:1:uint_0001 "
ALL_TESTS = " $ALL_TESTS 0005:3:1:int_0003 "
2019-05-14 15:45:10 -07:00
ALL_TESTS = " $ALL_TESTS 0006:50:1:bitmap_0001 "
2020-06-07 21:40:38 -07:00
ALL_TESTS = " $ALL_TESTS 0007:1:1:boot_int "
2022-05-01 11:55:24 +08:00
ALL_TESTS = " $ALL_TESTS 0008:1:1:match_int "
2017-07-12 14:33:46 -07:00
function allow_user_defaults( )
{
if [ -z $DIR ] ; then
DIR = "/sys/module/test_sysctl/"
fi
if [ -z $DEFAULT_NUM_TESTS ] ; then
DEFAULT_NUM_TESTS = 50
fi
if [ -z $SYSCTL ] ; then
SYSCTL = "/proc/sys/debug/test_sysctl"
fi
if [ -z $PROD_SYSCTL ] ; then
PROD_SYSCTL = "/proc/sys"
fi
if [ -z $WRITES_STRICT ] ; then
WRITES_STRICT = " ${ PROD_SYSCTL } /kernel/sysctl_writes_strict "
fi
}
function check_production_sysctl_writes_strict( )
{
echo -n "Checking production write strict setting ... "
if [ ! -e ${ WRITES_STRICT } ] ; then
echo "FAIL, but skip in case of old kernel" >& 2
else
old_strict = $( cat ${ WRITES_STRICT } )
if [ " $old_strict " = "1" ] ; then
echo "ok"
else
echo "FAIL, strict value is 0 but force to 1 to continue" >& 2
echo "1" > ${ WRITES_STRICT }
fi
fi
2017-07-12 14:33:49 -07:00
if [ -z $PAGE_SIZE ] ; then
PAGE_SIZE = $( getconf PAGESIZE)
fi
if [ -z $MAX_DIGITS ] ; then
MAX_DIGITS = $(( $PAGE_SIZE / 8 ))
fi
2017-07-12 14:33:52 -07:00
if [ -z $INT_MAX ] ; then
INT_MAX = $( getconf INT_MAX)
fi
2017-07-12 14:33:55 -07:00
if [ -z $UINT_MAX ] ; then
UINT_MAX = $( getconf UINT_MAX)
fi
2017-07-12 14:33:46 -07:00
}
test_reqs( )
{
uid = $( id -u)
if [ $uid -ne 0 ] ; then
echo $msg must be run as root >& 2
2018-06-12 18:11:37 -06:00
exit $ksft_skip
2017-07-12 14:33:46 -07:00
fi
if ! which perl 2> /dev/null > /dev/null; then
echo " $0 : You need perl installed "
2018-06-12 18:11:37 -06:00
exit $ksft_skip
2017-07-12 14:33:46 -07:00
fi
2017-07-12 14:33:49 -07:00
if ! which getconf 2> /dev/null > /dev/null; then
echo " $0 : You need getconf installed "
2018-06-12 18:11:37 -06:00
exit $ksft_skip
2017-07-12 14:33:49 -07:00
fi
2017-07-12 14:33:58 -07:00
if ! which diff 2> /dev/null > /dev/null; then
echo " $0 : You need diff installed "
2018-06-12 18:11:37 -06:00
exit $ksft_skip
2017-07-12 14:33:58 -07:00
fi
2017-07-12 14:33:46 -07:00
}
function load_req_mod( )
{
2020-06-07 21:40:35 -07:00
if [ ! -d $SYSCTL ] ; then
2018-06-12 18:11:37 -06:00
if ! modprobe -q -n $TEST_DRIVER ; then
echo " $0 : module $TEST_DRIVER not found [SKIP] "
2020-05-28 23:52:26 +09:00
echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >& 2
2018-06-12 18:11:37 -06:00
exit $ksft_skip
fi
2017-07-12 14:33:46 -07:00
modprobe $TEST_DRIVER
if [ $? -ne 0 ] ; then
2020-05-28 23:52:26 +09:00
echo " $0 : modprobe $TEST_DRIVER failed. "
2017-07-12 14:33:46 -07:00
exit
fi
fi
}
2017-07-12 14:33:49 -07:00
reset_vals( )
{
VAL = ""
TRIGGER = $( basename ${ TARGET } )
case " $TRIGGER " in
int_0001)
VAL = "60"
; ;
2017-07-12 14:33:52 -07:00
int_0002)
VAL = "1"
; ;
2017-07-12 14:33:55 -07:00
uint_0001)
VAL = "314"
; ;
2017-07-12 14:33:49 -07:00
string_0001)
VAL = "(none)"
; ;
2019-05-14 15:45:10 -07:00
bitmap_0001)
VAL = ""
; ;
2017-07-12 14:33:49 -07:00
*)
; ;
esac
echo -n $VAL > $TARGET
}
2017-07-12 14:33:46 -07:00
set_orig( )
{
2019-05-14 15:45:07 -07:00
if [ ! -z $TARGET ] && [ ! -z $ORIG ] ; then
if [ -f ${ TARGET } ] ; then
echo " ${ ORIG } " > " ${ TARGET } "
fi
2017-07-12 14:33:46 -07:00
fi
}
set_test( )
{
echo " ${ TEST_STR } " > " ${ TARGET } "
}
verify( )
{
local seen
seen = $( cat " $1 " )
if [ " ${ seen } " != " ${ TEST_STR } " ] ; then
return 1
fi
return 0
}
2019-05-14 15:45:10 -07:00
# proc files get read a page at a time, which can confuse diff,
# and get you incorrect results on proc files with long data. To use
# diff against them you must first extract the output to a file, and
# then compare against that file.
verify_diff_proc_file( )
{
TMP_DUMP_FILE = $( mktemp)
cat $1 > $TMP_DUMP_FILE
if ! diff -w -q $TMP_DUMP_FILE $2 ; then
return 1
else
return 0
fi
}
2017-07-12 14:33:58 -07:00
verify_diff_w( )
{
2019-05-14 15:45:04 -07:00
echo " $TEST_STR " | diff -q -w -u - $1 > /dev/null
2017-07-12 14:33:58 -07:00
return $?
}
2017-07-12 14:33:46 -07:00
test_rc( )
{
if [ [ $rc != 0 ] ] ; then
echo " Failed test, return value: $rc " >& 2
exit $rc
fi
}
test_finish( )
{
set_orig
rm -f " ${ TEST_FILE } "
if [ ! -z ${ old_strict } ] ; then
echo ${ old_strict } > ${ WRITES_STRICT }
fi
exit $rc
}
run_numerictests( )
{
echo " == Testing sysctl behavior against ${ TARGET } == "
rc = 0
echo -n "Writing test file ... "
echo " ${ TEST_STR } " > " ${ TEST_FILE } "
if ! verify " ${ TEST_FILE } " ; then
echo "FAIL" >& 2
exit 1
else
echo "ok"
fi
echo -n "Checking sysctl is not set to test value ... "
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
exit 1
else
echo "ok"
fi
echo -n "Writing sysctl from shell ... "
set_test
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
exit 1
else
echo "ok"
fi
echo -n "Resetting sysctl to original value ... "
set_orig
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
exit 1
else
echo "ok"
fi
# Now that we've validated the sanity of "set_test" and "set_orig",
# we can use those functions to set starting states before running
# specific behavioral tests.
echo -n "Writing entire sysctl in single write ... "
set_orig
dd if = " ${ TEST_FILE } " of = " ${ TARGET } " bs = 4096 2>/dev/null
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Writing middle of sysctl after synchronized seek ... "
set_test
dd if = " ${ TEST_FILE } " of = " ${ TARGET } " bs = 1 seek = 1 skip = 1 2>/dev/null
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Writing beyond end of sysctl ... "
set_orig
dd if = " ${ TEST_FILE } " of = " ${ TARGET } " bs = 20 seek = 2 2>/dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Writing sysctl with multiple long writes ... "
set_orig
( perl -e 'print "A" x 50;' ; echo " ${ TEST_STR } " ) | \
dd of = " ${ TARGET } " bs = 50 2>/dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
2017-07-12 14:33:49 -07:00
test_rc
}
2019-03-11 23:27:58 -07:00
check_failure( )
{
echo -n " Testing that $1 fails as expected... "
reset_vals
TEST_STR = " $1 "
orig = " $( cat $TARGET ) "
echo -n " $TEST_STR " > $TARGET 2> /dev/null
# write should fail and $TARGET should retain its original value
if [ $? = 0 ] || [ " $( cat $TARGET ) " != " $orig " ] ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
}
run_wideint_tests( )
{
# sysctl conversion functions receive a boolean sign and ulong
# magnitude; here we list the magnitudes we want to test (each of
# which will be tested in both positive and negative forms). Since
# none of these values fit in 32 bits, writing them to an int- or
# uint-typed sysctl should fail.
local magnitudes = (
# common boundary-condition values (zero, +1, -1, INT_MIN,
# and INT_MAX respectively) if truncated to lower 32 bits
# (potential for being falsely deemed in range)
0x0000000100000000
0x0000000100000001
0x00000001ffffffff
0x0000000180000000
0x000000017fffffff
# these look like negatives, but without a leading '-' are
# actually large positives (should be rejected as above
# despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32)
0xffffffff00000000
0xffffffff00000001
0xffffffffffffffff
0xffffffff80000000
0xffffffff7fffffff
)
for sign in '' '-' ; do
for mag in " ${ magnitudes [@] } " ; do
check_failure " ${ sign } ${ mag } "
done
done
}
2017-07-12 14:33:49 -07:00
# Your test must accept digits 3 and 4 to use this
run_limit_digit( )
{
echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ..."
reset_vals
2017-07-12 14:33:46 -07:00
2017-07-12 14:33:49 -07:00
LIMIT = $(( MAX_DIGITS - 1 ))
TEST_STR = "3"
( perl -e 'print " " x ' $LIMIT ';' ; echo " ${ TEST_STR } " ) | \
dd of = " ${ TARGET } " 2>/dev/null
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Checking passing PAGE_SIZE of spaces fails on write ..."
reset_vals
LIMIT = $(( MAX_DIGITS))
TEST_STR = "4"
( perl -e 'print " " x ' $LIMIT ';' ; echo " ${ TEST_STR } " ) | \
dd of = " ${ TARGET } " 2>/dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
2017-07-12 14:33:46 -07:00
test_rc
}
2017-07-12 14:33:52 -07:00
# You are using an int
run_limit_digit_int( )
{
echo -n "Testing INT_MAX works ..."
reset_vals
TEST_STR = " $INT_MAX "
echo -n $TEST_STR > $TARGET
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing INT_MAX + 1 will fail as expected..."
reset_vals
let TEST_STR = $INT_MAX +1
echo -n $TEST_STR > $TARGET 2> /dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing negative values will work as expected..."
reset_vals
TEST_STR = "-3"
echo -n $TEST_STR > $TARGET 2> /dev/null
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
}
2017-07-12 14:33:58 -07:00
# You used an int array
run_limit_digit_int_array( )
{
echo -n "Testing array works as expected ... "
TEST_STR = "4 3 2 1"
echo -n $TEST_STR > $TARGET
if ! verify_diff_w " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing skipping trailing array elements works ... "
# Do not reset_vals, carry on the values from the last test.
# If we only echo in two digits the last two are left intact
TEST_STR = "100 101"
echo -n $TEST_STR > $TARGET
# After we echo in, to help diff we need to set on TEST_STR what
# we expect the result to be.
TEST_STR = "100 101 2 1"
if ! verify_diff_w " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing PAGE_SIZE limit on array works ... "
# Do not reset_vals, carry on the values from the last test.
# Even if you use an int array, you are still restricted to
# MAX_DIGITS, this is a known limitation. Test limit works.
LIMIT = $(( MAX_DIGITS - 1 ))
TEST_STR = "9"
( perl -e 'print " " x ' $LIMIT ';' ; echo " ${ TEST_STR } " ) | \
dd of = " ${ TARGET } " 2>/dev/null
TEST_STR = "9 101 2 1"
if ! verify_diff_w " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "
# Do not reset_vals, carry on the values from the last test.
# Now go over limit.
LIMIT = $(( MAX_DIGITS))
TEST_STR = "7"
( perl -e 'print " " x ' $LIMIT ';' ; echo " ${ TEST_STR } " ) | \
dd of = " ${ TARGET } " 2>/dev/null
TEST_STR = "7 101 2 1"
if verify_diff_w " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
}
2017-07-12 14:33:55 -07:00
# You are using an unsigned int
run_limit_digit_uint( )
{
echo -n "Testing UINT_MAX works ..."
reset_vals
TEST_STR = " $UINT_MAX "
echo -n $TEST_STR > $TARGET
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing UINT_MAX + 1 will fail as expected..."
reset_vals
TEST_STR = $(( $UINT_MAX + 1 ))
echo -n $TEST_STR > $TARGET 2> /dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
echo -n "Testing negative values will not work as expected ..."
reset_vals
TEST_STR = "-3"
echo -n $TEST_STR > $TARGET 2> /dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
}
2017-07-12 14:33:46 -07:00
run_stringtests( )
{
echo -n "Writing entire sysctl in short writes ... "
set_orig
dd if = " ${ TEST_FILE } " of = " ${ TARGET } " bs = 1 2>/dev/null
if ! verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Writing middle of sysctl after unsynchronized seek ... "
set_test
dd if = " ${ TEST_FILE } " of = " ${ TARGET } " bs = 1 seek = 1 2>/dev/null
if verify " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n " Checking sysctl maxlen is at least $MAXLEN ... "
set_orig
perl -e 'print "A" x (' " ${ MAXLEN } " '-2), "B";' | \
dd of = " ${ TARGET } " bs = " ${ MAXLEN } " 2>/dev/null
if ! grep -q B " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Checking sysctl keeps original string on overflow append ... "
set_orig
perl -e 'print "A" x (' " ${ MAXLEN } " '-1), "B";' | \
dd of = " ${ TARGET } " bs = $(( MAXLEN - 1 )) 2>/dev/null
if grep -q B " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Checking sysctl stays NULL terminated on write ... "
set_orig
perl -e 'print "A" x (' " ${ MAXLEN } " '-1), "B";' | \
dd of = " ${ TARGET } " bs = " ${ MAXLEN } " 2>/dev/null
if grep -q B " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
echo -n "Checking sysctl stays NULL terminated on overwrite ... "
set_orig
perl -e 'print "A" x (' " ${ MAXLEN } " '-1), "BB";' | \
dd of = " ${ TARGET } " bs = $(( $MAXLEN + 1 )) 2>/dev/null
if grep -q B " ${ TARGET } " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
fi
test_rc
}
2019-05-14 15:45:07 -07:00
target_exists( )
{
TARGET = " ${ SYSCTL } / $1 "
TEST_ID = " $2 "
if [ ! -f ${ TARGET } ] ; then
echo " Target for test $TEST_ID : $TARGET not exist, skipping test ... "
return 0
fi
return 1
}
2019-05-14 15:45:10 -07:00
run_bitmaptest( ) {
# Total length of bitmaps string to use, a bit under
# the maximum input size of the test node
LENGTH = $(( RANDOM % 65000 ))
# First bit to set
BIT = $(( RANDOM % 1024 ))
# String containing our list of bits to set
TEST_STR = $BIT
# build up the string
while [ " ${# TEST_STR } " -le " $LENGTH " ] ; do
# Make sure next entry is discontiguous,
# skip ahead at least 2
BIT = $(( BIT + $(( 2 + RANDOM % 10 )) ))
# Add new bit to the list
TEST_STR = " ${ TEST_STR } , ${ BIT } "
# Randomly make it a range
if [ " $(( RANDOM % 2 )) " -eq "1" ] ; then
RANGE_END = $(( BIT + $(( 1 + RANDOM % 10 )) ))
TEST_STR = " ${ TEST_STR } - ${ RANGE_END } "
BIT = $RANGE_END
fi
done
echo -n "Checking bitmap handler... "
TEST_FILE = $( mktemp)
echo -n " $TEST_STR " > $TEST_FILE
cat $TEST_FILE > $TARGET 2> /dev/null
if [ $? -ne 0 ] ; then
echo "FAIL" >& 2
rc = 1
test_rc
fi
if ! verify_diff_proc_file " $TARGET " " $TEST_FILE " ; then
echo "FAIL" >& 2
rc = 1
else
echo "ok"
rc = 0
fi
test_rc
}
2017-07-12 14:33:46 -07:00
sysctl_test_0001( )
{
2019-05-14 15:45:07 -07:00
TARGET = " ${ SYSCTL } / $( get_test_target 0001) "
2017-07-12 14:33:49 -07:00
reset_vals
2017-07-12 14:33:46 -07:00
ORIG = $( cat " ${ TARGET } " )
TEST_STR = $(( $ORIG + 1 ))
run_numerictests
2019-03-11 23:27:58 -07:00
run_wideint_tests
2017-07-12 14:33:49 -07:00
run_limit_digit
2017-07-12 14:33:46 -07:00
}
sysctl_test_0002( )
{
2019-05-14 15:45:07 -07:00
TARGET = " ${ SYSCTL } / $( get_test_target 0002) "
2017-07-12 14:33:49 -07:00
reset_vals
2017-07-12 14:33:46 -07:00
ORIG = $( cat " ${ TARGET } " )
TEST_STR = "Testing sysctl"
# Only string sysctls support seeking/appending.
MAXLEN = 65
run_numerictests
run_stringtests
}
2017-07-12 14:33:52 -07:00
sysctl_test_0003( )
{
2019-05-14 15:45:07 -07:00
TARGET = " ${ SYSCTL } / $( get_test_target 0003) "
2017-07-12 14:33:52 -07:00
reset_vals
ORIG = $( cat " ${ TARGET } " )
TEST_STR = $(( $ORIG + 1 ))
run_numerictests
2019-03-11 23:27:58 -07:00
run_wideint_tests
2017-07-12 14:33:52 -07:00
run_limit_digit
run_limit_digit_int
}
2017-07-12 14:33:55 -07:00
sysctl_test_0004( )
{
2019-05-14 15:45:07 -07:00
TARGET = " ${ SYSCTL } / $( get_test_target 0004) "
2017-07-12 14:33:55 -07:00
reset_vals
ORIG = $( cat " ${ TARGET } " )
TEST_STR = $(( $ORIG + 1 ))
run_numerictests
2019-03-11 23:27:58 -07:00
run_wideint_tests
2017-07-12 14:33:55 -07:00
run_limit_digit
run_limit_digit_uint
}
2017-07-12 14:33:58 -07:00
sysctl_test_0005( )
{
2019-05-14 15:45:07 -07:00
TARGET = " ${ SYSCTL } / $( get_test_target 0005) "
2017-07-12 14:33:58 -07:00
reset_vals
ORIG = $( cat " ${ TARGET } " )
run_limit_digit_int_array
}
2019-05-14 15:45:10 -07:00
sysctl_test_0006( )
{
TARGET = " ${ SYSCTL } /bitmap_0001 "
reset_vals
ORIG = ""
run_bitmaptest
}
2020-06-07 21:40:38 -07:00
sysctl_test_0007( )
{
TARGET = " ${ SYSCTL } /boot_int "
if [ ! -f $TARGET ] ; then
echo " Skipping test for $TARGET as it is not present ... "
return $ksft_skip
fi
if [ -d $DIR ] ; then
echo "Boot param test only possible sysctl_test is built-in, not module:"
cat $TEST_DIR /config >& 2
return $ksft_skip
fi
echo -n " Testing if $TARGET is set to 1 ... "
ORIG = $( cat " ${ TARGET } " )
if [ x$ORIG = "x1" ] ; then
echo "ok"
return 0
fi
echo "FAIL"
echo "Checking if /proc/cmdline contains setting of the expected parameter ..."
if [ ! -f /proc/cmdline ] ; then
echo "/proc/cmdline does not exist, test inconclusive"
return 0
fi
FOUND = $( grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline)
if [ $FOUND = "1" ] ; then
echo " Kernel param found but $TARGET is not 1, TEST FAILED "
rc = 1
test_rc
fi
echo "Skipping test, expected kernel parameter missing."
echo "To perform this test, make sure kernel is booted with parameter: sysctl.debug.test_sysctl.boot_int=1"
return $ksft_skip
}
2022-05-01 11:55:24 +08:00
sysctl_test_0008( )
{
TARGET = " ${ SYSCTL } /match_int "
if [ ! -f $TARGET ] ; then
echo " Skipping test for $TARGET as it is not present ... "
return $ksft_skip
fi
echo -n " Testing if $TARGET is matched in kernel "
ORIG_VALUE = $( cat " ${ TARGET } " )
if [ $ORIG_VALUE -ne 1 ] ; then
echo "TEST FAILED"
rc = 1
test_rc
fi
echo "ok"
return 0
}
2017-07-12 14:33:46 -07:00
list_tests( )
{
echo "Test ID list:"
echo
echo "TEST_ID x NUM_TEST"
echo "TEST_ID: Test ID"
echo "NUM_TESTS: Number of recommended times to run the test"
echo
echo " 0001 x $( get_test_count 0001) - tests proc_dointvec_minmax() "
echo " 0002 x $( get_test_count 0002) - tests proc_dostring() "
2017-07-12 14:33:52 -07:00
echo " 0003 x $( get_test_count 0003) - tests proc_dointvec() "
2017-07-12 14:33:55 -07:00
echo " 0004 x $( get_test_count 0004) - tests proc_douintvec() "
2017-07-12 14:33:58 -07:00
echo " 0005 x $( get_test_count 0005) - tests proc_douintvec() array "
2019-05-14 15:45:10 -07:00
echo " 0006 x $( get_test_count 0006) - tests proc_do_large_bitmap() "
2020-06-07 21:40:38 -07:00
echo " 0007 x $( get_test_count 0007) - tests setting sysctl from kernel boot param "
2022-05-01 11:55:24 +08:00
echo " 0008 x $( get_test_count 0008) - tests sysctl macro values match "
2017-07-12 14:33:46 -07:00
}
usage( )
{
NUM_TESTS = $( grep -o ' ' <<< " $ALL_TESTS " | grep -c .)
let NUM_TESTS = $NUM_TESTS +1
MAX_TEST = $( printf "%04d\n" $NUM_TESTS )
echo " Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] | "
echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
echo " [ all ] [ -h | --help ] [ -l ]"
echo ""
echo " Valid tests: 0001- $MAX_TEST "
echo ""
echo " all Runs all tests (default)"
echo " -t Run test ID the number amount of times is recommended"
echo " -w Watch test ID run until it runs into an error"
echo " -c Run test ID once"
echo " -s Run test ID x test-count number of times"
echo " -l List all test ID list"
echo " -h|--help Help"
echo
echo "If an error every occurs execution will immediately terminate."
echo "If you are adding a new test try using -w <test-ID> first to"
echo "make sure the test passes a series of tests."
echo
echo Example uses:
echo
echo " $TEST_NAME .sh -- executes all tests "
echo " $TEST_NAME .sh -t 0002 -- Executes test ID 0002 number of times is recomended "
echo " $TEST_NAME .sh -w 0002 -- Watch test ID 0002 run until an error occurs "
echo " $TEST_NAME .sh -s 0002 -- Run test ID 0002 once "
echo " $TEST_NAME .sh -c 0002 3 -- Run test ID 0002 three times "
echo
list_tests
exit 1
}
function test_num( )
{
re = '^[0-9]+$'
if ! [ [ $1 = ~ $re ] ] ; then
usage
fi
}
function get_test_count( )
{
test_num $1
TEST_DATA = $( echo $ALL_TESTS | awk '{print $' $1 '}' )
2019-05-14 15:45:07 -07:00
echo ${ TEST_DATA } | awk -F":" '{print $2}'
2017-07-12 14:33:46 -07:00
}
function get_test_enabled( )
{
test_num $1
TEST_DATA = $( echo $ALL_TESTS | awk '{print $' $1 '}' )
2019-05-14 15:45:07 -07:00
echo ${ TEST_DATA } | awk -F":" '{print $3}'
}
function get_test_target( )
{
test_num $1
TEST_DATA = $( echo $ALL_TESTS | awk '{print $' $1 '}' )
echo ${ TEST_DATA } | awk -F":" '{print $4}'
2017-07-12 14:33:46 -07:00
}
function run_all_tests( )
{
for i in $ALL_TESTS ; do
2019-05-14 15:45:07 -07:00
TEST_ID = ${ i % : * : * : * }
2017-07-12 14:33:46 -07:00
ENABLED = $( get_test_enabled $TEST_ID )
TEST_COUNT = $( get_test_count $TEST_ID )
2019-05-14 15:45:07 -07:00
TEST_TARGET = $( get_test_target $TEST_ID )
2019-05-14 15:45:10 -07:00
if target_exists $TEST_TARGET $TEST_ID ; then
2019-05-14 15:45:07 -07:00
continue
fi
2017-07-12 14:33:46 -07:00
if [ [ $ENABLED -eq "1" ] ] ; then
2019-05-14 15:45:07 -07:00
test_case $TEST_ID $TEST_COUNT $TEST_TARGET
2017-07-12 14:33:46 -07:00
fi
done
}
function watch_log( )
{
if [ $# -ne 3 ] ; then
clear
fi
date
echo " Running test: $2 - run # $1 "
}
function watch_case( )
{
i = 0
while [ 1 ] ; do
if [ $# -eq 1 ] ; then
test_num $1
watch_log $i ${ TEST_NAME } _test_$1
${ TEST_NAME } _test_$1
else
watch_log $i all
run_all_tests
fi
let i = $i +1
done
}
function test_case( )
{
2019-05-14 15:45:07 -07:00
NUM_TESTS = $2
2017-07-12 14:33:46 -07:00
i = 0
2019-05-14 15:45:07 -07:00
if target_exists $3 $1 ; then
continue
fi
2017-07-12 14:33:46 -07:00
while [ $i -lt $NUM_TESTS ] ; do
test_num $1
watch_log $i ${ TEST_NAME } _test_$1 noclear
RUN_TEST = ${ TEST_NAME } _test_$1
$RUN_TEST
let i = $i +1
done
}
function parse_args( )
{
if [ $# -eq 0 ] ; then
run_all_tests
else
if [ [ " $1 " = "all" ] ] ; then
run_all_tests
elif [ [ " $1 " = "-w" ] ] ; then
shift
watch_case $@
elif [ [ " $1 " = "-t" ] ] ; then
shift
test_num $1
2019-05-14 15:45:07 -07:00
test_case $1 $( get_test_count $1 ) $( get_test_target $1 )
2017-07-12 14:33:46 -07:00
elif [ [ " $1 " = "-c" ] ] ; then
shift
test_num $1
test_num $2
2019-05-14 15:45:07 -07:00
test_case $1 $2 $( get_test_target $1 )
2017-07-12 14:33:46 -07:00
elif [ [ " $1 " = "-s" ] ] ; then
shift
2019-05-14 15:45:07 -07:00
test_case $1 1 $( get_test_target $1 )
2017-07-12 14:33:46 -07:00
elif [ [ " $1 " = "-l" ] ] ; then
list_tests
elif [ [ " $1 " = "-h" || " $1 " = "--help" ] ] ; then
usage
else
usage
fi
fi
}
test_reqs
allow_user_defaults
check_production_sysctl_writes_strict
load_req_mod
trap "test_finish" EXIT
parse_args $@
exit 0