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