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