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