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