xref: /freebsd/libexec/rc/tests/rc_subr_test.sh (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
1#-
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright 2022 Mateusz Piotrowski <0mp@FreeBSD.org>
5# Copyright (c) 2025 Klara, Inc.
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
29atf_test_case oomprotect_all
30oomprotect_all_head()
31{
32	atf_set "descr" "Verify that \${name}_oomprotect=all protects " \
33		"the command and all its current and future children"
34	atf_set "require.user" "root" # For protect(1).
35}
36
37oomprotect_all_body()
38{
39	if [ "$(sysctl -n security.jail.jailed)" != 0 ]; then
40		atf_skip "protect(1) cannot be used in a jail"
41	fi
42
43	__name="$(atf_get ident)"
44	__pidfile="$(mktemp -t "${__name}.pid")"
45	__childpidfile="$(mktemp -t "${__name}.childpid")"
46	__script=$(mktemp -t "${__name}.script")
47
48	cat >> "$__script" <<-'LITERAL'
49	. /etc/rc.subr
50	name="$1"
51	pidfile="$2"
52	_childpidfile="$3"
53	_rc_arg="$4"
54	setvar "${name}_oomprotect" all
55	command="/usr/sbin/daemon"
56	command_args="-P $pidfile -p $_childpidfile -- /bin/sleep 60"
57	run_rc_command "$_rc_arg"
58	LITERAL
59
60	atf_check -s exit:0 -o inline:"Starting ${__name}.\n" -e empty \
61		/bin/sh "$__script" "$__name" "$__pidfile" "$__childpidfile" onestart
62	atf_check -s exit:0 -o match:'^..1..... .......1$' -e empty \
63		ps -p "$(cat "$__pidfile")" -o flags,flags2
64	atf_check -s exit:0 -o match:'^..1..... .......1$' -e empty \
65		ps -p "$(cat "$__childpidfile")" -o flags,flags2
66	atf_check -s exit:0 -o ignore -e empty \
67		/bin/sh "$__script" "$__name" "$__pidfile" "$__childpidfile" onestop
68}
69
70atf_test_case oomprotect_yes
71oomprotect_yes_head()
72{
73	atf_set "descr" "Verify that \${name}_oomprotect=yes protects " \
74		"the command but not its children"
75	atf_set "require.user" "root" # For protect(1).
76}
77
78oomprotect_yes_body()
79{
80	if [ "$(sysctl -n security.jail.jailed)" != 0 ]; then
81		atf_skip "protect(1) cannot be used in a jail"
82	fi
83
84	__name="$(atf_get ident)"
85	__pidfile="$(mktemp -t "${__name}.pid")"
86	__script=$(mktemp -t "${__name}.script")
87
88	cat >> "$__script" <<-'LITERAL'
89	. /etc/rc.subr
90	name="$1"
91	pidfile="$2"
92	_rc_arg="$3"
93	setvar "${name}_oomprotect" yes
94	procname="/bin/sleep"
95	command="/usr/sbin/daemon"
96	command_args="-p $pidfile -- $procname 60"
97	run_rc_command "$_rc_arg"
98	LITERAL
99
100	atf_check -s exit:0 -o inline:"Starting ${__name}.\n" -e empty \
101		/bin/sh "$__script" "$__name" "$__pidfile" onestart
102	atf_check -s exit:0 -o match:'^..1..... .......0$' -e empty \
103		ps -p "$(cat "$__pidfile")" -ax -o flags,flags2
104	atf_check -s exit:0 -o ignore -e empty \
105		/bin/sh "$__script" "$__name" "$__pidfile" onestop
106}
107
108atf_test_case wait_for_pids_progress
109wait_for_pids_progress_head()
110{
111	atf_set "descr" "Verify that wait_for_pids prints progress updates"
112}
113wait_for_pids_progress_body()
114{
115	cat >>script <<'EOF'
116. /etc/rc.subr
117sleep 15 &
118a=$!
119sleep 10 &
120b=$!
121sleep 5 &
122c=$!
123wait_for_pids $a $b $c
124EOF
125	re="^Waiting for PIDS: [0-9]+ [0-9]+ [0-9]+"
126	re="${re}, [0-9]+ [0-9]+"
127	re="${re}, [0-9]+\.$"
128	atf_check -s exit:0 -o match:"${re}" /bin/sh script
129}
130
131atf_init_test_cases()
132{
133	atf_add_test_case oomprotect_all
134	atf_add_test_case oomprotect_yes
135	atf_add_test_case wait_for_pids_progress
136}
137