1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

tests: fix intermittent $RANDOM reseeding fails (re: af6a32d1)

When testing whether subshell $RANDOM reseeding worked, checking
for non-identical numbers is not sufficient. There is no check for
randomly occurring duplicate numbers, nor can there be, because
subshells cannot (or, in the case of virtual subshells, should not)
influence each other or the parent shell.

src/cmd/ksh93/tests/variables.sh:
- Try up to three times, tolerating identical numbers twice.
This commit is contained in:
Martijn Dekker 2021-11-15 19:07:19 +01:00
parent 56c2e13e92
commit 7ea95b7df3

View file

@ -34,46 +34,60 @@ fi
# When the $RANDOM variable is used in a forked subshell, it shouldn't # When the $RANDOM variable is used in a forked subshell, it shouldn't
# use the same pseudorandom seed as the main shell. # use the same pseudorandom seed as the main shell.
# https://github.com/ksh93/ksh/issues/285 # https://github.com/ksh93/ksh/issues/285
# These tests sometimes fail as duplicate numbers can occur randomly, so try up to $N times.
integer N=3 i rand1 rand2
RANDOM=123 RANDOM=123
function rand_print { function rand_print {
ulimit -t unlimited 2> /dev/null ulimit -t unlimited 2> /dev/null
print $RANDOM print $RANDOM
} }
integer rand1=$(rand_print) for((i=0; i<N; i++))
integer rand2=$(rand_print) do rand1=$(rand_print)
rand2=$(rand_print)
((rand1 != rand2)) && break
done
(( rand1 == rand2 )) && err_exit "Test 1: \$RANDOM seed in subshell doesn't change" \ (( rand1 == rand2 )) && err_exit "Test 1: \$RANDOM seed in subshell doesn't change" \
"(both results are $rand1)" "(both results are $rand1)"
# Make sure we're actually using a different pseudorandom seed # Make sure we're actually using a different pseudorandom seed
integer rand1=$( for((i=0; i<N; i++))
ulimit -t unlimited 2> /dev/null do rand1=$(
test $RANDOM ulimit -t unlimited 2> /dev/null
print $RANDOM test $RANDOM
) print $RANDOM
integer rand2=${ print $RANDOM ;} )
rand2=${ print $RANDOM ;}
((rand1 != rand2)) && break
done
(( rand1 == rand2 )) && err_exit "Test 2: \$RANDOM seed in subshell doesn't change" \ (( rand1 == rand2 )) && err_exit "Test 2: \$RANDOM seed in subshell doesn't change" \
"(both results are $rand1)" "(both results are $rand1)"
# $RANDOM should be reseeded when the final command is inside of a subshell # $RANDOM should be reseeded when the final command is inside of a subshell
rand1=$($SHELL -c 'RANDOM=1; (echo $RANDOM)') for((i=0; i<N; i++))
rand2=$($SHELL -c 'RANDOM=1; (echo $RANDOM)') do rand1=$("$SHELL" -c 'RANDOM=1; (echo $RANDOM)')
rand2=$("$SHELL" -c 'RANDOM=1; (echo $RANDOM)')
((rand1 != rand2)) && break
done
(( rand1 == rand2 )) && err_exit "Test 3: \$RANDOM seed in subshell doesn't change" \ (( rand1 == rand2 )) && err_exit "Test 3: \$RANDOM seed in subshell doesn't change" \
"(both results are $rand1)" "(both results are $rand1)"
# $RANDOM should be reseeded for the ( simple_command & ) optimization # $RANDOM should be reseeded for the ( simple_command & ) optimization
( echo $RANDOM & ) >r1 for((i=0; i<N; i++))
( echo $RANDOM & ) >r2 do ( echo $RANDOM & ) >|r1
integer giveup=0 ( echo $RANDOM & ) >|r2
trap '((giveup++))' USR1 integer giveup=0
(sleep 2; kill -s USR1 $$) & trap '((giveup++))' USR1
while [[ ! -s r1 || ! -s r2 ]] (sleep 2; kill -s USR1 $$) &
do ((giveup)) && break while [[ ! -s r1 || ! -s r2 ]]
do ((giveup)) && break
done
if ((giveup))
then err_exit "Test 4: ( echo $RANDOM & ) does not write output"
fi
kill $! 2>/dev/null
trap - USR1
unset giveup
[[ $(<r1) != "$(<r2)" ]] && break
done done
if ((giveup)) [[ $(<r1) == "$(<r2)" ]] && err_exit "Test 4: \$RANDOM seed in ( simple_command & ) doesn't change" \
then err_exit "Test 4: ( echo $RANDOM & ) does not write output" "(both results are $(printf %q "$(<r1)"))"
else [[ $(<r1) == "$(<r2)" ]] && err_exit "Test 4: \$RANDOM seed in ( simple_command & ) doesn't change" \
"(both results are $(printf %q "$(<r1)"))"
fi
kill $! 2>/dev/null
trap - USR1
unset giveup
# Virtual subshells should not influence the parent shell's RANDOM sequence # Virtual subshells should not influence the parent shell's RANDOM sequence
RANDOM=456 RANDOM=456
exp="$RANDOM $RANDOM $RANDOM $RANDOM $RANDOM" exp="$RANDOM $RANDOM $RANDOM $RANDOM $RANDOM"
@ -85,6 +99,7 @@ do : $( : $RANDOM $RANDOM $RANDOM )
done done
[[ $got == "$exp" ]] || err_exit 'Using $RANDOM in subshell influences reproducible sequence in parent environment' \ [[ $got == "$exp" ]] || err_exit 'Using $RANDOM in subshell influences reproducible sequence in parent environment' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))" "(expected $(printf %q "$exp"), got $(printf %q "$got"))"
unset N i rand1 rand2
# SECONDS # SECONDS
float secElapsed=0.0 secSleep=0.001 float secElapsed=0.0 secSleep=0.001