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