]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/daemon/tests/daemon_test.sh
bsddialog: import snapshot 2021-12-05
[FreeBSD/FreeBSD.git] / usr.sbin / daemon / tests / daemon_test.sh
1 #!/bin/sh
2 #
3 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 #
5 # Copyright (c) 2021 Axcient
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27
28 # $FreeBSD$
29
30 atf_test_case both_pidfile cleanup
31 both_pidfile_head() {
32         atf_set "descr" "daemon should write pid files for itself and its child"
33 }
34 both_pidfile_body() {
35         daemon -P daemon.pid -p sleep.pid sleep 300
36         atf_check -s exit:0 test -f daemon.pid
37         atf_check -s exit:0 -o match:"daemon: sleep" ps -p `cat daemon.pid`
38         atf_check -s exit:0 test -f sleep.pid
39         atf_check -s exit:0 -o match:"[0-9] sleep 300$" ps -p `cat sleep.pid`
40 }
41 both_pidfile_cleanup() {
42         if [ -f daemon.pid ]; then
43                 daemon_pid=`cat daemon.pid`
44         fi
45         if [ -f sleep_pid ]; then
46                 sleep_pid=`cat sleep.pid`
47         fi
48         [ -n "$sleep_pid" ] && kill $sleep_pid
49         # NB: killing the sleep should kill the daemon too, so we musn't fail
50         # the test if the second kill fails with ESRCH
51         [ -n "$daemon_pid" ] && kill $daemon_pid || true
52 }
53
54 atf_test_case chdir cleanup
55 chdir_head() {
56         atf_set "descr" "daemon should chdir to /"
57 }
58 chdir_body() {
59         # Executing sleep by relative path will only work from /
60         daemon -p ${PWD}/sleep.pid -c bin/sleep 300
61         atf_check -s exit:0 test -f sleep.pid
62         atf_check -s exit:0 -o match:"[0-9] bin/sleep 300$" \
63                 ps -p `cat sleep.pid`
64 }
65 chdir_cleanup() {
66         [ -f sleep.pid ] && kill `cat sleep.pid`
67 }
68
69 atf_test_case child_pidfile cleanup
70 child_pidfile_head() {
71         atf_set "descr" "daemon should write its child's pid to a pidfile"
72 }
73 child_pidfile_body() {
74         daemon -p sleep.pid sleep 300
75         atf_check -s exit:0 test -f sleep.pid
76         atf_check -s exit:0 -o match:"[0-9] sleep 300$" ps -p `cat sleep.pid`
77 }
78 child_pidfile_cleanup() {
79         [ -f sleep.pid ] && kill `cat sleep.pid`
80 }
81
82 atf_test_case child_pidfile_lock cleanup
83 child_pidfile_lock_head() {
84         atf_set "descr" "daemon should refuse to clobber an existing child"
85 }
86 child_pidfile_lock_body() {
87         daemon -p sleep.pid sleep 300
88         atf_check -s exit:0 test -f sleep.pid
89         atf_check -s not-exit:0 -e match:"process already running" \
90                 daemon -p sleep.pid sleep 300
91 }
92 child_pidfile_lock_cleanup() {
93         [ -f sleep.pid ] && kill `cat sleep.pid`
94 }
95
96 atf_test_case newsyslog cleanup
97 newsyslog_head() {
98         atf_set "descr" "daemon should close and reopen the output file on SIGHUP"
99 }
100 newsyslog_body() {
101         cat > child.sh <<HERE
102 #! /bin/sh
103 while true ; do
104         echo "my output"
105         sleep 0.1
106 done
107 HERE
108         chmod +x child.sh
109         daemon -P daemon.pid -H -o output_file ./child.sh
110         atf_check -s exit:0 test -f daemon.pid
111         sleep 0.2
112         mv output_file output_file.0
113         kill -HUP `cat daemon.pid`
114         sleep 0.2
115         atf_check -s exit:0 test -s output_file.0
116         atf_check -s exit:0 test -s output_file
117 }
118 newsyslog_cleanup() {
119         [ -f daemon.pid ] && kill `cat daemon.pid`
120 }
121
122 atf_test_case output_file
123 output_file_head() {
124         atf_set "descr" "daemon should redirect stdout to a file"
125 }
126 output_file_body() {
127         daemon -o output_file seq 1 5
128         seq 1 5 > expected_file
129         atf_check -s exit:0 cmp output_file expected_file
130 }
131
132 atf_test_case restart_child cleanup
133 restart_child_head() {
134         atf_set "descr" "daemon should restart a dead child"
135 }
136 restart_child_body() {
137         daemon -rP daemon.pid -p sleep.pid sleep 300
138         atf_check -s exit:0 test -f daemon.pid
139         atf_check -s exit:0 test -f sleep.pid
140         orig_sleep_pid=`cat sleep.pid`
141         kill $orig_sleep_pid
142         # Wait up to 10s for the daemon to restart the child.
143         for t in `seq 0 0.1 10`; do
144                 new_sleep_pid=`cat sleep.pid`
145                 [ "$orig_sleep_pid" -ne "$new_sleep_pid" ] && break
146                 sleep 0.1
147         done
148         [ "$orig_sleep_pid" -ne "$new_sleep_pid" ] || \
149                 atf_fail "child was not restarted"
150
151 }
152 restart_child_cleanup() {
153         [ -f daemon.pid ] && kill `cat daemon.pid`
154 }
155
156 atf_test_case supervisor_pidfile cleanup
157 supervisor_pidfile_head() {
158         atf_set "descr" "daemon should write its own pid to a pidfile"
159 }
160 supervisor_pidfile_body() {
161         daemon -P daemon.pid sleep 300
162         atf_check -s exit:0 test -f daemon.pid
163         atf_check -s exit:0 -o match:"daemon: sleep" ps -p `cat daemon.pid`
164 }
165 supervisor_pidfile_cleanup() {
166         [ -f daemon.pid ] && kill `cat daemon.pid`
167 }
168
169 atf_test_case supervisor_pidfile_lock cleanup
170 supervisor_pidfile_lock_head() {
171         atf_set "descr" "daemon should refuse to clobber an existing instance"
172 }
173 supervisor_pidfile_lock_body() {
174         daemon -P daemon.pid sleep 300
175         atf_check -s exit:0 test -f daemon.pid
176         atf_check -s not-exit:0 -e match:"process already running" \
177                 daemon -p daemon.pid sleep 300
178 }
179 supervisor_pidfile_lock_cleanup() {
180         [ -f daemon.pid ] && kill `cat daemon.pid`
181 }
182
183 atf_test_case title cleanup
184 title_head() {
185         atf_set "descr" "daemon should change its process title"
186 }
187 title_body() {
188         daemon -P daemon.pid -t "I'm a title!" sleep 300
189         atf_check -s exit:0 test -f daemon.pid
190         atf_check -s exit:0 -o match:"daemon: I'm a title!" \
191                 ps -p `cat daemon.pid`
192 }
193 title_cleanup() {
194         [ -f daemon.pid ] && kill `cat daemon.pid`
195 }
196
197 atf_test_case user cleanup
198 user_head() {
199         atf_set "descr" "daemon should drop privileges"
200         atf_set "require.user" "root"
201 }
202 user_body() {
203         daemon -p sleep.pid -u nobody sleep 300
204         atf_check -s exit:0 test -f sleep.pid
205         atf_check -s exit:0 -o match:"^nobody" ps -up `cat sleep.pid`
206 }
207 user_cleanup() {
208         [ -f sleep.pid ] && kill `cat sleep.pid`
209 }
210
211
212 atf_init_test_cases() {
213         atf_add_test_case both_pidfile
214         atf_add_test_case chdir
215         atf_add_test_case child_pidfile
216         atf_add_test_case child_pidfile_lock
217         atf_add_test_case newsyslog
218         atf_add_test_case output_file
219         atf_add_test_case restart_child
220         atf_add_test_case supervisor_pidfile
221         atf_add_test_case supervisor_pidfile_lock
222         atf_add_test_case title
223         atf_add_test_case user
224 }