xref: /freebsd/usr.sbin/sysrc/tests/sysrc_test.sh (revision b5daf675efc746611c7cfcd1fa474b8905064c4b)
1#-
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2025 Michal Scigocki <michal.os@hotmail.com>
5#
6
7readonly SYSRC_CONF="${PWD}/sysrc_test.conf"
8
9atf_test_case check_variable
10check_variable_head()
11{
12	atf_set "descr" "Check rc variable"
13}
14check_variable_body()
15{
16	cat <<- EOF > "${SYSRC_CONF}"
17		test_enable="NO"
18		test_list="item1 item2"
19		test2_list=""
20	EOF
21
22	atf_check -o inline:"test_enable: NO\n" \
23	    sysrc -f "${SYSRC_CONF}" test_enable
24	atf_check -o inline:"test2_list: \n" \
25	    sysrc -f "${SYSRC_CONF}" test2_list
26	atf_check -o inline:"test_enable: NO\ntest_list: item1 item2\n" \
27	    sysrc -f "${SYSRC_CONF}" test_enable test_list
28	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
29	    -s exit:1 sysrc -f "${SYSRC_CONF}" noexist
30	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
31	    -s exit:1 -o inline:"test_enable: NO\n" \
32	    sysrc -f "${SYSRC_CONF}" test_enable noexist
33}
34
35atf_test_case set_variable
36set_variable_head()
37{
38	atf_set "descr" "Set rc variable"
39}
40set_variable_body()
41{
42	# Previously unset variable
43	atf_check -o inline:"test_enable:  -> YES\n" \
44	    sysrc -f "${SYSRC_CONF}" test_enable=YES
45	atf_check -o inline:'test_enable="YES"\n' cat "${SYSRC_CONF}"
46	# Change set variable
47	atf_check -o inline:"test_enable: YES -> YES\n" \
48	    sysrc -f "${SYSRC_CONF}" test_enable=YES
49	atf_check -o inline:'test_enable="YES"\n' cat "${SYSRC_CONF}"
50	atf_check -o inline:"test_enable: YES -> NO\n" \
51	    sysrc -f "${SYSRC_CONF}" test_enable=NO
52	atf_check -o inline:'test_enable="NO"\n' cat "${SYSRC_CONF}"
53	# Set an empty variable
54	atf_check -o inline:"test2_enable:  -> \n" \
55	    sysrc -f "${SYSRC_CONF}" test2_enable=""
56	atf_check -o inline:'test_enable="NO"\ntest2_enable=""\n' \
57	    cat "${SYSRC_CONF}"
58}
59
60atf_test_case remove_variable_x_flag
61remove_variable_x_flag_head()
62{
63	atf_set "descr" "Remove rc variable (-x flag)"
64}
65remove_variable_x_flag_body()
66{
67	cat <<- EOF > "${SYSRC_CONF}"
68		test1_enable="YES"
69		test2_enable="NO"
70		test3_enable=""
71	EOF
72
73	atf_check sysrc -f "${SYSRC_CONF}" -x test1_enable
74	atf_check -o inline:'test2_enable="NO"\ntest3_enable=""\n' \
75	    cat "${SYSRC_CONF}"
76	atf_check sysrc -f "${SYSRC_CONF}" -x test2_enable test3_enable
77	atf_check -o empty cat "${SYSRC_CONF}"
78	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
79	    -s exit:1 sysrc -f "${SYSRC_CONF}" -x noexist
80}
81
82atf_test_case append_list
83append_list_head()
84{
85	atf_set "descr" "Append rc variable to list"
86}
87append_list_body()
88{
89	atf_check -o inline:"test_list:  -> item1\n" \
90	    sysrc -f "${SYSRC_CONF}" test_list+=item1
91	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
92	atf_check -o inline:"test_list: item1 -> item1\n" \
93	    sysrc -f "${SYSRC_CONF}" test_list+=item1
94	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
95	atf_check -o inline:"test_list: item1 -> item1 item2\n" \
96	    sysrc -f "${SYSRC_CONF}" test_list+=item2
97	atf_check -o inline:'test_list="item1 item2"\n' \
98	    cat "${SYSRC_CONF}"
99}
100
101atf_test_case subtract_list
102subtract_list_head()
103{
104	atf_set "descr" "Subtract rc variable from list"
105}
106subtract_list_body()
107{
108	echo 'test_list="item1 item2"' > "${SYSRC_CONF}"
109
110	atf_check -o inline:"test_list: item1 item2 -> item1\n" \
111	    sysrc -f "${SYSRC_CONF}" test_list-=item2
112	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
113	atf_check -o inline:"test_list: item1 -> \n" \
114	    sysrc -f "${SYSRC_CONF}" test_list-=item1
115	atf_check -o inline:'test_list=""\n' cat "${SYSRC_CONF}"
116	atf_check -o inline:"test_list:  -> \n" \
117	    sysrc -f "${SYSRC_CONF}" test_list-=item3
118	atf_check -o inline:'test_list=""\n' cat "${SYSRC_CONF}"
119
120	# Subtracting a non-existant rc variable results in an empty variable
121	# being created. This is by design, see sysrc(8).
122	atf_check -s exit:1 grep test2_list "${SYSRC_CONF}"
123	atf_check -o inline:"test2_list:  -> \n" \
124	    sysrc -f "${SYSRC_CONF}" test2_list-=item1
125	atf_check -o inline:'test_list=""\ntest2_list=""\n' \
126	    cat "${SYSRC_CONF}"
127}
128
129atf_test_case multiple_operations
130multiple_operations_head()
131{
132	atf_set "descr" "Check performing multiple operations on rc variables"
133}
134multiple_operations_body()
135{
136	atf_check -o inline:"test1_enable:  -> YES\ntest1_list:  -> item1\n" \
137	    sysrc -f "${SYSRC_CONF}" test1_enable=YES test1_list+=item1
138	atf_check -o inline:'test1_enable="YES"\ntest1_list="item1"\n' \
139	    cat "${SYSRC_CONF}"
140
141	# The trailing space on line "^test1_list:" is necessary.
142	cat <<- EOF > expected
143		test1_enable: YES
144		test1_enable: YES -> NO
145		test2_enable:  -> YES
146		test1_list: item1 -> 
147		test2_list:  -> item3
148	EOF
149	atf_check -s exit:1 -e inline:"sysrc: unknown variable 'noexist'\n" \
150	    -o file:expected sysrc -f "${SYSRC_CONF}" test1_enable \
151	    test1_enable=NO noexist test2_enable=YES test1_list-=item1 \
152	    test2_list+=item3
153
154	cat <<- EOF > expected
155		test1_enable="NO"
156		test1_list=""
157		test2_enable="YES"
158		test2_list="item3"
159	EOF
160	atf_check -o file:expected cat "${SYSRC_CONF}"
161}
162
163atf_test_case a_flag
164a_flag_head()
165{
166	atf_set "descr" "Verify -a behavior"
167}
168a_flag_body()
169{
170	echo 'test_enable="YES"' > "${SYSRC_CONF}"
171
172	atf_check -o inline:"test_enable: YES\n" sysrc -f "${SYSRC_CONF}" -a
173}
174
175atf_test_case A_flag cleanup
176A_flag_head()
177{
178	atf_set "descr" "Verify -A behavior"
179}
180A_flag_body()
181{
182	RC_DEFAULTS="${PWD}/rc_defaults.conf"
183	echo "rc_conf_files=\"${SYSRC_CONF}\"" > "${RC_DEFAULTS}"
184	echo 'test_enable="NO"' >> "${RC_DEFAULTS}"
185	echo 'test_enable="YES"' > "${SYSRC_CONF}"
186
187	export RC_DEFAULTS
188
189	# sysrc is coupled to the "source_rc_confs" sh(1) script function in
190	# /etc/defaults/rc.conf. For this test we use a custom default
191	# rc.conf file that is missing the "source_rc_confs" function, which
192	# causes sysrc to print an error message. While the coupling exists,
193	# we assume the error message is expected behaviour instead of just
194	# ignoring the stderr output to make sure we don't ignore other error
195	# messages in case of future regressions.
196	atf_check -e inline:"/usr/sbin/sysrc: source_rc_confs: not found\n" \
197	    -o inline:"rc_conf_files: ${SYSRC_CONF}\ntest_enable: NO\n" \
198	    sysrc -A
199	# Because "source_rc_confs" does not exist in our custom default
200	# rc.conf file, we cannot get sysrc to load the other SYSRC_CONF file
201	# to compare results. We can only verify that configuration variables
202	# get read from the RC_DEFAULTS file.
203}
204A_flag_cleanup()
205{
206	unset RC_DEFAULTS
207}
208
209atf_test_case c_flag
210c_flag_head()
211{
212	atf_set "descr" "Verify -c behavior"
213}
214c_flag_body()
215{
216	echo 'test_enable="NO"' > "${SYSRC_CONF}"
217	echo 'test_list="item1 item2"' >> "${SYSRC_CONF}"
218
219	# Test if rc variable is set
220	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable
221	atf_check sysrc -f "${SYSRC_CONF}" -c test_list
222	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable test_list
223	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
224	    -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist
225	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
226	    -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_enable noexist
227
228	cat <<- EOF > expected_err
229		sysrc: unknown variable 'noexist1'
230		sysrc: unknown variable 'noexist2'
231	EOF
232	atf_check -e file:expected_err -s exit:1 \
233	    sysrc -f "${SYSRC_CONF}" -c noexist1 noexist2
234
235	# Test rc variable assignment
236	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO
237	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_enable=YES
238	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist=YES
239
240	# Test appending rc variables
241	atf_check sysrc -f "${SYSRC_CONF}" -c test_list+=item1
242	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_list+=item3
243	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist+=item1
244	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list+=item1
245	atf_check -s exit:1 \
246	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list+=item1
247	atf_check -s exit:1 \
248	    sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list+=item3
249	atf_check -s exit:1 \
250	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list+=item3
251
252	# Test subracting rc variables
253	atf_check sysrc -f "${SYSRC_CONF}" -c test_list-=item3
254	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_list-=item1
255	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist-=item1
256	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list-=item3
257	atf_check -s exit:1 \
258	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list-=item3
259	atf_check -s exit:1 \
260	    sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list-=item1
261	atf_check -s exit:1 \
262	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list-=item1
263}
264
265atf_test_case d_flag cleanup
266d_flag_head()
267{
268	atf_set "descr" "Verify -f behavior"
269}
270d_flag_body()
271{
272	echo 'test_enable="NO" # Test Description' > "${SYSRC_CONF}"
273
274	export RC_DEFAULTS="${SYSRC_CONF}"
275
276	atf_check -o inline:'test_enable: Test Description\n' \
277	    sysrc -d test_enable
278}
279d_flag_cleanup()
280{
281	unset RC_DEFAULTS
282}
283
284atf_test_case f_flag
285f_flag_head()
286{
287	atf_set "descr" "Verify -f behavior"
288}
289f_flag_body()
290{
291	local sysrc2_conf="${PWD}/sysrc2.conf"
292	echo 'test_list="item1"' > "${sysrc2_conf}"
293	echo 'test_enable="NO"' >> "${sysrc2_conf}"
294
295	atf_check test ! -f "${SYSRC_CONF}"
296	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
297	    -s exit:1 sysrc -f "${SYSRC_CONF}" noexist
298	atf_check test ! -f "${SYSRC_CONF}"
299	atf_check -o inline:"test_enable:  -> YES\n" \
300	    sysrc -f "${SYSRC_CONF}" test_enable=YES
301	atf_check test -f "${SYSRC_CONF}"
302	atf_check -o inline:"test_enable: YES\n" \
303	    sysrc -f "${SYSRC_CONF}" test_enable
304	# -f file order impacts final settings
305	atf_check -o inline:"test_enable: YES\n" \
306	    sysrc -f "${sysrc2_conf}" -f "${SYSRC_CONF}" test_enable
307	atf_check -o inline:"test_enable: NO\n" \
308	    sysrc -f "${SYSRC_CONF}" -f "${sysrc2_conf}" test_enable
309	atf_check -o inline:"test_enable: YES\ntest_list: item1\n" \
310	    sysrc -f "${sysrc2_conf}" -f "${SYSRC_CONF}" -a
311}
312
313atf_test_case F_flag
314F_flag_head()
315{
316	atf_set "descr" "Verify -F behavior"
317}
318F_flag_body()
319{
320	local sysrc2_conf="${PWD}/sysrc2.conf"
321	echo 'test_list="item1"' > "${sysrc2_conf}"
322	echo 'test_enable="NO"' > "${SYSRC_CONF}"
323
324	atf_check -o inline:"test_enable: ${SYSRC_CONF}\n" \
325	    sysrc -f "${SYSRC_CONF}" -F test_enable
326	atf_check -o inline:"test_list: ${sysrc2_conf}\n" \
327	    sysrc -f "${sysrc2_conf}" -F test_list
328
329	cat <<- EOF > expected
330		test_enable: ${SYSRC_CONF}
331		test_list: ${sysrc2_conf}
332	EOF
333	atf_check -o file:expected sysrc -f "${SYSRC_CONF}" \
334	    -f ${sysrc2_conf} -F test_enable test_list
335}
336
337atf_init_test_cases()
338{
339	atf_add_test_case check_variable
340	atf_add_test_case set_variable
341	atf_add_test_case remove_variable_x_flag
342	atf_add_test_case append_list
343	atf_add_test_case subtract_list
344	atf_add_test_case multiple_operations
345	atf_add_test_case a_flag
346	atf_add_test_case A_flag
347	atf_add_test_case c_flag
348	atf_add_test_case d_flag
349	atf_add_test_case f_flag
350	atf_add_test_case F_flag
351}
352