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