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