1070 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.13# Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>4 5# This performs a series tests against the proc sysctl interface.6 7# Kselftest framework requirement - SKIP code is 4.8ksft_skip=49 10TEST_NAME="sysctl"11TEST_DRIVER="test_${TEST_NAME}"12TEST_DIR=$(dirname $0)13TEST_FILE=$(mktemp)14 15# This represents16#17# TEST_ID:TEST_COUNT:ENABLED:TARGET:SKIP_NO_TARGET18#19# TEST_ID: is the test id number20# TEST_COUNT: number of times we should run the test21# ENABLED: 1 if enabled, 0 otherwise22# TARGET: test target file required on the test_sysctl module23# SKIP_NO_TARGET: 1 skip if TARGET not there24# 0 run eventhough TARGET not there25#26# Once these are enabled please leave them as-is. Write your own test,27# we have tons of space.28ALL_TESTS="0001:1:1:int_0001:1"29ALL_TESTS="$ALL_TESTS 0002:1:1:string_0001:1"30ALL_TESTS="$ALL_TESTS 0003:1:1:int_0002:1"31ALL_TESTS="$ALL_TESTS 0004:1:1:uint_0001:1"32ALL_TESTS="$ALL_TESTS 0005:3:1:int_0003:1"33ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001:1"34ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int:1"35ALL_TESTS="$ALL_TESTS 0008:1:1:match_int:1"36ALL_TESTS="$ALL_TESTS 0009:1:1:unregister_error:0"37ALL_TESTS="$ALL_TESTS 0010:1:1:mnt/mnt_error:0"38ALL_TESTS="$ALL_TESTS 0011:1:1:empty_add:0"39 40function allow_user_defaults()41{42 if [ -z $DIR ]; then43 DIR="/sys/module/test_sysctl/"44 fi45 if [ -z $DEFAULT_NUM_TESTS ]; then46 DEFAULT_NUM_TESTS=5047 fi48 if [ -z $SYSCTL ]; then49 SYSCTL="/proc/sys/debug/test_sysctl"50 fi51 if [ -z $PROD_SYSCTL ]; then52 PROD_SYSCTL="/proc/sys"53 fi54 if [ -z $WRITES_STRICT ]; then55 WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict"56 fi57}58 59function check_production_sysctl_writes_strict()60{61 echo -n "Checking production write strict setting ... "62 if [ ! -e ${WRITES_STRICT} ]; then63 echo "FAIL, but skip in case of old kernel" >&264 else65 old_strict=$(cat ${WRITES_STRICT})66 if [ "$old_strict" = "1" ]; then67 echo "OK"68 else69 echo "FAIL, strict value is 0 but force to 1 to continue" >&270 echo "1" > ${WRITES_STRICT}71 fi72 fi73 74 if [ -z $PAGE_SIZE ]; then75 PAGE_SIZE=$(getconf PAGESIZE)76 fi77 if [ -z $MAX_DIGITS ]; then78 MAX_DIGITS=$(($PAGE_SIZE/8))79 fi80 if [ -z $INT_MAX ]; then81 INT_MAX=$(getconf INT_MAX)82 fi83 if [ -z $UINT_MAX ]; then84 UINT_MAX=$(getconf UINT_MAX)85 fi86}87 88test_reqs()89{90 uid=$(id -u)91 if [ $uid -ne 0 ]; then92 echo $msg must be run as root >&293 exit $ksft_skip94 fi95 96 if ! which perl 2> /dev/null > /dev/null; then97 echo "$0: You need perl installed"98 exit $ksft_skip99 fi100 if ! which getconf 2> /dev/null > /dev/null; then101 echo "$0: You need getconf installed"102 exit $ksft_skip103 fi104 if ! which diff 2> /dev/null > /dev/null; then105 echo "$0: You need diff installed"106 exit $ksft_skip107 fi108}109 110function load_req_mod()111{112 if [ ! -d $SYSCTL ]; then113 if ! modprobe -q -n $TEST_DRIVER; then114 echo "$0: module $TEST_DRIVER not found [SKIP]"115 echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2116 exit $ksft_skip117 fi118 modprobe $TEST_DRIVER119 if [ $? -ne 0 ]; then120 echo "$0: modprobe $TEST_DRIVER failed."121 exit122 fi123 fi124}125 126reset_vals()127{128 VAL=""129 TRIGGER=$(basename ${TARGET})130 case "$TRIGGER" in131 int_0001)132 VAL="60"133 ;;134 int_0002)135 VAL="1"136 ;;137 uint_0001)138 VAL="314"139 ;;140 string_0001)141 VAL="(none)"142 ;;143 bitmap_0001)144 VAL=""145 ;;146 *)147 ;;148 esac149 echo -n $VAL > $TARGET150}151 152set_orig()153{154 if [ ! -z $TARGET ] && [ ! -z $ORIG ]; then155 if [ -f ${TARGET} ]; then156 echo "${ORIG}" > "${TARGET}"157 fi158 fi159}160 161set_test()162{163 echo "${TEST_STR}" > "${TARGET}"164}165 166verify()167{168 local seen169 seen=$(cat "$1")170 if [ "${seen}" != "${TEST_STR}" ]; then171 return 1172 fi173 return 0174}175 176# proc files get read a page at a time, which can confuse diff,177# and get you incorrect results on proc files with long data. To use178# diff against them you must first extract the output to a file, and179# then compare against that file.180verify_diff_proc_file()181{182 TMP_DUMP_FILE=$(mktemp)183 cat $1 > $TMP_DUMP_FILE184 185 if ! diff -w -q $TMP_DUMP_FILE $2; then186 return 1187 else188 return 0189 fi190}191 192verify_diff_w()193{194 echo "$TEST_STR" | diff -q -w -u - $1 > /dev/null195 return $?196}197 198test_rc()199{200 if [[ $rc != 0 ]]; then201 echo "Failed test, return value: $rc" >&2202 exit $rc203 fi204}205 206test_finish()207{208 set_orig209 rm -f "${TEST_FILE}"210 211 if [ ! -z ${old_strict} ]; then212 echo ${old_strict} > ${WRITES_STRICT}213 fi214 exit $rc215}216 217run_numerictests()218{219 echo "== Testing sysctl behavior against ${TARGET} =="220 221 rc=0222 223 echo -n "Writing test file ... "224 echo "${TEST_STR}" > "${TEST_FILE}"225 if ! verify "${TEST_FILE}"; then226 echo "FAIL" >&2227 exit 1228 else229 echo "OK"230 fi231 232 echo -n "Checking sysctl is not set to test value ... "233 if verify "${TARGET}"; then234 echo "FAIL" >&2235 exit 1236 else237 echo "OK"238 fi239 240 echo -n "Writing sysctl from shell ... "241 set_test242 if ! verify "${TARGET}"; then243 echo "FAIL" >&2244 exit 1245 else246 echo "OK"247 fi248 249 echo -n "Resetting sysctl to original value ... "250 set_orig251 if verify "${TARGET}"; then252 echo "FAIL" >&2253 exit 1254 else255 echo "OK"256 fi257 258 # Now that we've validated the sanity of "set_test" and "set_orig",259 # we can use those functions to set starting states before running260 # specific behavioral tests.261 262 echo -n "Writing entire sysctl in single write ... "263 set_orig264 dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null265 if ! verify "${TARGET}"; then266 echo "FAIL" >&2267 rc=1268 else269 echo "OK"270 fi271 272 echo -n "Writing middle of sysctl after synchronized seek ... "273 set_test274 dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null275 if ! verify "${TARGET}"; then276 echo "FAIL" >&2277 rc=1278 else279 echo "OK"280 fi281 282 echo -n "Writing beyond end of sysctl ... "283 set_orig284 dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null285 if verify "${TARGET}"; then286 echo "FAIL" >&2287 rc=1288 else289 echo "OK"290 fi291 292 echo -n "Writing sysctl with multiple long writes ... "293 set_orig294 (perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \295 dd of="${TARGET}" bs=50 2>/dev/null296 if verify "${TARGET}"; then297 echo "FAIL" >&2298 rc=1299 else300 echo "OK"301 fi302 test_rc303}304 305check_failure()306{307 echo -n "Testing that $1 fails as expected ... "308 reset_vals309 TEST_STR="$1"310 orig="$(cat $TARGET)"311 echo -n "$TEST_STR" > $TARGET 2> /dev/null312 313 # write should fail and $TARGET should retain its original value314 if [ $? = 0 ] || [ "$(cat $TARGET)" != "$orig" ]; then315 echo "FAIL" >&2316 rc=1317 else318 echo "OK"319 fi320 test_rc321}322 323run_wideint_tests()324{325 # sysctl conversion functions receive a boolean sign and ulong326 # magnitude; here we list the magnitudes we want to test (each of327 # which will be tested in both positive and negative forms). Since328 # none of these values fit in 32 bits, writing them to an int- or329 # uint-typed sysctl should fail.330 local magnitudes=(331 # common boundary-condition values (zero, +1, -1, INT_MIN,332 # and INT_MAX respectively) if truncated to lower 32 bits333 # (potential for being falsely deemed in range)334 0x0000000100000000335 0x0000000100000001336 0x00000001ffffffff337 0x0000000180000000338 0x000000017fffffff339 340 # these look like negatives, but without a leading '-' are341 # actually large positives (should be rejected as above342 # despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32)343 0xffffffff00000000344 0xffffffff00000001345 0xffffffffffffffff346 0xffffffff80000000347 0xffffffff7fffffff348 )349 350 for sign in '' '-'; do351 for mag in "${magnitudes[@]}"; do352 check_failure "${sign}${mag}"353 done354 done355}356 357# Your test must accept digits 3 and 4 to use this358run_limit_digit()359{360 echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ... "361 reset_vals362 363 LIMIT=$((MAX_DIGITS -1))364 TEST_STR="3"365 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \366 dd of="${TARGET}" 2>/dev/null367 368 if ! verify "${TARGET}"; then369 echo "FAIL" >&2370 rc=1371 else372 echo "OK"373 fi374 test_rc375 376 echo -n "Checking passing PAGE_SIZE of spaces fails on write ... "377 reset_vals378 379 LIMIT=$((MAX_DIGITS))380 TEST_STR="4"381 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \382 dd of="${TARGET}" 2>/dev/null383 384 if verify "${TARGET}"; then385 echo "FAIL" >&2386 rc=1387 else388 echo "OK"389 fi390 test_rc391}392 393# You are using an int394run_limit_digit_int()395{396 echo -n "Testing INT_MAX works ... "397 reset_vals398 TEST_STR="$INT_MAX"399 echo -n $TEST_STR > $TARGET400 401 if ! verify "${TARGET}"; then402 echo "FAIL" >&2403 rc=1404 else405 echo "OK"406 fi407 test_rc408 409 echo -n "Testing INT_MAX + 1 will fail as expected ... "410 reset_vals411 let TEST_STR=$INT_MAX+1412 echo -n $TEST_STR > $TARGET 2> /dev/null413 414 if verify "${TARGET}"; then415 echo "FAIL" >&2416 rc=1417 else418 echo "OK"419 fi420 test_rc421 422 echo -n "Testing negative values will work as expected ... "423 reset_vals424 TEST_STR="-3"425 echo -n $TEST_STR > $TARGET 2> /dev/null426 if ! verify "${TARGET}"; then427 echo "FAIL" >&2428 rc=1429 else430 echo "OK"431 fi432 test_rc433}434 435# You used an int array436run_limit_digit_int_array()437{438 echo -n "Testing array works as expected ... "439 TEST_STR="4 3 2 1"440 echo -n $TEST_STR > $TARGET441 442 if ! verify_diff_w "${TARGET}"; then443 echo "FAIL" >&2444 rc=1445 else446 echo "OK"447 fi448 test_rc449 450 echo -n "Testing skipping trailing array elements works ... "451 # Do not reset_vals, carry on the values from the last test.452 # If we only echo in two digits the last two are left intact453 TEST_STR="100 101"454 echo -n $TEST_STR > $TARGET455 # After we echo in, to help diff we need to set on TEST_STR what456 # we expect the result to be.457 TEST_STR="100 101 2 1"458 459 if ! verify_diff_w "${TARGET}"; then460 echo "FAIL" >&2461 rc=1462 else463 echo "OK"464 fi465 test_rc466 467 echo -n "Testing PAGE_SIZE limit on array works ... "468 # Do not reset_vals, carry on the values from the last test.469 # Even if you use an int array, you are still restricted to470 # MAX_DIGITS, this is a known limitation. Test limit works.471 LIMIT=$((MAX_DIGITS -1))472 TEST_STR="9"473 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \474 dd of="${TARGET}" 2>/dev/null475 476 TEST_STR="9 101 2 1"477 if ! verify_diff_w "${TARGET}"; then478 echo "FAIL" >&2479 rc=1480 else481 echo "OK"482 fi483 test_rc484 485 echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "486 # Do not reset_vals, carry on the values from the last test.487 # Now go over limit.488 LIMIT=$((MAX_DIGITS))489 TEST_STR="7"490 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \491 dd of="${TARGET}" 2>/dev/null492 493 TEST_STR="7 101 2 1"494 if verify_diff_w "${TARGET}"; then495 echo "FAIL" >&2496 rc=1497 else498 echo "OK"499 fi500 test_rc501}502 503# You are using an unsigned int504run_limit_digit_uint()505{506 echo -n "Testing UINT_MAX works ... "507 reset_vals508 TEST_STR="$UINT_MAX"509 echo -n $TEST_STR > $TARGET510 511 if ! verify "${TARGET}"; then512 echo "FAIL" >&2513 rc=1514 else515 echo "OK"516 fi517 test_rc518 519 echo -n "Testing UINT_MAX + 1 will fail as expected ... "520 reset_vals521 TEST_STR=$(($UINT_MAX+1))522 echo -n $TEST_STR > $TARGET 2> /dev/null523 524 if verify "${TARGET}"; then525 echo "FAIL" >&2526 rc=1527 else528 echo "OK"529 fi530 test_rc531 532 echo -n "Testing negative values will not work as expected ... "533 reset_vals534 TEST_STR="-3"535 echo -n $TEST_STR > $TARGET 2> /dev/null536 537 if verify "${TARGET}"; then538 echo "FAIL" >&2539 rc=1540 else541 echo "OK"542 fi543 test_rc544}545 546run_stringtests()547{548 echo -n "Writing entire sysctl in short writes ... "549 set_orig550 dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null551 if ! verify "${TARGET}"; then552 echo "FAIL" >&2553 rc=1554 else555 echo "OK"556 fi557 558 echo -n "Writing middle of sysctl after unsynchronized seek ... "559 set_test560 dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null561 if verify "${TARGET}"; then562 echo "FAIL" >&2563 rc=1564 else565 echo "OK"566 fi567 568 echo -n "Checking sysctl maxlen is at least $MAXLEN ... "569 set_orig570 perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \571 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null572 if ! grep -q B "${TARGET}"; then573 echo "FAIL" >&2574 rc=1575 else576 echo "OK"577 fi578 579 echo -n "Checking sysctl keeps original string on overflow append ... "580 set_orig581 perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \582 dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null583 if grep -q B "${TARGET}"; then584 echo "FAIL" >&2585 rc=1586 else587 echo "OK"588 fi589 590 echo -n "Checking sysctl stays NULL terminated on write ... "591 set_orig592 perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \593 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null594 if grep -q B "${TARGET}"; then595 echo "FAIL" >&2596 rc=1597 else598 echo "OK"599 fi600 601 echo -n "Checking sysctl stays NULL terminated on overwrite ... "602 set_orig603 perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \604 dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null605 if grep -q B "${TARGET}"; then606 echo "FAIL" >&2607 rc=1608 else609 echo "OK"610 fi611 612 test_rc613}614 615target_exists()616{617 TARGET="${SYSCTL}/$1"618 TEST_ID="$2"619 620 if [ ! -f ${TARGET} ] ; then621 return 0622 fi623 return 1624}625 626run_bitmaptest() {627 # Total length of bitmaps string to use, a bit under628 # the maximum input size of the test node629 LENGTH=$((RANDOM % 65000))630 631 # First bit to set632 BIT=$((RANDOM % 1024))633 634 # String containing our list of bits to set635 TEST_STR=$BIT636 637 # build up the string638 while [ "${#TEST_STR}" -le "$LENGTH" ]; do639 # Make sure next entry is discontiguous,640 # skip ahead at least 2641 BIT=$((BIT + $((2 + RANDOM % 10))))642 643 # Add new bit to the list644 TEST_STR="${TEST_STR},${BIT}"645 646 # Randomly make it a range647 if [ "$((RANDOM % 2))" -eq "1" ]; then648 RANGE_END=$((BIT + $((1 + RANDOM % 10))))649 TEST_STR="${TEST_STR}-${RANGE_END}"650 BIT=$RANGE_END651 fi652 done653 654 echo -n "Checking bitmap handler ... "655 TEST_FILE=$(mktemp)656 echo -n "$TEST_STR" > $TEST_FILE657 658 cat $TEST_FILE > $TARGET 2> /dev/null659 if [ $? -ne 0 ]; then660 echo "FAIL" >&2661 rc=1662 test_rc663 fi664 665 if ! verify_diff_proc_file "$TARGET" "$TEST_FILE"; then666 echo "FAIL" >&2667 rc=1668 else669 echo "OK"670 rc=0671 fi672 test_rc673}674 675sysctl_test_0001()676{677 TARGET="${SYSCTL}/$(get_test_target 0001)"678 reset_vals679 ORIG=$(cat "${TARGET}")680 TEST_STR=$(( $ORIG + 1 ))681 682 run_numerictests683 run_wideint_tests684 run_limit_digit685}686 687sysctl_test_0002()688{689 TARGET="${SYSCTL}/$(get_test_target 0002)"690 reset_vals691 ORIG=$(cat "${TARGET}")692 TEST_STR="Testing sysctl"693 # Only string sysctls support seeking/appending.694 MAXLEN=65695 696 run_numerictests697 run_stringtests698}699 700sysctl_test_0003()701{702 TARGET="${SYSCTL}/$(get_test_target 0003)"703 reset_vals704 ORIG=$(cat "${TARGET}")705 TEST_STR=$(( $ORIG + 1 ))706 707 run_numerictests708 run_wideint_tests709 run_limit_digit710 run_limit_digit_int711}712 713sysctl_test_0004()714{715 TARGET="${SYSCTL}/$(get_test_target 0004)"716 reset_vals717 ORIG=$(cat "${TARGET}")718 TEST_STR=$(( $ORIG + 1 ))719 720 run_numerictests721 run_wideint_tests722 run_limit_digit723 run_limit_digit_uint724}725 726sysctl_test_0005()727{728 TARGET="${SYSCTL}/$(get_test_target 0005)"729 reset_vals730 ORIG=$(cat "${TARGET}")731 732 run_limit_digit_int_array733}734 735sysctl_test_0006()736{737 TARGET="${SYSCTL}/$(get_test_target 0006)"738 reset_vals739 ORIG=""740 run_bitmaptest741}742 743sysctl_test_0007()744{745 TARGET="${SYSCTL}/$(get_test_target 0007)"746 echo -n "Testing if $TARGET is set to 1 ... "747 748 if [ ! -f $TARGET ]; then749 echo -e "SKIPPING\n$TARGET is not present"750 return $ksft_skip751 fi752 753 if [ -d $DIR ]; then754 echo -e "SKIPPING\nTest only possible if sysctl_test is built-in, not module:"755 cat $TEST_DIR/config >&2756 return $ksft_skip757 fi758 759 ORIG=$(cat "${TARGET}")760 761 if [ x$ORIG = "x1" ]; then762 echo "OK"763 return 0764 fi765 766 if [ ! -f /proc/cmdline ]; then767 echo -e "SKIPPING\nThere is no /proc/cmdline to check for paramter"768 return $ksft_skip769 fi770 771 FOUND=$(grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline)772 if [ $FOUND = "1" ]; then773 echo -e "FAIL\nKernel param found but $TARGET is not 1." >&2774 rc=1775 test_rc776 fi777 778 echo -e "SKIPPING\nExpected kernel parameter missing."779 echo "Kernel must be booted with parameter: sysctl.debug.test_sysctl.boot_int=1"780 return $ksft_skip781}782 783sysctl_test_0008()784{785 TARGET="${SYSCTL}/$(get_test_target 0008)"786 echo -n "Testing if $TARGET is matched in kernel ... "787 788 if [ ! -f $TARGET ]; then789 echo -e "SKIPPING\n$TARGET is not present"790 return $ksft_skip791 fi792 793 ORIG_VALUE=$(cat "${TARGET}")794 795 if [ $ORIG_VALUE -ne 1 ]; then796 echo "FAIL" >&2797 rc=1798 test_rc799 fi800 801 echo "OK"802 return 0803}804 805sysctl_test_0009()806{807 TARGET="${SYSCTL}/$(get_test_target 0009)"808 echo -n "Testing if $TARGET unregistered correctly ... "809 if [ -d $TARGET ]; then810 echo "FAIL" >&2811 rc=1812 test_rc813 fi814 815 echo "OK"816 return 0817}818 819sysctl_test_0010()820{821 TARGET="${SYSCTL}/$(get_test_target 0010)"822 echo -n "Testing that $TARGET was not created ... "823 if [ -d $TARGET ]; then824 echo "FAIL" >&2825 rc=1826 test_rc827 fi828 829 echo "OK"830 return 0831}832 833sysctl_test_0011()834{835 TARGET="${SYSCTL}/$(get_test_target 0011)"836 echo -n "Testing empty dir handling in ${TARGET} ... "837 if [ ! -d ${TARGET} ]; then838 echo -e "FAIL\nCould not create ${TARGET}" >&2839 rc=1840 test_rc841 fi842 843 TARGET2="${TARGET}/empty"844 if [ ! -d ${TARGET2} ]; then845 echo -e "FAIL\nCould not create ${TARGET2}" >&2846 rc=1847 test_rc848 fi849 850 echo "OK"851 return 0852}853 854list_tests()855{856 echo "Test ID list:"857 echo858 echo "TEST_ID x NUM_TEST"859 echo "TEST_ID: Test ID"860 echo "NUM_TESTS: Number of recommended times to run the test"861 echo862 echo "0001 x $(get_test_count 0001) - tests proc_dointvec_minmax()"863 echo "0002 x $(get_test_count 0002) - tests proc_dostring()"864 echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"865 echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"866 echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"867 echo "0006 x $(get_test_count 0006) - tests proc_do_large_bitmap()"868 echo "0007 x $(get_test_count 0007) - tests setting sysctl from kernel boot param"869 echo "0008 x $(get_test_count 0008) - tests sysctl macro values match"870 echo "0009 x $(get_test_count 0009) - tests sysct unregister"871 echo "0010 x $(get_test_count 0010) - tests sysct mount point"872 echo "0011 x $(get_test_count 0011) - tests empty directories"873}874 875usage()876{877 NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)878 let NUM_TESTS=$NUM_TESTS+1879 MAX_TEST=$(printf "%04d\n" $NUM_TESTS)880 echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"881 echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"882 echo " [ all ] [ -h | --help ] [ -l ]"883 echo ""884 echo "Valid tests: 0001-$MAX_TEST"885 echo ""886 echo " all Runs all tests (default)"887 echo " -t Run test ID the number amount of times is recommended"888 echo " -w Watch test ID run until it runs into an error"889 echo " -c Run test ID once"890 echo " -s Run test ID x test-count number of times"891 echo " -l List all test ID list"892 echo " -h|--help Help"893 echo894 echo "If an error every occurs execution will immediately terminate."895 echo "If you are adding a new test try using -w <test-ID> first to"896 echo "make sure the test passes a series of tests."897 echo898 echo Example uses:899 echo900 echo "$TEST_NAME.sh -- executes all tests"901 echo "$TEST_NAME.sh -t 0002 -- Executes test ID 0002 number of times is recomended"902 echo "$TEST_NAME.sh -w 0002 -- Watch test ID 0002 run until an error occurs"903 echo "$TEST_NAME.sh -s 0002 -- Run test ID 0002 once"904 echo "$TEST_NAME.sh -c 0002 3 -- Run test ID 0002 three times"905 echo906 list_tests907 exit 1908}909 910function test_num()911{912 re='^[0-9]+$'913 if ! [[ $1 =~ $re ]]; then914 usage915 fi916}917function remove_leading_zeros()918{919 echo $1 | sed 's/^0*//'920}921 922function get_test_count()923{924 test_num $1925 awk_field=$(remove_leading_zeros $1)926 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')927 echo ${TEST_DATA} | awk -F":" '{print $2}'928}929 930function get_test_enabled()931{932 test_num $1933 awk_field=$(remove_leading_zeros $1)934 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')935 echo ${TEST_DATA} | awk -F":" '{print $3}'936}937 938function get_test_target()939{940 test_num $1941 awk_field=$(remove_leading_zeros $1)942 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')943 echo ${TEST_DATA} | awk -F":" '{print $4}'944}945 946function get_test_skip_no_target()947{948 test_num $1949 awk_field=$(remove_leading_zeros $1)950 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')951 echo ${TEST_DATA} | awk -F":" '{print $5}'952}953 954function skip_test()955{956 TEST_ID=$1957 TEST_TARGET=$2958 if target_exists $TEST_TARGET $TEST_ID; then959 TEST_SKIP=$(get_test_skip_no_target $TEST_ID)960 if [[ $TEST_SKIP -eq "1" ]]; then961 echo "Target $TEST_TARGET for test $TEST_ID does not exist ... SKIPPING"962 return 0963 fi964 fi965 return 1966}967 968function run_all_tests()969{970 for i in $ALL_TESTS ; do971 TEST_ID=${i%:*:*:*:*}972 ENABLED=$(get_test_enabled $TEST_ID)973 TEST_COUNT=$(get_test_count $TEST_ID)974 TEST_TARGET=$(get_test_target $TEST_ID)975 976 if [[ $ENABLED -eq "1" ]]; then977 test_case $TEST_ID $TEST_COUNT $TEST_TARGET978 fi979 done980}981 982function watch_log()983{984 if [ $# -ne 3 ]; then985 clear986 fi987 date988 echo "Running test: $2 - run #$1"989}990 991function watch_case()992{993 i=0994 while [ 1 ]; do995 996 if [ $# -eq 1 ]; then997 test_num $1998 watch_log $i ${TEST_NAME}_test_$1999 ${TEST_NAME}_test_$11000 else1001 watch_log $i all1002 run_all_tests1003 fi1004 let i=$i+11005 done1006}1007 1008function test_case()1009{1010 TEST_ID=$11011 NUM_TESTS=$21012 TARGET=$31013 1014 if skip_test $TEST_ID $TARGET; then1015 return1016 fi1017 1018 i=01019 while [ $i -lt $NUM_TESTS ]; do1020 test_num $TEST_ID1021 watch_log $i ${TEST_NAME}_test_${TEST_ID} noclear1022 RUN_TEST=${TEST_NAME}_test_${TEST_ID}1023 $RUN_TEST1024 let i=$i+11025 done1026}1027 1028function parse_args()1029{1030 if [ $# -eq 0 ]; then1031 run_all_tests1032 else1033 if [[ "$1" = "all" ]]; then1034 run_all_tests1035 elif [[ "$1" = "-w" ]]; then1036 shift1037 watch_case $@1038 elif [[ "$1" = "-t" ]]; then1039 shift1040 test_num $11041 test_case $1 $(get_test_count $1) $(get_test_target $1)1042 elif [[ "$1" = "-c" ]]; then1043 shift1044 test_num $11045 test_num $21046 test_case $1 $2 $(get_test_target $1)1047 elif [[ "$1" = "-s" ]]; then1048 shift1049 test_case $1 1 $(get_test_target $1)1050 elif [[ "$1" = "-l" ]]; then1051 list_tests1052 elif [[ "$1" = "-h" || "$1" = "--help" ]]; then1053 usage1054 else1055 usage1056 fi1057 fi1058}1059 1060test_reqs1061allow_user_defaults1062check_production_sysctl_writes_strict1063load_req_mod1064 1065trap "test_finish" EXIT1066 1067parse_args $@1068 1069exit 01070