1 #!/bin/bash
2 #
3 # Copyright (C) 2008 Paul Armstrong. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1. Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
13 #
14 # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 # SUCH DAMAGE.
25
26 # Unit test for lockf(1)
27
28 ERROR=""
29 LOCK_FILE="`pwd`/test_lock"
30
31 err() {
32 echo "$@" >&2
33 ERROR="TRUE"
34 }
35
36 if [ ! -x lockf ]; then
37 echo "lockf doesn't exist or is not executable. Compile it?" >&2
38 exit 1
39 fi
40
41 lockf -t -f does_not_exist
42 if [ "$?" -ne 0 ]; then
43 err "lockf returned failure for a non-existant lock"
44 fi
45
46 # /devices is read-only for everyone
47 FAILED_WRITE="$(lockf -l -f /devices/test_lock 2>/dev/null)"
48 if [ -n "${FAILED_WRITE}" ]; then
49 err "lockf exited successfully on a failed lock creation"
50 kill "${FAILED_WRITE}"
51 fi
52
53 # all tests after here require this to succeed so it exists immediately on
54 # failure
55 LOCK_PID="$(lockf -l -f ${LOCK_FILE})"
56 if [ -z "${LOCK_PID}" ]; then
57 err "lockf didn't return a PID on lock creation"
58 exit 1
59 fi
60
61 lockf -l -f "${LOCK_FILE}"
62 if [ "$?" -eq 0 ]; then
63 err "lockf returned success for a locked file"
64 fi
65
66 lockf -t -f "${LOCK_FILE}"
67 if [ "$?" -eq 0 ]; then
68 err "lockf returned success for testing a locked file"
69 fi
70
71 lockf -u "${LOCK_PID}"
72 if [ "$?" -ne 0 ]; then
73 err "lockf failed to unlock ${LOCK_PID}"
74 fi
75 if [ -n "$(ps -eo pid | grep ${LOCK_PID})" ]; then
76 err "Failed to kill child ${LOCK_PID}"
77 fi
78
79 LOCK_PID=""
80
81 # Create a lock so we can test waiting on a lock creation
82 LOCK_PID="$(lockf -l -f ${LOCK_FILE})"
83 if [ -z "${LOCK_PID}" ]; then
84 err "lockf didn't return a PID on lock creation"
85 else
86 (sleep 2; kill ${LOCK_PID})&
87
88 LOCK_PID2="$(alarm 4 lockf -w -f ${LOCK_FILE})"
89 if [ -z "${LOCK_PID2}" ]; then
90 err "Failed to create a lock after a wait"
91 fi
92
93 lockf -u "${LOCK_PID2}"
94 if [ -n "$(ps -eo pid | grep ${LOCK_PID2})" ]; then
95 err "Failed to kill child ${LOCK_PID2}"
96 fi
97 fi
98
99 # Create a lock so we can test waiting on a lock creation
100 LOCK_PID3="$(lockf -l -f ${LOCK_FILE})"
101 if [ -z "${LOCK_PID3}" ]; then
102 err "lockf didn't return a PID on lock creation"
103 else
104 LOCK_PID4="$(alarm 2 lockf -w -f ${LOCK_FILE})"
105 if [ "$?" -eq 0 ]; then
106 err "alarm should have returned a failure"
107 fi
108 if [ -n "${LOCK_PID4}" ]; then
109 err "Says it created a lock when it should have been waiting"
110 fi
111
112 lockf -u "${LOCK_PID3}"
113 if [ -n "$(ps -eo pid | grep ${LOCK_PID3})" ]; then
114 err "Failed to kill child ${LOCK_PID3}"
115 fi
116 fi
117
118 if [ -f "${LOCK_FILE}" ]; then
119 rm -f "${LOCK_FILE}"
120 fi
121 if [ "${ERROR}" = "TRUE" ]; then
122 exit 1
123 else
124 exit 0
125 fi