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. 8 ksft_skip=4 9 10 TEST_NAME="sysctl" 11 TEST_DRIVER="test_${TEST_NAME}" 12 TEST_DIR=$(dirname $0) 13 TEST_FILE=$(mktemp) 14 15 # This represents 16 # 17 # TEST_ID:TEST_COUNT:ENABLED:TARGET:SKIP_NO_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 # SKIP_NO_TARGET: 1 skip if TARGET not there 24 # 0 run eventhough TARGET not there 25 # 26 # Once these are enabled please leave them as-is. Write your own test, 27 # we have tons of space. 28 ALL_TESTS="0001:1:1:int_0001:1" 29 ALL_TESTS="$ALL_TESTS 0002:1:1:string_0001:1" 30 ALL_TESTS="$ALL_TESTS 0003:1:1:int_0002:1" 31 ALL_TESTS="$ALL_TESTS 0004:1:1:uint_0001:1" 32 ALL_TESTS="$ALL_TESTS 0005:3:1:int_0003:1" 33 ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001:1" 34 ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int:1" 35 ALL_TESTS="$ALL_TESTS 0008:1:1:match_int:1" 36 ALL_TESTS="$ALL_TESTS 0009:1:1:unregister_error:0" 37 ALL_TESTS="$ALL_TESTS 0010:1:1:mnt/mnt_error:0" 38 ALL_TESTS="$ALL_TESTS 0011:1:1:empty_add:0" 39 40 function allow_user_defaults() 41 { 42 if [ -z $DIR ]; then 43 DIR="/sys/module/test_sysctl/" 44 fi 45 if [ -z $DEFAULT_NUM_TESTS ]; then 46 DEFAULT_NUM_TESTS=50 47 fi 48 if [ -z $SYSCTL ]; then 49 SYSCTL="/proc/sys/debug/test_sysctl" 50 fi 51 if [ -z $PROD_SYSCTL ]; then 52 PROD_SYSCTL="/proc/sys" 53 fi 54 if [ -z $WRITES_STRICT ]; then 55 WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict" 56 fi 57 } 58 59 function check_production_sysctl_writes_strict() 60 { 61 echo -n "Checking production write strict setting ... " 62 if [ ! -e ${WRITES_STRICT} ]; then 63 echo "FAIL, but skip in case of old kernel" >&2 64 else 65 old_strict=$(cat ${WRITES_STRICT}) 66 if [ "$old_strict" = "1" ]; then 67 echo "OK" 68 else 69 echo "FAIL, strict value is 0 but force to 1 to continue" >&2 70 echo "1" > ${WRITES_STRICT} 71 fi 72 fi 73 74 if [ -z $PAGE_SIZE ]; then 75 PAGE_SIZE=$(getconf PAGESIZE) 76 fi 77 if [ -z $MAX_DIGITS ]; then 78 MAX_DIGITS=$(($PAGE_SIZE/8)) 79 fi 80 if [ -z $INT_MAX ]; then 81 INT_MAX=$(getconf INT_MAX) 82 fi 83 if [ -z $UINT_MAX ]; then 84 UINT_MAX=$(getconf UINT_MAX) 85 fi 86 } 87 88 test_reqs() 89 { 90 uid=$(id -u) 91 if [ $uid -ne 0 ]; then 92 echo $msg must be run as root >&2 93 exit $ksft_skip 94 fi 95 96 if ! which perl 2> /dev/null > /dev/null; then 97 echo "$0: You need perl installed" 98 exit $ksft_skip 99 fi 100 if ! which getconf 2> /dev/null > /dev/null; then 101 echo "$0: You need getconf installed" 102 exit $ksft_skip 103 fi 104 if ! which diff 2> /dev/null > /dev/null; then 105 echo "$0: You need diff installed" 106 exit $ksft_skip 107 fi 108 } 109 110 function load_req_mod() 111 { 112 if [ ! -d $SYSCTL ]; then 113 if ! modprobe -q -n $TEST_DRIVER; then 114 echo "$0: module $TEST_DRIVER not found [SKIP]" 115 echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2 116 exit $ksft_skip 117 fi 118 modprobe $TEST_DRIVER 119 if [ $? -ne 0 ]; then 120 echo "$0: modprobe $TEST_DRIVER failed." 121 exit 122 fi 123 fi 124 } 125 126 reset_vals() 127 { 128 VAL="" 129 TRIGGER=$(basename ${TARGET}) 130 case "$TRIGGER" in 131 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 esac 149 echo -n $VAL > $TARGET 150 } 151 152 set_orig() 153 { 154 if [ ! -z $TARGET ] && [ ! -z $ORIG ]; then 155 if [ -f ${TARGET} ]; then 156 echo "${ORIG}" > "${TARGET}" 157 fi 158 fi 159 } 160 161 set_test() 162 { 163 echo "${TEST_STR}" > "${TARGET}" 164 } 165 166 verify() 167 { 168 local seen 169 seen=$(cat "$1") 170 if [ "${seen}" != "${TEST_STR}" ]; then 171 return 1 172 fi 173 return 0 174 } 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 use 178 # diff against them you must first extract the output to a file, and 179 # then compare against that file. 180 verify_diff_proc_file() 181 { 182 TMP_DUMP_FILE=$(mktemp) 183 cat $1 > $TMP_DUMP_FILE 184 185 if ! diff -w -q $TMP_DUMP_FILE $2; then 186 return 1 187 else 188 return 0 189 fi 190 } 191 192 verify_diff_w() 193 { 194 echo "$TEST_STR" | diff -q -w -u - $1 > /dev/null 195 return $? 196 } 197 198 test_rc() 199 { 200 if [[ $rc != 0 ]]; then 201 echo "Failed test, return value: $rc" >&2 202 exit $rc 203 fi 204 } 205 206 test_finish() 207 { 208 set_orig 209 rm -f "${TEST_FILE}" 210 211 if [ ! -z ${old_strict} ]; then 212 echo ${old_strict} > ${WRITES_STRICT} 213 fi 214 exit $rc 215 } 216 217 run_numerictests() 218 { 219 echo "== Testing sysctl behavior against ${TARGET} ==" 220 221 rc=0 222 223 echo -n "Writing test file ... " 224 echo "${TEST_STR}" > "${TEST_FILE}" 225 if ! verify "${TEST_FILE}"; then 226 echo "FAIL" >&2 227 exit 1 228 else 229 echo "OK" 230 fi 231 232 echo -n "Checking sysctl is not set to test value ... " 233 if verify "${TARGET}"; then 234 echo "FAIL" >&2 235 exit 1 236 else 237 echo "OK" 238 fi 239 240 echo -n "Writing sysctl from shell ... " 241 set_test 242 if ! verify "${TARGET}"; then 243 echo "FAIL" >&2 244 exit 1 245 else 246 echo "OK" 247 fi 248 249 echo -n "Resetting sysctl to original value ... " 250 set_orig 251 if verify "${TARGET}"; then 252 echo "FAIL" >&2 253 exit 1 254 else 255 echo "OK" 256 fi 257 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 running 260 # specific behavioral tests. 261 262 echo -n "Writing entire sysctl in single write ... " 263 set_orig 264 dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null 265 if ! verify "${TARGET}"; then 266 echo "FAIL" >&2 267 rc=1 268 else 269 echo "OK" 270 fi 271 272 echo -n "Writing middle of sysctl after synchronized seek ... " 273 set_test 274 dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null 275 if ! verify "${TARGET}"; then 276 echo "FAIL" >&2 277 rc=1 278 else 279 echo "OK" 280 fi 281 282 echo -n "Writing beyond end of sysctl ... " 283 set_orig 284 dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null 285 if verify "${TARGET}"; then 286 echo "FAIL" >&2 287 rc=1 288 else 289 echo "OK" 290 fi 291 292 echo -n "Writing sysctl with multiple long writes ... " 293 set_orig 294 (perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \ 295 dd of="${TARGET}" bs=50 2>/dev/null 296 if verify "${TARGET}"; then 297 echo "FAIL" >&2 298 rc=1 299 else 300 echo "OK" 301 fi 302 test_rc 303 } 304 305 check_failure() 306 { 307 echo -n "Testing that $1 fails as expected ... " 308 reset_vals 309 TEST_STR="$1" 310 orig="$(cat $TARGET)" 311 echo -n "$TEST_STR" > $TARGET 2> /dev/null 312 313 # write should fail and $TARGET should retain its original value 314 if [ $? = 0 ] || [ "$(cat $TARGET)" != "$orig" ]; then 315 echo "FAIL" >&2 316 rc=1 317 else 318 echo "OK" 319 fi 320 test_rc 321 } 322 323 run_wideint_tests() 324 { 325 # sysctl conversion functions receive a boolean sign and ulong 326 # magnitude; here we list the magnitudes we want to test (each of 327 # which will be tested in both positive and negative forms). Since 328 # none of these values fit in 32 bits, writing them to an int- or 329 # 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 bits 333 # (potential for being falsely deemed in range) 334 0x0000000100000000 335 0x0000000100000001 336 0x00000001ffffffff 337 0x0000000180000000 338 0x000000017fffffff 339 340 # these look like negatives, but without a leading '-' are 341 # actually large positives (should be rejected as above 342 # despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32) 343 0xffffffff00000000 344 0xffffffff00000001 345 0xffffffffffffffff 346 0xffffffff80000000 347 0xffffffff7fffffff 348 ) 349 350 for sign in '' '-'; do 351 for mag in "${magnitudes[@]}"; do 352 check_failure "${sign}${mag}" 353 done 354 done 355 } 356 357 # Your test must accept digits 3 and 4 to use this 358 run_limit_digit() 359 { 360 echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ... " 361 reset_vals 362 363 LIMIT=$((MAX_DIGITS -1)) 364 TEST_STR="3" 365 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ 366 dd of="${TARGET}" 2>/dev/null 367 368 if ! verify "${TARGET}"; then 369 echo "FAIL" >&2 370 rc=1 371 else 372 echo "OK" 373 fi 374 test_rc 375 376 echo -n "Checking passing PAGE_SIZE of spaces fails on write ... " 377 reset_vals 378 379 LIMIT=$((MAX_DIGITS)) 380 TEST_STR="4" 381 (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ 382 dd of="${TARGET}" 2>/dev/null 383 384 if verify "${TARGET}"; then 385 echo "FAIL" >&2 386 rc=1 387 else 388 echo "OK" 389 fi 390 test_rc 391 } 392 393 # You are using an int 394 run_limit_digit_int() 395 { 396 echo -n "Testing INT_MAX works ... " 397 reset_vals 398 TEST_STR="$INT_MAX" 399 echo -n $TEST_STR > $TARGET 400 401 if ! verify "${TARGET}"; then 402 echo "FAIL" >&2 403 rc=1 404 else 405 echo "OK" 406 fi 407 test_rc 408 409 echo -n "Testing INT_MAX + 1 will fail as expected ... " 410 reset_vals 411 let TEST_STR=$INT_MAX+1 412 echo -n $TEST_STR > $TARGET 2> /dev/null 413 414 if verify "${TARGET}"; then 415 echo "FAIL" >&2 416 rc=1 417 else 418 echo "OK" 419 fi 420 test_rc 421 422 echo -n "Testing negative values will work as expected ... " 423 reset_vals 424 TEST_STR="-3" 425 echo -n $TEST_STR > $TARGET 2> /dev/null 426 if ! verify "${TARGET}"; then 427 echo "FAIL" >&2 428 rc=1 429 else 430 echo "OK" 431 fi 432 test_rc 433 } 434 435 # You used an int array 436 run_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 > $TARGET 441 442 if ! verify_diff_w "${TARGET}"; then 443 echo "FAIL" >&2 444 rc=1 445 else 446 echo "OK" 447 fi 448 test_rc 449 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 intact 453 TEST_STR="100 101" 454 echo -n $TEST_STR > $TARGET 455 # After we echo in, to help diff we need to set on TEST_STR what 456 # we expect the result to be. 457 TEST_STR="100 101 2 1" 458 459 if ! verify_diff_w "${TARGET}"; then 460 echo "FAIL" >&2 461 rc=1 462 else 463 echo "OK" 464 fi 465 test_rc 466 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 to 470 # 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/null 475 476 TEST_STR="9 101 2 1" 477 if ! verify_diff_w "${TARGET}"; then 478 echo "FAIL" >&2 479 rc=1 480 else 481 echo "OK" 482 fi 483 test_rc 484 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/null 492 493 TEST_STR="7 101 2 1" 494 if verify_diff_w "${TARGET}"; then 495 echo "FAIL" >&2 496 rc=1 497 else 498 echo "OK" 499 fi 500 test_rc 501 } 502 503 # You are using an unsigned int 504 run_limit_digit_uint() 505 { 506 echo -n "Testing UINT_MAX works ... " 507 reset_vals 508 TEST_STR="$UINT_MAX" 509 echo -n $TEST_STR > $TARGET 510 511 if ! verify "${TARGET}"; then 512 echo "FAIL" >&2 513 rc=1 514 else 515 echo "OK" 516 fi 517 test_rc 518 519 echo -n "Testing UINT_MAX + 1 will fail as expected ... " 520 reset_vals 521 TEST_STR=$(($UINT_MAX+1)) 522 echo -n $TEST_STR > $TARGET 2> /dev/null 523 524 if verify "${TARGET}"; then 525 echo "FAIL" >&2 526 rc=1 527 else 528 echo "OK" 529 fi 530 test_rc 531 532 echo -n "Testing negative values will not work as expected ... " 533 reset_vals 534 TEST_STR="-3" 535 echo -n $TEST_STR > $TARGET 2> /dev/null 536 537 if verify "${TARGET}"; then 538 echo "FAIL" >&2 539 rc=1 540 else 541 echo "OK" 542 fi 543 test_rc 544 } 545 546 run_stringtests() 547 { 548 echo -n "Writing entire sysctl in short writes ... " 549 set_orig 550 dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null 551 if ! verify "${TARGET}"; then 552 echo "FAIL" >&2 553 rc=1 554 else 555 echo "OK" 556 fi 557 558 echo -n "Writing middle of sysctl after unsynchronized seek ... " 559 set_test 560 dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null 561 if verify "${TARGET}"; then 562 echo "FAIL" >&2 563 rc=1 564 else 565 echo "OK" 566 fi 567 568 echo -n "Checking sysctl maxlen is at least $MAXLEN ... " 569 set_orig 570 perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \ 571 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null 572 if ! grep -q B "${TARGET}"; then 573 echo "FAIL" >&2 574 rc=1 575 else 576 echo "OK" 577 fi 578 579 echo -n "Checking sysctl keeps original string on overflow append ... " 580 set_orig 581 perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ 582 dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null 583 if grep -q B "${TARGET}"; then 584 echo "FAIL" >&2 585 rc=1 586 else 587 echo "OK" 588 fi 589 590 echo -n "Checking sysctl stays NULL terminated on write ... " 591 set_orig 592 perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ 593 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null 594 if grep -q B "${TARGET}"; then 595 echo "FAIL" >&2 596 rc=1 597 else 598 echo "OK" 599 fi 600 601 echo -n "Checking sysctl stays NULL terminated on overwrite ... " 602 set_orig 603 perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \ 604 dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null 605 if grep -q B "${TARGET}"; then 606 echo "FAIL" >&2 607 rc=1 608 else 609 echo "OK" 610 fi 611 612 test_rc 613 } 614 615 target_exists() 616 { 617 TARGET="${SYSCTL}/$1" 618 TEST_ID="$2" 619 620 if [ ! -f ${TARGET} ] ; then 621 return 0 622 fi 623 return 1 624 } 625 626 run_bitmaptest() { 627 # Total length of bitmaps string to use, a bit under 628 # the maximum input size of the test node 629 LENGTH=$((RANDOM % 65000)) 630 631 # First bit to set 632 BIT=$((RANDOM % 1024)) 633 634 # String containing our list of bits to set 635 TEST_STR=$BIT 636 637 # build up the string 638 while [ "${#TEST_STR}" -le "$LENGTH" ]; do 639 # Make sure next entry is discontiguous, 640 # skip ahead at least 2 641 BIT=$((BIT + $((2 + RANDOM % 10)))) 642 643 # Add new bit to the list 644 TEST_STR="${TEST_STR},${BIT}" 645 646 # Randomly make it a range 647 if [ "$((RANDOM % 2))" -eq "1" ]; then 648 RANGE_END=$((BIT + $((1 + RANDOM % 10)))) 649 TEST_STR="${TEST_STR}-${RANGE_END}" 650 BIT=$RANGE_END 651 fi 652 done 653 654 echo -n "Checking bitmap handler ... " 655 TEST_FILE=$(mktemp) 656 echo -n "$TEST_STR" > $TEST_FILE 657 658 cat $TEST_FILE > $TARGET 2> /dev/null 659 if [ $? -ne 0 ]; then 660 echo "FAIL" >&2 661 rc=1 662 test_rc 663 fi 664 665 if ! verify_diff_proc_file "$TARGET" "$TEST_FILE"; then 666 echo "FAIL" >&2 667 rc=1 668 else 669 echo "OK" 670 rc=0 671 fi 672 test_rc 673 } 674 675 sysctl_test_0001() 676 { 677 TARGET="${SYSCTL}/$(get_test_target 0001)" 678 reset_vals 679 ORIG=$(cat "${TARGET}") 680 TEST_STR=$(( $ORIG + 1 )) 681 682 run_numerictests 683 run_wideint_tests 684 run_limit_digit 685 } 686 687 sysctl_test_0002() 688 { 689 TARGET="${SYSCTL}/$(get_test_target 0002)" 690 reset_vals 691 ORIG=$(cat "${TARGET}") 692 TEST_STR="Testing sysctl" 693 # Only string sysctls support seeking/appending. 694 MAXLEN=65 695 696 run_numerictests 697 run_stringtests 698 } 699 700 sysctl_test_0003() 701 { 702 TARGET="${SYSCTL}/$(get_test_target 0003)" 703 reset_vals 704 ORIG=$(cat "${TARGET}") 705 TEST_STR=$(( $ORIG + 1 )) 706 707 run_numerictests 708 run_wideint_tests 709 run_limit_digit 710 run_limit_digit_int 711 } 712 713 sysctl_test_0004() 714 { 715 TARGET="${SYSCTL}/$(get_test_target 0004)" 716 reset_vals 717 ORIG=$(cat "${TARGET}") 718 TEST_STR=$(( $ORIG + 1 )) 719 720 run_numerictests 721 run_wideint_tests 722 run_limit_digit 723 run_limit_digit_uint 724 } 725 726 sysctl_test_0005() 727 { 728 TARGET="${SYSCTL}/$(get_test_target 0005)" 729 reset_vals 730 ORIG=$(cat "${TARGET}") 731 732 run_limit_digit_int_array 733 } 734 735 sysctl_test_0006() 736 { 737 TARGET="${SYSCTL}/$(get_test_target 0006)" 738 reset_vals 739 ORIG="" 740 run_bitmaptest 741 } 742 743 sysctl_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 ]; then 749 echo -e "SKIPPING\n$TARGET is not present" 750 return $ksft_skip 751 fi 752 753 if [ -d $DIR ]; then 754 echo -e "SKIPPING\nTest only possible if sysctl_test is built-in, not module:" 755 cat $TEST_DIR/config >&2 756 return $ksft_skip 757 fi 758 759 ORIG=$(cat "${TARGET}") 760 761 if [ x$ORIG = "x1" ]; then 762 echo "OK" 763 return 0 764 fi 765 766 if [ ! -f /proc/cmdline ]; then 767 echo -e "SKIPPING\nThere is no /proc/cmdline to check for paramter" 768 return $ksft_skip 769 fi 770 771 FOUND=$(grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline) 772 if [ $FOUND = "1" ]; then 773 echo -e "FAIL\nKernel param found but $TARGET is not 1." >&2 774 rc=1 775 test_rc 776 fi 777 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_skip 781 } 782 783 sysctl_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 ]; then 789 echo -e "SKIPPING\n$TARGET is not present" 790 return $ksft_skip 791 fi 792 793 ORIG_VALUE=$(cat "${TARGET}") 794 795 if [ $ORIG_VALUE -ne 1 ]; then 796 echo "FAIL" >&2 797 rc=1 798 test_rc 799 fi 800 801 echo "OK" 802 return 0 803 } 804 805 sysctl_test_0009() 806 { 807 TARGET="${SYSCTL}/$(get_test_target 0009)" 808 echo -n "Testing if $TARGET unregistered correctly ... " 809 if [ -d $TARGET ]; then 810 echo "FAIL" >&2 811 rc=1 812 test_rc 813 fi 814 815 echo "OK" 816 return 0 817 } 818 819 sysctl_test_0010() 820 { 821 TARGET="${SYSCTL}/$(get_test_target 0010)" 822 echo -n "Testing that $TARGET was not created ... " 823 if [ -d $TARGET ]; then 824 echo "FAIL" >&2 825 rc=1 826 test_rc 827 fi 828 829 echo "OK" 830 return 0 831 } 832 833 sysctl_test_0011() 834 { 835 TARGET="${SYSCTL}/$(get_test_target 0011)" 836 echo -n "Testing empty dir handling in ${TARGET} ... " 837 if [ ! -d ${TARGET} ]; then 838 echo -e "FAIL\nCould not create ${TARGET}" >&2 839 rc=1 840 test_rc 841 fi 842 843 TARGET2="${TARGET}/empty" 844 if [ ! -d ${TARGET2} ]; then 845 echo -e "FAIL\nCould not create ${TARGET2}" >&2 846 rc=1 847 test_rc 848 fi 849 850 echo "OK" 851 return 0 852 } 853 854 list_tests() 855 { 856 echo "Test ID list:" 857 echo 858 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 echo 862 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 875 usage() 876 { 877 NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .) 878 let NUM_TESTS=$NUM_TESTS+1 879 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 echo 894 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 echo 898 echo Example uses: 899 echo 900 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 echo 906 list_tests 907 exit 1 908 } 909 910 function test_num() 911 { 912 re='^[0-9]+$' 913 if ! [[ $1 =~ $re ]]; then 914 usage 915 fi 916 } 917 function remove_leading_zeros() 918 { 919 echo $1 | sed 's/^0*//' 920 } 921 922 function get_test_count() 923 { 924 test_num $1 925 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 930 function get_test_enabled() 931 { 932 test_num $1 933 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 938 function get_test_target() 939 { 940 test_num $1 941 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 946 function get_test_skip_no_target() 947 { 948 test_num $1 949 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 954 function skip_test() 955 { 956 TEST_ID=$1 957 TEST_TARGET=$2 958 if target_exists $TEST_TARGET $TEST_ID; then 959 TEST_SKIP=$(get_test_skip_no_target $TEST_ID) 960 if [[ $TEST_SKIP -eq "1" ]]; then 961 echo "Target $TEST_TARGET for test $TEST_ID does not exist ... SKIPPING" 962 return 0 963 fi 964 fi 965 return 1 966 } 967 968 function run_all_tests() 969 { 970 for i in $ALL_TESTS ; do 971 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" ]]; then 977 test_case $TEST_ID $TEST_COUNT $TEST_TARGET 978 fi 979 done 980 } 981 982 function watch_log() 983 { 984 if [ $# -ne 3 ]; then 985 clear 986 fi 987 date 988 echo "Running test: $2 - run #$1" 989 } 990 991 function watch_case() 992 { 993 i=0 994 while [ 1 ]; do 995 996 if [ $# -eq 1 ]; then 997 test_num $1 998 watch_log $i ${TEST_NAME}_test_$1 999 ${TEST_NAME}_test_$1 1000 else 1001 watch_log $i all 1002 run_all_tests 1003 fi 1004 let i=$i+1 1005 done 1006 } 1007 1008 function test_case() 1009 { 1010 TEST_ID=$1 1011 NUM_TESTS=$2 1012 TARGET=$3 1013 1014 if skip_test $TEST_ID $TARGET; then 1015 return 1016 fi 1017 1018 i=0 1019 while [ $i -lt $NUM_TESTS ]; do 1020 test_num $TEST_ID 1021 watch_log $i ${TEST_NAME}_test_${TEST_ID} noclear 1022 RUN_TEST=${TEST_NAME}_test_${TEST_ID} 1023 $RUN_TEST 1024 let i=$i+1 1025 done 1026 } 1027 1028 function parse_args() 1029 { 1030 if [ $# -eq 0 ]; then 1031 run_all_tests 1032 else 1033 if [[ "$1" = "all" ]]; then 1034 run_all_tests 1035 elif [[ "$1" = "-w" ]]; then 1036 shift 1037 watch_case $@ 1038 elif [[ "$1" = "-t" ]]; then 1039 shift 1040 test_num $1 1041 test_case $1 $(get_test_count $1) $(get_test_target $1) 1042 elif [[ "$1" = "-c" ]]; then 1043 shift 1044 test_num $1 1045 test_num $2 1046 test_case $1 $2 $(get_test_target $1) 1047 elif [[ "$1" = "-s" ]]; then 1048 shift 1049 test_case $1 1 $(get_test_target $1) 1050 elif [[ "$1" = "-l" ]]; then 1051 list_tests 1052 elif [[ "$1" = "-h" || "$1" = "--help" ]]; then 1053 usage 1054 else 1055 usage 1056 fi 1057 fi 1058 } 1059 1060 test_reqs 1061 allow_user_defaults 1062 check_production_sysctl_writes_strict 1063 load_req_mod 1064 1065 trap "test_finish" EXIT 1066 1067 parse_args $@ 1068 1069 exit 0
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.