1 #!/bin/ksh 2 # 3 # This file and its contents are supplied under the terms of the 4 # Common Development and Distribution License ("CDDL"), version 1.0. 5 # You may only use this file in accordance with the terms of version 6 # 1.0 of the CDDL. 7 # 8 # A full copy of the text of the CDDL should have accompanied this 9 # source. A copy of the CDDL is also available via the Internet at 10 # http://www.illumos.org/license/CDDL. 11 # 12 13 # 14 # Copyright 2019 Robert Mustacchi 15 # Copyright 2020 Joyent, Inc. 16 # 17 18 # 19 # Basic tests of sleep(1). sleep is a little hard to test, especially 20 # for longer running cases. Therefore to test it, we basically take 21 # advantage of our knowledge of how it is implemented. We see that it 22 # properly is sleeping for the right amount of time by looking at the 23 # call to nanosleep in libc and make sure that the structures time is 24 # what we expect. 25 # 26 27 unalias -a 28 set -o pipefail 29 30 # 31 # Set the locale for the start of the test to be C.UTF-8 to make sure 32 # that we have a good starting point and correct fractional 33 # interpretation. 34 # 35 export LC_ALL=C.UTF-8 36 37 sleep_arg0="$(basename $0)" 38 sleep_prog=/usr/bin/sleep 39 sleep_dir="$(dirname $0)" 40 sleep_dscript=$sleep_dir/sleep.d 41 sleep_awk=$sleep_dir/sleep.awk 42 sleep_exit=0 43 44 # 45 # This is the factor by which we're going to basically say that the slp 46 # microstate has to complete within. Because the system will usually 47 # have a bit of additional latency, we will usually be greater than that 48 # as well. This determines how much we should actually do that by. 49 # 50 sleep_factor=1.5 51 52 warn() 53 { 54 typeset msg="$*" 55 [[ -z "$msg" ]] && msg="failed" 56 echo "TEST FAILED: $sleep_arg0: $msg" >&2 57 } 58 59 sleep_bound() 60 { 61 typeset min=$1 62 typeset test="sleep $min: bounding" 63 64 ptime -m $sleep_prog $min 2>&1 | nawk -f $sleep_awk min=$min \ 65 factor=$sleep_factor 66 if [[ $? -ne 42 ]]; then 67 warn "$test" 68 sleep_exit=1 69 else 70 printf "TEST PASSED: %s\n" "$test" 71 fi 72 } 73 74 sleep_one() 75 { 76 typeset arg=$1 77 typeset secs=$2 78 typeset nsecs=$3 79 typeset test="sleep $arg: $secs secs $nsecs ns" 80 81 if ! dtrace -qws $sleep_dscript -c "$sleep_prog $arg" $secs $nsecs; then 82 warn "$test" 83 sleep_exit=1 84 else 85 printf "TEST PASSED: %s\n" "$test" 86 fi 87 } 88 89 sleep_err() 90 { 91 typeset test="negative test: sleep $*" 92 93 if $sleep_prog $* 2>/dev/null; then 94 warn "$test" 95 sleep_exit=1 96 else 97 printf "TEST PASSED: %s\n" "$test" 98 fi 99 } 100 101 if [[ -n $SLEEP ]]; then 102 sleep_prog=$SLEEP 103 fi 104 105 # 106 # First test basic integer values. Both in base 10 and hex. 107 # 108 sleep_one 1 1 0 109 sleep_one 23 23 0 110 sleep_one 0xff 0xff 0 111 sleep_one 123456789 123456789 0 112 sleep_one 1e8 100000000 0 113 114 # 115 # Fractional values. 116 # 117 sleep_one 2.5 2 500000000 118 sleep_one 0.9 0 900000000 119 sleep_one 34.0051 34 5100000 120 sleep_one 0x654.100 0x654 62500000 121 122 # 123 # Large values that are basically the same as infinity. The current 124 # implementation will do a sleep in groups of INT32_MAX at a time. So 125 # make sure our large values are the same. 126 # 127 sleep_one Inf 0x7fffffff 0 128 sleep_one +Inf 0x7fffffff 0 129 sleep_one 1e100 0x7fffffff 0 130 sleep_one 0x123456789abc 0x7fffffff 0 131 132 # 133 # That all of our suffixes for time increments work and make sense. 134 # 135 sleep_one 1s 1 0 136 sleep_one 1m 60 0 137 sleep_one 1h 3600 0 138 sleep_one 1d 86400 0 139 sleep_one 1w 604800 0 140 sleep_one 1y 31536000 0 141 142 sleep_one 3.5s 3 500000000 143 sleep_one 3.6d 311040 0 144 sleep_one 2.001y 63103536 0 145 146 # 147 # Now we need to go through and use ptime -m to get the slp time for 148 # things and make sure it is always greater than what we asked for and 149 # less than a bound. 150 # 151 sleep_bound 0.01 152 sleep_bound 0.1 153 sleep_bound 0.25 154 sleep_bound 0.5 155 sleep_bound 0.75 156 157 # 158 # The next set of tests are negative tests that make sure that sleep 159 # does not correctly execute in these cases. 160 # 161 sleep_err \"\" 162 sleep_err 1 2 3 163 sleep_err 1@23 164 sleep_err 0,56 165 sleep_err "hello" 166 sleep_err s 167 sleep_err 1z 168 sleep_err -- -0.3 169 170 # 171 # Test a locale that uses a ',' character (de_DE.UTF-8 is one) as the 172 # decimal point to make sure that sleep is correctly using LC_NUMERIC. 173 export LC_ALL=de_DE.UTF-8 174 sleep_err 21.45 175 sleep_one 2,5 2 500000000 176 sleep_one 34,0051 34 5100000 177 sleep_one 3,6d 311040 0 178 export LC_ALL=C.UTF-8 179 180 exit $sleep_exit