Home | History | Annotate | Download | only in sysctl
      1 #!/bin/bash
      2 # Copyright (C) 2017 Luis R. Rodriguez <mcgrof (at] 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.
     18 ksft_skip=4
     19 
     20 TEST_NAME="sysctl"
     21 TEST_DRIVER="test_${TEST_NAME}"
     22 TEST_DIR=$(dirname $0)
     23 TEST_FILE=$(mktemp)
     24 
     25 # This represents
     26 #
     27 # TEST_ID:TEST_COUNT:ENABLED
     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 #
     33 # Once these are enabled please leave them as-is. Write your own test,
     34 # we have tons of space.
     35 ALL_TESTS="0001:1:1"
     36 ALL_TESTS="$ALL_TESTS 0002:1:1"
     37 ALL_TESTS="$ALL_TESTS 0003:1:1"
     38 ALL_TESTS="$ALL_TESTS 0004:1:1"
     39 ALL_TESTS="$ALL_TESTS 0005:3:1"
     40 
     41 test_modprobe()
     42 {
     43        if [ ! -d $DIR ]; then
     44                echo "$0: $DIR not present" >&2
     45                echo "You must have the following enabled in your kernel:" >&2
     46                cat $TEST_DIR/config >&2
     47                exit $ksft_skip
     48        fi
     49 }
     50 
     51 function allow_user_defaults()
     52 {
     53 	if [ -z $DIR ]; then
     54 		DIR="/sys/module/test_sysctl/"
     55 	fi
     56 	if [ -z $DEFAULT_NUM_TESTS ]; then
     57 		DEFAULT_NUM_TESTS=50
     58 	fi
     59 	if [ -z $SYSCTL ]; then
     60 		SYSCTL="/proc/sys/debug/test_sysctl"
     61 	fi
     62 	if [ -z $PROD_SYSCTL ]; then
     63 		PROD_SYSCTL="/proc/sys"
     64 	fi
     65 	if [ -z $WRITES_STRICT ]; then
     66 		WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict"
     67 	fi
     68 }
     69 
     70 function check_production_sysctl_writes_strict()
     71 {
     72 	echo -n "Checking production write strict setting ... "
     73 	if [ ! -e ${WRITES_STRICT} ]; then
     74 		echo "FAIL, but skip in case of old kernel" >&2
     75 	else
     76 		old_strict=$(cat ${WRITES_STRICT})
     77 		if [ "$old_strict" = "1" ]; then
     78 			echo "ok"
     79 		else
     80 			echo "FAIL, strict value is 0 but force to 1 to continue" >&2
     81 			echo "1" > ${WRITES_STRICT}
     82 		fi
     83 	fi
     84 
     85 	if [ -z $PAGE_SIZE ]; then
     86 		PAGE_SIZE=$(getconf PAGESIZE)
     87 	fi
     88 	if [ -z $MAX_DIGITS ]; then
     89 		MAX_DIGITS=$(($PAGE_SIZE/8))
     90 	fi
     91 	if [ -z $INT_MAX ]; then
     92 		INT_MAX=$(getconf INT_MAX)
     93 	fi
     94 	if [ -z $UINT_MAX ]; then
     95 		UINT_MAX=$(getconf UINT_MAX)
     96 	fi
     97 }
     98 
     99 test_reqs()
    100 {
    101 	uid=$(id -u)
    102 	if [ $uid -ne 0 ]; then
    103 		echo $msg must be run as root >&2
    104 		exit $ksft_skip
    105 	fi
    106 
    107 	if ! which perl 2> /dev/null > /dev/null; then
    108 		echo "$0: You need perl installed"
    109 		exit $ksft_skip
    110 	fi
    111 	if ! which getconf 2> /dev/null > /dev/null; then
    112 		echo "$0: You need getconf installed"
    113 		exit $ksft_skip
    114 	fi
    115 	if ! which diff 2> /dev/null > /dev/null; then
    116 		echo "$0: You need diff installed"
    117 		exit $ksft_skip
    118 	fi
    119 }
    120 
    121 function load_req_mod()
    122 {
    123 	if [ ! -d $DIR ]; then
    124 		if ! modprobe -q -n $TEST_DRIVER; then
    125 			echo "$0: module $TEST_DRIVER not found [SKIP]"
    126 			exit $ksft_skip
    127 		fi
    128 		modprobe $TEST_DRIVER
    129 		if [ $? -ne 0 ]; then
    130 			exit
    131 		fi
    132 	fi
    133 }
    134 
    135 reset_vals()
    136 {
    137 	VAL=""
    138 	TRIGGER=$(basename ${TARGET})
    139 	case "$TRIGGER" in
    140 		int_0001)
    141 			VAL="60"
    142 			;;
    143 		int_0002)
    144 			VAL="1"
    145 			;;
    146 		uint_0001)
    147 			VAL="314"
    148 			;;
    149 		string_0001)
    150 			VAL="(none)"
    151 			;;
    152 		*)
    153 			;;
    154 	esac
    155 	echo -n $VAL > $TARGET
    156 }
    157 
    158 set_orig()
    159 {
    160 	if [ ! -z $TARGET ]; then
    161 		echo "${ORIG}" > "${TARGET}"
    162 	fi
    163 }
    164 
    165 set_test()
    166 {
    167 	echo "${TEST_STR}" > "${TARGET}"
    168 }
    169 
    170 verify()
    171 {
    172 	local seen
    173 	seen=$(cat "$1")
    174 	if [ "${seen}" != "${TEST_STR}" ]; then
    175 		return 1
    176 	fi
    177 	return 0
    178 }
    179 
    180 verify_diff_w()
    181 {
    182 	echo "$TEST_STR" | diff -q -w -u - $1
    183 	return $?
    184 }
    185 
    186 test_rc()
    187 {
    188 	if [[ $rc != 0 ]]; then
    189 		echo "Failed test, return value: $rc" >&2
    190 		exit $rc
    191 	fi
    192 }
    193 
    194 test_finish()
    195 {
    196 	set_orig
    197 	rm -f "${TEST_FILE}"
    198 
    199 	if [ ! -z ${old_strict} ]; then
    200 		echo ${old_strict} > ${WRITES_STRICT}
    201 	fi
    202 	exit $rc
    203 }
    204 
    205 run_numerictests()
    206 {
    207 	echo "== Testing sysctl behavior against ${TARGET} =="
    208 
    209 	rc=0
    210 
    211 	echo -n "Writing test file ... "
    212 	echo "${TEST_STR}" > "${TEST_FILE}"
    213 	if ! verify "${TEST_FILE}"; then
    214 		echo "FAIL" >&2
    215 		exit 1
    216 	else
    217 		echo "ok"
    218 	fi
    219 
    220 	echo -n "Checking sysctl is not set to test value ... "
    221 	if verify "${TARGET}"; then
    222 		echo "FAIL" >&2
    223 		exit 1
    224 	else
    225 		echo "ok"
    226 	fi
    227 
    228 	echo -n "Writing sysctl from shell ... "
    229 	set_test
    230 	if ! verify "${TARGET}"; then
    231 		echo "FAIL" >&2
    232 		exit 1
    233 	else
    234 		echo "ok"
    235 	fi
    236 
    237 	echo -n "Resetting sysctl to original value ... "
    238 	set_orig
    239 	if verify "${TARGET}"; then
    240 		echo "FAIL" >&2
    241 		exit 1
    242 	else
    243 		echo "ok"
    244 	fi
    245 
    246 	# Now that we've validated the sanity of "set_test" and "set_orig",
    247 	# we can use those functions to set starting states before running
    248 	# specific behavioral tests.
    249 
    250 	echo -n "Writing entire sysctl in single write ... "
    251 	set_orig
    252 	dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null
    253 	if ! verify "${TARGET}"; then
    254 		echo "FAIL" >&2
    255 		rc=1
    256 	else
    257 		echo "ok"
    258 	fi
    259 
    260 	echo -n "Writing middle of sysctl after synchronized seek ... "
    261 	set_test
    262 	dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 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 beyond end of sysctl ... "
    271 	set_orig
    272 	dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 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 sysctl with multiple long writes ... "
    281 	set_orig
    282 	(perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \
    283 		dd of="${TARGET}" bs=50 2>/dev/null
    284 	if verify "${TARGET}"; then
    285 		echo "FAIL" >&2
    286 		rc=1
    287 	else
    288 		echo "ok"
    289 	fi
    290 	test_rc
    291 }
    292 
    293 # Your test must accept digits 3 and 4 to use this
    294 run_limit_digit()
    295 {
    296 	echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ..."
    297 	reset_vals
    298 
    299 	LIMIT=$((MAX_DIGITS -1))
    300 	TEST_STR="3"
    301 	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
    302 		dd of="${TARGET}" 2>/dev/null
    303 
    304 	if ! verify "${TARGET}"; then
    305 		echo "FAIL" >&2
    306 		rc=1
    307 	else
    308 		echo "ok"
    309 	fi
    310 	test_rc
    311 
    312 	echo -n "Checking passing PAGE_SIZE of spaces fails on write ..."
    313 	reset_vals
    314 
    315 	LIMIT=$((MAX_DIGITS))
    316 	TEST_STR="4"
    317 	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
    318 		dd of="${TARGET}" 2>/dev/null
    319 
    320 	if verify "${TARGET}"; then
    321 		echo "FAIL" >&2
    322 		rc=1
    323 	else
    324 		echo "ok"
    325 	fi
    326 	test_rc
    327 }
    328 
    329 # You are using an int
    330 run_limit_digit_int()
    331 {
    332 	echo -n "Testing INT_MAX works ..."
    333 	reset_vals
    334 	TEST_STR="$INT_MAX"
    335 	echo -n $TEST_STR > $TARGET
    336 
    337 	if ! verify "${TARGET}"; then
    338 		echo "FAIL" >&2
    339 		rc=1
    340 	else
    341 		echo "ok"
    342 	fi
    343 	test_rc
    344 
    345 	echo -n "Testing INT_MAX + 1 will fail as expected..."
    346 	reset_vals
    347 	let TEST_STR=$INT_MAX+1
    348 	echo -n $TEST_STR > $TARGET 2> /dev/null
    349 
    350 	if verify "${TARGET}"; then
    351 		echo "FAIL" >&2
    352 		rc=1
    353 	else
    354 		echo "ok"
    355 	fi
    356 	test_rc
    357 
    358 	echo -n "Testing negative values will work as expected..."
    359 	reset_vals
    360 	TEST_STR="-3"
    361 	echo -n $TEST_STR > $TARGET 2> /dev/null
    362 	if ! verify "${TARGET}"; then
    363 		echo "FAIL" >&2
    364 		rc=1
    365 	else
    366 		echo "ok"
    367 	fi
    368 	test_rc
    369 }
    370 
    371 # You used an int array
    372 run_limit_digit_int_array()
    373 {
    374 	echo -n "Testing array works as expected ... "
    375 	TEST_STR="4 3 2 1"
    376 	echo -n $TEST_STR > $TARGET
    377 
    378 	if ! verify_diff_w "${TARGET}"; then
    379 		echo "FAIL" >&2
    380 		rc=1
    381 	else
    382 		echo "ok"
    383 	fi
    384 	test_rc
    385 
    386 	echo -n "Testing skipping trailing array elements works ... "
    387 	# Do not reset_vals, carry on the values from the last test.
    388 	# If we only echo in two digits the last two are left intact
    389 	TEST_STR="100 101"
    390 	echo -n $TEST_STR > $TARGET
    391 	# After we echo in, to help diff we need to set on TEST_STR what
    392 	# we expect the result to be.
    393 	TEST_STR="100 101 2 1"
    394 
    395 	if ! verify_diff_w "${TARGET}"; then
    396 		echo "FAIL" >&2
    397 		rc=1
    398 	else
    399 		echo "ok"
    400 	fi
    401 	test_rc
    402 
    403 	echo -n "Testing PAGE_SIZE limit on array works ... "
    404 	# Do not reset_vals, carry on the values from the last test.
    405 	# Even if you use an int array, you are still restricted to
    406 	# MAX_DIGITS, this is a known limitation. Test limit works.
    407 	LIMIT=$((MAX_DIGITS -1))
    408 	TEST_STR="9"
    409 	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
    410 		dd of="${TARGET}" 2>/dev/null
    411 
    412 	TEST_STR="9 101 2 1"
    413 	if ! verify_diff_w "${TARGET}"; then
    414 		echo "FAIL" >&2
    415 		rc=1
    416 	else
    417 		echo "ok"
    418 	fi
    419 	test_rc
    420 
    421 	echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "
    422 	# Do not reset_vals, carry on the values from the last test.
    423 	# Now go over limit.
    424 	LIMIT=$((MAX_DIGITS))
    425 	TEST_STR="7"
    426 	(perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
    427 		dd of="${TARGET}" 2>/dev/null
    428 
    429 	TEST_STR="7 101 2 1"
    430 	if verify_diff_w "${TARGET}"; then
    431 		echo "FAIL" >&2
    432 		rc=1
    433 	else
    434 		echo "ok"
    435 	fi
    436 	test_rc
    437 }
    438 
    439 # You are using an unsigned int
    440 run_limit_digit_uint()
    441 {
    442 	echo -n "Testing UINT_MAX works ..."
    443 	reset_vals
    444 	TEST_STR="$UINT_MAX"
    445 	echo -n $TEST_STR > $TARGET
    446 
    447 	if ! verify "${TARGET}"; then
    448 		echo "FAIL" >&2
    449 		rc=1
    450 	else
    451 		echo "ok"
    452 	fi
    453 	test_rc
    454 
    455 	echo -n "Testing UINT_MAX + 1 will fail as expected..."
    456 	reset_vals
    457 	TEST_STR=$(($UINT_MAX+1))
    458 	echo -n $TEST_STR > $TARGET 2> /dev/null
    459 
    460 	if verify "${TARGET}"; then
    461 		echo "FAIL" >&2
    462 		rc=1
    463 	else
    464 		echo "ok"
    465 	fi
    466 	test_rc
    467 
    468 	echo -n "Testing negative values will not work as expected ..."
    469 	reset_vals
    470 	TEST_STR="-3"
    471 	echo -n $TEST_STR > $TARGET 2> /dev/null
    472 
    473 	if verify "${TARGET}"; then
    474 		echo "FAIL" >&2
    475 		rc=1
    476 	else
    477 		echo "ok"
    478 	fi
    479 	test_rc
    480 }
    481 
    482 run_stringtests()
    483 {
    484 	echo -n "Writing entire sysctl in short writes ... "
    485 	set_orig
    486 	dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null
    487 	if ! verify "${TARGET}"; then
    488 		echo "FAIL" >&2
    489 		rc=1
    490 	else
    491 		echo "ok"
    492 	fi
    493 
    494 	echo -n "Writing middle of sysctl after unsynchronized seek ... "
    495 	set_test
    496 	dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null
    497 	if verify "${TARGET}"; then
    498 		echo "FAIL" >&2
    499 		rc=1
    500 	else
    501 		echo "ok"
    502 	fi
    503 
    504 	echo -n "Checking sysctl maxlen is at least $MAXLEN ... "
    505 	set_orig
    506 	perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \
    507 		dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
    508 	if ! grep -q B "${TARGET}"; then
    509 		echo "FAIL" >&2
    510 		rc=1
    511 	else
    512 		echo "ok"
    513 	fi
    514 
    515 	echo -n "Checking sysctl keeps original string on overflow append ... "
    516 	set_orig
    517 	perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
    518 		dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null
    519 	if grep -q B "${TARGET}"; then
    520 		echo "FAIL" >&2
    521 		rc=1
    522 	else
    523 		echo "ok"
    524 	fi
    525 
    526 	echo -n "Checking sysctl stays NULL terminated on write ... "
    527 	set_orig
    528 	perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
    529 		dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
    530 	if grep -q B "${TARGET}"; then
    531 		echo "FAIL" >&2
    532 		rc=1
    533 	else
    534 		echo "ok"
    535 	fi
    536 
    537 	echo -n "Checking sysctl stays NULL terminated on overwrite ... "
    538 	set_orig
    539 	perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \
    540 		dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null
    541 	if grep -q B "${TARGET}"; then
    542 		echo "FAIL" >&2
    543 		rc=1
    544 	else
    545 		echo "ok"
    546 	fi
    547 
    548 	test_rc
    549 }
    550 
    551 sysctl_test_0001()
    552 {
    553 	TARGET="${SYSCTL}/int_0001"
    554 	reset_vals
    555 	ORIG=$(cat "${TARGET}")
    556 	TEST_STR=$(( $ORIG + 1 ))
    557 
    558 	run_numerictests
    559 	run_limit_digit
    560 }
    561 
    562 sysctl_test_0002()
    563 {
    564 	TARGET="${SYSCTL}/string_0001"
    565 	reset_vals
    566 	ORIG=$(cat "${TARGET}")
    567 	TEST_STR="Testing sysctl"
    568 	# Only string sysctls support seeking/appending.
    569 	MAXLEN=65
    570 
    571 	run_numerictests
    572 	run_stringtests
    573 }
    574 
    575 sysctl_test_0003()
    576 {
    577 	TARGET="${SYSCTL}/int_0002"
    578 	reset_vals
    579 	ORIG=$(cat "${TARGET}")
    580 	TEST_STR=$(( $ORIG + 1 ))
    581 
    582 	run_numerictests
    583 	run_limit_digit
    584 	run_limit_digit_int
    585 }
    586 
    587 sysctl_test_0004()
    588 {
    589 	TARGET="${SYSCTL}/uint_0001"
    590 	reset_vals
    591 	ORIG=$(cat "${TARGET}")
    592 	TEST_STR=$(( $ORIG + 1 ))
    593 
    594 	run_numerictests
    595 	run_limit_digit
    596 	run_limit_digit_uint
    597 }
    598 
    599 sysctl_test_0005()
    600 {
    601 	TARGET="${SYSCTL}/int_0003"
    602 	reset_vals
    603 	ORIG=$(cat "${TARGET}")
    604 
    605 	run_limit_digit_int_array
    606 }
    607 
    608 list_tests()
    609 {
    610 	echo "Test ID list:"
    611 	echo
    612 	echo "TEST_ID x NUM_TEST"
    613 	echo "TEST_ID:   Test ID"
    614 	echo "NUM_TESTS: Number of recommended times to run the test"
    615 	echo
    616 	echo "0001 x $(get_test_count 0001) - tests proc_dointvec_minmax()"
    617 	echo "0002 x $(get_test_count 0002) - tests proc_dostring()"
    618 	echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"
    619 	echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"
    620 	echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"
    621 }
    622 
    623 test_reqs
    624 
    625 usage()
    626 {
    627 	NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)
    628 	let NUM_TESTS=$NUM_TESTS+1
    629 	MAX_TEST=$(printf "%04d\n" $NUM_TESTS)
    630 	echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"
    631 	echo "		 [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
    632 	echo "           [ all ] [ -h | --help ] [ -l ]"
    633 	echo ""
    634 	echo "Valid tests: 0001-$MAX_TEST"
    635 	echo ""
    636 	echo "    all     Runs all tests (default)"
    637 	echo "    -t      Run test ID the number amount of times is recommended"
    638 	echo "    -w      Watch test ID run until it runs into an error"
    639 	echo "    -c      Run test ID once"
    640 	echo "    -s      Run test ID x test-count number of times"
    641 	echo "    -l      List all test ID list"
    642 	echo " -h|--help  Help"
    643 	echo
    644 	echo "If an error every occurs execution will immediately terminate."
    645 	echo "If you are adding a new test try using -w <test-ID> first to"
    646 	echo "make sure the test passes a series of tests."
    647 	echo
    648 	echo Example uses:
    649 	echo
    650 	echo "$TEST_NAME.sh            -- executes all tests"
    651 	echo "$TEST_NAME.sh -t 0002    -- Executes test ID 0002 number of times is recomended"
    652 	echo "$TEST_NAME.sh -w 0002    -- Watch test ID 0002 run until an error occurs"
    653 	echo "$TEST_NAME.sh -s 0002    -- Run test ID 0002 once"
    654 	echo "$TEST_NAME.sh -c 0002 3  -- Run test ID 0002 three times"
    655 	echo
    656 	list_tests
    657 	exit 1
    658 }
    659 
    660 function test_num()
    661 {
    662 	re='^[0-9]+$'
    663 	if ! [[ $1 =~ $re ]]; then
    664 		usage
    665 	fi
    666 }
    667 
    668 function get_test_count()
    669 {
    670 	test_num $1
    671 	TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
    672 	LAST_TWO=${TEST_DATA#*:*}
    673 	echo ${LAST_TWO%:*}
    674 }
    675 
    676 function get_test_enabled()
    677 {
    678 	test_num $1
    679 	TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
    680 	echo ${TEST_DATA#*:*:}
    681 }
    682 
    683 function run_all_tests()
    684 {
    685 	for i in $ALL_TESTS ; do
    686 		TEST_ID=${i%:*:*}
    687 		ENABLED=$(get_test_enabled $TEST_ID)
    688 		TEST_COUNT=$(get_test_count $TEST_ID)
    689 		if [[ $ENABLED -eq "1" ]]; then
    690 			test_case $TEST_ID $TEST_COUNT
    691 		fi
    692 	done
    693 }
    694 
    695 function watch_log()
    696 {
    697 	if [ $# -ne 3 ]; then
    698 		clear
    699 	fi
    700 	date
    701 	echo "Running test: $2 - run #$1"
    702 }
    703 
    704 function watch_case()
    705 {
    706 	i=0
    707 	while [ 1 ]; do
    708 
    709 		if [ $# -eq 1 ]; then
    710 			test_num $1
    711 			watch_log $i ${TEST_NAME}_test_$1
    712 			${TEST_NAME}_test_$1
    713 		else
    714 			watch_log $i all
    715 			run_all_tests
    716 		fi
    717 		let i=$i+1
    718 	done
    719 }
    720 
    721 function test_case()
    722 {
    723 	NUM_TESTS=$DEFAULT_NUM_TESTS
    724 	if [ $# -eq 2 ]; then
    725 		NUM_TESTS=$2
    726 	fi
    727 
    728 	i=0
    729 	while [ $i -lt $NUM_TESTS ]; do
    730 		test_num $1
    731 		watch_log $i ${TEST_NAME}_test_$1 noclear
    732 		RUN_TEST=${TEST_NAME}_test_$1
    733 		$RUN_TEST
    734 		let i=$i+1
    735 	done
    736 }
    737 
    738 function parse_args()
    739 {
    740 	if [ $# -eq 0 ]; then
    741 		run_all_tests
    742 	else
    743 		if [[ "$1" = "all" ]]; then
    744 			run_all_tests
    745 		elif [[ "$1" = "-w" ]]; then
    746 			shift
    747 			watch_case $@
    748 		elif [[ "$1" = "-t" ]]; then
    749 			shift
    750 			test_num $1
    751 			test_case $1 $(get_test_count $1)
    752 		elif [[ "$1" = "-c" ]]; then
    753 			shift
    754 			test_num $1
    755 			test_num $2
    756 			test_case $1 $2
    757 		elif [[ "$1" = "-s" ]]; then
    758 			shift
    759 			test_case $1 1
    760 		elif [[ "$1" = "-l" ]]; then
    761 			list_tests
    762 		elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
    763 			usage
    764 		else
    765 			usage
    766 		fi
    767 	fi
    768 }
    769 
    770 test_reqs
    771 allow_user_defaults
    772 check_production_sysctl_writes_strict
    773 test_modprobe
    774 load_req_mod
    775 
    776 trap "test_finish" EXIT
    777 
    778 parse_args $@
    779 
    780 exit 0
    781