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