xref: /freebsd/usr.bin/lockf/tests/lockf_test.sh (revision 296a5a4db1fc8203f5f6aa8f68321e6ab4652b56)
1#
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2023 Klara, Inc.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27
28# sysexits(3)
29: ${EX_USAGE:=64}
30: ${EX_UNAVAILABLE:=69}
31: ${EX_CANTCREAT:=73}
32: ${EX_TEMPFAIL:=75}
33
34atf_test_case badargs
35badargs_body()
36{
37	atf_check -s exit:${EX_USAGE} -e not-empty lockf
38	atf_check -s exit:${EX_USAGE} -e not-empty lockf "testlock"
39}
40
41atf_test_case basic
42basic_body()
43{
44	# Something innocent so that it does eventually go away without our
45	# intervention.
46	lockf "testlock" sleep 10 &
47	lpid=$!
48
49	# Make sure that the lock exists...
50	atf_check test -e "testlock"
51
52	# Attempt both verbose and silent re-lock
53	atf_check -s exit:${EX_TEMPFAIL} -e not-empty \
54	    lockf -t 0 "testlock" sleep 0
55	atf_check -s exit:${EX_TEMPFAIL} -e empty \
56	    lockf -t 0 -s "testlock" sleep 0
57
58	# Make sure it cleans up after the initial sleep 10 is over.
59	wait "$lpid"
60	atf_check test ! -e "testlock"
61}
62
63atf_test_case keep
64keep_body()
65{
66	lockf -k "testlock" sleep 10 &
67	lpid=$!
68
69	# Make sure that the lock exists now...
70	while ! test -e "testlock"; do
71		sleep 0.5
72	done
73
74	kill "$lpid"
75	wait "$lpid"
76
77	# And it still exits after the lock has been relinquished.
78	atf_check test -e "testlock"
79}
80
81atf_test_case needfile
82needfile_body()
83{
84	# Hopefully the clock doesn't jump.
85	start=$(date +"%s")
86
87	# Should fail if the lockfile does not yet exist.
88	atf_check -s exit:"${EX_UNAVAILABLE}" lockf -sn "testlock" sleep 30
89
90	# It's hard to guess how quickly we should have finished that; one would
91	# hope that it exits fast, but to be safe we specified a sleep 30 under
92	# lock so that we have a good margin below that duration that we can
93	# safely test to make sure we didn't actually execute the program, more
94	# or less.
95	now=$(date +"%s")
96	tpass=$((now - start))
97	atf_check test "$tpass" -lt 10
98}
99
100atf_test_case timeout
101timeout_body()
102{
103	lockf "testlock" sleep 30 &
104	lpid=$!
105
106	while ! test -e "testlock"; do
107		sleep 0.5
108	done
109
110	start=$(date +"%s")
111	timeout=2
112	atf_check -s exit:${EX_TEMPFAIL} lockf -st "$timeout" "testlock" sleep 0
113
114	# We should have taken no less than our timeout, at least.
115	now=$(date +"%s")
116	tpass=$((now - start))
117	atf_check test "$tpass" -ge "$timeout"
118
119	kill "$lpid"
120	wait "$lpid" || true
121}
122
123atf_test_case wrlock
124wrlock_head()
125{
126	atf_set "require.user" "unprivileged"
127}
128wrlock_body()
129{
130	touch "testlock"
131	chmod -w "testlock"
132
133	# Demonstrate that we can lock the file normally, but -w fails if we
134	# can't write.
135	atf_check lockf -kt 0 "testlock" sleep 0
136	atf_check -s exit:${EX_CANTCREAT} -e not-empty \
137	    lockf -wt 0 "testlock" sleep 0
138}
139
140atf_init_test_cases()
141{
142	atf_add_test_case badargs
143	atf_add_test_case basic
144	atf_add_test_case keep
145	atf_add_test_case needfile
146	atf_add_test_case timeout
147	atf_add_test_case wrlock
148}
149