diff options
Diffstat (limited to 'tests/ts/misc/flock')
-rwxr-xr-x | tests/ts/misc/flock | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/ts/misc/flock b/tests/ts/misc/flock new file mode 100755 index 0000000..0c6ac0b --- /dev/null +++ b/tests/ts/misc/flock @@ -0,0 +1,124 @@ +#!/bin/bash + +# This file is part of util-linux. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +TS_TOPDIR="${0%/*}/../.." +TS_DESC="flock" + +. "$TS_TOPDIR"/functions.sh +ts_init "$*" + +ts_check_test_command "$TS_CMD_FLOCK" +ts_check_prog "pgrep" +ts_check_prog "timeout" + + +function do_lock { + local opts="$1" + local expected_rc="$2" + local mesg="$3" + + $TS_CMD_FLOCK $1 $TS_OUTDIR/lockfile \ + echo "$mesg" \ + >> $TS_OUTPUT 2>> $TS_ERRLOG + + local rc="$?" + + if [ "$rc" == "$expected_rc" ]; then + ts_log "Success" + else + ts_log "Failed [rc=$rc]" + fi +} + +# general lock +GEN_OUTPUT="$TS_OUTPUT" +START=$(date '+%s') +# running flock in background is not the best usage example +$TS_CMD_FLOCK --shared $TS_OUTDIR/lockfile \ + bash -c 'echo "Locking"; sleep 3; echo "Unlocking"' \ + > $GEN_OUTPUT 2>&1 & +pid=$! + +# check for running background process +if [ "$pid" -le "0" ] || ! kill -s 0 "$pid" &>/dev/null; then + ts_die "unable to run flock" +fi +# the lock should be established when flock has a child +timeout 1s bash -c "while ! pgrep -P $pid >/dev/null; do sleep 0.1 ;done" \ + || ts_die "timeout waiting for flock child" + +ts_init_subtest "non-block" +do_lock "--nonblock --conflict-exit-code 123" 123 "You will never see this!" +ts_finalize_subtest + + +ts_init_subtest "no-fork" +do_lock "--no-fork --nonblock --conflict-exit-code 123" 123 "You will never see this!" +ts_finalize_subtest + + +ts_init_subtest "shared" +do_lock "--shared" 0 "Have shared lock" +ts_finalize_subtest + + +# this is the same as non-block test (exclusive lock is the default), but here +# we explicitly specify --exclusive on command line +ts_init_subtest "exclusive" +do_lock "--nonblock --exclusive --conflict-exit-code 123" 123 "You will never see this!" +ts_finalize_subtest + + +ts_init_subtest "fd" +cd "$TS_OUTDIR" +rm 4 2> /dev/null +exec 4<>$TS_OUTDIR/lockfile || ts_log "Could not open lockfile" +$TS_CMD_FLOCK --nonblock --exclusive --conflict-exit-code 123 4 \ + >> $TS_OUTPUT 2>> $TS_ERRLOG + +rc="$?" + +if [ "$rc" == "123" ]; then + ts_log "Success" +else + ts_log "Failed [rc=$rc]" +fi +[ -f 4 ] && ts_log "fd file should not exist" +ts_finalize_subtest + + +ts_init_subtest "timeout" +do_lock "--timeout 5 --conflict-exit-code 5" 0 "After timeout." +END=$(date '+%s') +ts_finalize_subtest + + +# expected is 3 seconds (see "sleep 3" for the general lock), but we should not +# rely on exact number due to scheduler, machine load, etc. Let's check for +# inmterval <3,5>. +# +ts_init_subtest "time-check" +TIMEDIFF=$(( $END - $START )) +if [ $TIMEDIFF -lt 3 ]; then + ts_log "general lock failed [$TIMEDIFF sec]" +elif [ $TIMEDIFF -gt 5 ]; then + ts_log "wait too long [$TIMEDIFF sec]" +else + ts_log "success" +fi +ts_finalize_subtest "diff ${TIMEDIFF} sec" + + +echo "Unlocked" >> $GEN_OUTPUT +ts_finalize |