Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Apr 2025 18:21:11 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: eeb2d4ffe95b - main - sysrc: Add some regressions tests
Message-ID:  <202504281821.53SILB7X093137@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=eeb2d4ffe95b4332811c14b56cfdf5fc6ea821b0

commit eeb2d4ffe95b4332811c14b56cfdf5fc6ea821b0
Author:     Michal Scigocki <michal.os@hotmail.com>
AuthorDate: 2025-04-14 07:00:07 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-04-28 18:18:08 +0000

    sysrc: Add some regressions tests
    
    Reviewed by:    markj
    MFC after:      1 month
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1664
---
 etc/mtree/BSD.tests.dist           |   2 +
 usr.sbin/sysrc/Makefile            |   5 +
 usr.sbin/sysrc/tests/Makefile      |   3 +
 usr.sbin/sysrc/tests/sysrc_test.sh | 351 +++++++++++++++++++++++++++++++++++++
 4 files changed, 361 insertions(+)

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 673452434080..22b9686fb761 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -1277,6 +1277,8 @@
         ..
         syslogd
         ..
+        sysrc
+        ..
     ..
 ..
 
diff --git a/usr.sbin/sysrc/Makefile b/usr.sbin/sysrc/Makefile
index 0f2f98e8b0e8..e1f48f2af97b 100644
--- a/usr.sbin/sysrc/Makefile
+++ b/usr.sbin/sysrc/Makefile
@@ -1,5 +1,10 @@
+.include <src.opts.mk>
+
 SCRIPTS= sysrc
 
 MAN= sysrc.8
 
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+=	tests
+
 .include <bsd.prog.mk>
diff --git a/usr.sbin/sysrc/tests/Makefile b/usr.sbin/sysrc/tests/Makefile
new file mode 100644
index 000000000000..8b4bad96f4cc
--- /dev/null
+++ b/usr.sbin/sysrc/tests/Makefile
@@ -0,0 +1,3 @@
+ATF_TESTS_SH+=	sysrc_test
+
+.include <bsd.test.mk>
diff --git a/usr.sbin/sysrc/tests/sysrc_test.sh b/usr.sbin/sysrc/tests/sysrc_test.sh
new file mode 100644
index 000000000000..fa79e6262c21
--- /dev/null
+++ b/usr.sbin/sysrc/tests/sysrc_test.sh
@@ -0,0 +1,351 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2025 Michal Scigocki <michal.os@hotmail.com>
+#
+
+readonly SYSRC_CONF="${PWD}/sysrc_test.conf"
+
+atf_test_case check_variable
+check_variable_head()
+{
+	atf_set "descr" "Check rc variable"
+}
+check_variable_body()
+{
+	cat <<- EOF > "${SYSRC_CONF}"
+		test_enable="NO"
+		test_list="item1 item2"
+		test2_list=""
+	EOF
+
+	atf_check -o inline:"test_enable: NO\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable
+	atf_check -o inline:"test2_list: \n" \
+	    sysrc -f "${SYSRC_CONF}" test2_list
+	atf_check -o inline:"test_enable: NO\ntest_list: item1 item2\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable test_list
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
+	    -s exit:1 sysrc -f "${SYSRC_CONF}" noexist
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
+	    -s exit:1 -o inline:"test_enable: NO\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable noexist
+}
+
+atf_test_case set_variable
+set_variable_head()
+{
+	atf_set "descr" "Set rc variable"
+}
+set_variable_body()
+{
+	# Previously unset variable
+	atf_check -o inline:"test_enable:  -> YES\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable=YES
+	atf_check -o inline:'test_enable="YES"\n' cat "${SYSRC_CONF}"
+	# Change set variable
+	atf_check -o inline:"test_enable: YES -> YES\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable=YES
+	atf_check -o inline:'test_enable="YES"\n' cat "${SYSRC_CONF}"
+	atf_check -o inline:"test_enable: YES -> NO\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable=NO
+	atf_check -o inline:'test_enable="NO"\n' cat "${SYSRC_CONF}"
+	# Set an empty variable
+	atf_check -o inline:"test2_enable:  -> \n" \
+	    sysrc -f "${SYSRC_CONF}" test2_enable=""
+	atf_check -o inline:'test_enable="NO"\ntest2_enable=""\n' \
+	    cat "${SYSRC_CONF}"
+}
+
+atf_test_case remove_variable_x_flag
+remove_variable_x_flag_head()
+{
+	atf_set "descr" "Remove rc variable (-x flag)"
+}
+remove_variable_x_flag_body()
+{
+	cat <<- EOF > "${SYSRC_CONF}"
+		test1_enable="YES"
+		test2_enable="NO"
+		test3_enable=""
+	EOF
+
+	atf_check sysrc -f "${SYSRC_CONF}" -x test1_enable
+	atf_check -o inline:'test2_enable="NO"\ntest3_enable=""\n' \
+	    cat "${SYSRC_CONF}"
+	atf_check sysrc -f "${SYSRC_CONF}" -x test2_enable test3_enable
+	atf_check -o empty cat "${SYSRC_CONF}"
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
+	    -s exit:1 sysrc -f "${SYSRC_CONF}" -x noexist
+}
+
+atf_test_case append_list
+append_list_head()
+{
+	atf_set "descr" "Append rc variable to list"
+}
+append_list_body()
+{
+	atf_check -o inline:"test_list:  -> item1\n" \
+	    sysrc -f "${SYSRC_CONF}" test_list+=item1
+	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
+	atf_check -o inline:"test_list: item1 -> item1\n" \
+	    sysrc -f "${SYSRC_CONF}" test_list+=item1
+	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
+	atf_check -o inline:"test_list: item1 -> item1 item2\n" \
+	    sysrc -f "${SYSRC_CONF}" test_list+=item2
+	atf_check -o inline:'test_list="item1 item2"\n' \
+	    cat "${SYSRC_CONF}"
+}
+
+atf_test_case subtract_list
+subtract_list_head()
+{
+	atf_set "descr" "Subtract rc variable from list"
+}
+subtract_list_body()
+{
+	echo 'test_list="item1 item2"' > "${SYSRC_CONF}"
+
+	atf_check -o inline:"test_list: item1 item2 -> item1\n" \
+	    sysrc -f "${SYSRC_CONF}" test_list-=item2
+	atf_check -o inline:'test_list="item1"\n' cat "${SYSRC_CONF}"
+	atf_check -o inline:"test_list: item1 -> \n" \
+	    sysrc -f "${SYSRC_CONF}" test_list-=item1
+	atf_check -o inline:'test_list=""\n' cat "${SYSRC_CONF}"
+	atf_check -o inline:"test_list:  -> \n" \
+	    sysrc -f "${SYSRC_CONF}" test_list-=item3
+	atf_check -o inline:'test_list=""\n' cat "${SYSRC_CONF}"
+
+	# Subtracting a non-existant rc variable results in an empty variable
+	# being created. This is by design, see sysrc(8).
+	atf_check -s exit:1 grep test2_list "${SYSRC_CONF}"
+	atf_check -o inline:"test2_list:  -> \n" \
+	    sysrc -f "${SYSRC_CONF}" test2_list-=item1
+	atf_check -o inline:'test_list=""\ntest2_list=""\n' \
+	    cat "${SYSRC_CONF}"
+}
+
+atf_test_case multiple_operations
+multiple_operations_head()
+{
+	atf_set "descr" "Check performing multiple operations on rc variables"
+}
+multiple_operations_body()
+{
+	atf_check -o inline:"test1_enable:  -> YES\ntest1_list:  -> item1\n" \
+	    sysrc -f "${SYSRC_CONF}" test1_enable=YES test1_list+=item1
+	atf_check -o inline:'test1_enable="YES"\ntest1_list="item1"\n' \
+	    cat "${SYSRC_CONF}"
+
+	# The trailing space on line "^test1_list:" is necessary.
+	cat <<- EOF > expected
+		test1_enable: YES
+		test1_enable: YES -> NO
+		test2_enable:  -> YES
+		test1_list: item1 -> 
+		test2_list:  -> item3
+	EOF
+	atf_check -s exit:1 -e inline:"sysrc: unknown variable 'noexist'\n" \
+	    -o file:expected sysrc -f "${SYSRC_CONF}" test1_enable \
+	    test1_enable=NO noexist test2_enable=YES test1_list-=item1 \
+	    test2_list+=item3
+
+	cat <<- EOF > expected
+		test1_enable="NO"
+		test1_list=""
+		test2_enable="YES"
+		test2_list="item3"
+	EOF
+	atf_check -o file:expected cat "${SYSRC_CONF}"
+}
+
+atf_test_case a_flag
+a_flag_head()
+{
+	atf_set "descr" "Verify -a behavior"
+}
+a_flag_body()
+{
+	echo 'test_enable="YES"' > "${SYSRC_CONF}"
+
+	atf_check -o inline:"test_enable: YES\n" sysrc -f "${SYSRC_CONF}" -a
+}
+
+atf_test_case A_flag cleanup
+A_flag_head()
+{
+	atf_set "descr" "Verify -A behavior"
+}
+A_flag_body()
+{
+	RC_DEFAULTS="${PWD}/rc_defaults.conf"
+	echo "rc_conf_files=\"${SYSRC_CONF}\"" > "${RC_DEFAULTS}"
+	echo 'test_enable="NO"' >> "${RC_DEFAULTS}"
+	echo 'test_enable="YES"' > "${SYSRC_CONF}"
+
+	export RC_DEFAULTS
+
+	# sysrc is coupled to the "source_rc_confs" sh(1) script function in
+	# /etc/defaults/rc.conf. For this test we use a custom default
+	# rc.conf file that is missing the "source_rc_confs" function, which
+	# causes sysrc to print an error message. While the coupling exists,
+	# we assume the error message is expected behaviour instead of just
+	# ignoring the stderr output to make sure we don't ignore other error
+	# messages in case of future regressions.
+	atf_check -e inline:"/usr/sbin/sysrc: source_rc_confs: not found\n" \
+	    -o inline:"rc_conf_files: ${SYSRC_CONF}\ntest_enable: NO\n" \
+	    sysrc -A
+	# Because "source_rc_confs" does not exist in our custom default
+	# rc.conf file, we cannot get sysrc to load the other SYSRC_CONF file
+	# to compare results. We can only verify that configuration variables
+	# get read from the RC_DEFAULTS file.
+}
+A_flag_cleanup()
+{
+	unset RC_DEFAULTS
+}
+
+atf_test_case c_flag
+c_flag_head()
+{
+	atf_set "descr" "Verify -c behavior"
+}
+c_flag_body()
+{
+	echo 'test_enable="NO"' > "${SYSRC_CONF}"
+	echo 'test_list="item1 item2"' >> "${SYSRC_CONF}"
+
+	# Test if rc variable is set
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_list
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable test_list
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
+	    -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n"\
+	    -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_enable noexist
+
+	cat <<- EOF > expected_err
+		sysrc: unknown variable 'noexist1'
+		sysrc: unknown variable 'noexist2'
+	EOF
+	atf_check -e file:expected_err -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c noexist1 noexist2
+
+	# Test rc variable assignment
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_enable=YES
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist=YES
+
+	# Test appending rc variables
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_list+=item1
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_list+=item3
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist+=item1
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list+=item1
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list+=item1
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list+=item3
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list+=item3
+
+	# Test subracting rc variables
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_list-=item3
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c test_list-=item1
+	atf_check -s exit:1 sysrc -f "${SYSRC_CONF}" -c noexist-=item1
+	atf_check sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list-=item3
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list-=item3
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=NO test_list-=item1
+	atf_check -s exit:1 \
+	    sysrc -f "${SYSRC_CONF}" -c test_enable=YES test_list-=item1
+}
+
+atf_test_case d_flag cleanup
+d_flag_head()
+{
+	atf_set "descr" "Verify -f behavior"
+}
+d_flag_body()
+{
+	echo 'test_enable="NO" # Test Description' > "${SYSRC_CONF}"
+
+	export RC_DEFAULTS="${SYSRC_CONF}"
+
+	atf_check -o inline:'test_enable: Test Description\n' \
+	    sysrc -d test_enable
+}
+d_flag_cleanup()
+{
+	unset RC_DEFAULTS
+}
+
+atf_test_case f_flag
+f_flag_head()
+{
+	atf_set "descr" "Verify -f behavior"
+}
+f_flag_body()
+{
+	local sysrc2_conf="${PWD}/sysrc2.conf"
+	echo 'test_list="item1"' > "${sysrc2_conf}"
+	echo 'test_enable="NO"' >> "${sysrc2_conf}"
+
+	atf_check test ! -f "${SYSRC_CONF}"
+	atf_check -e inline:"sysrc: unknown variable 'noexist'\n" \
+	    -s exit:1 sysrc -f "${SYSRC_CONF}" noexist
+	atf_check test ! -f "${SYSRC_CONF}"
+	atf_check -o inline:"test_enable:  -> YES\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable=YES
+	atf_check test -f "${SYSRC_CONF}"
+	atf_check -o inline:"test_enable: YES\n" \
+	    sysrc -f "${SYSRC_CONF}" test_enable
+	# -f file order impacts final settings
+	atf_check -o inline:"test_enable: YES\n" \
+	    sysrc -f "${sysrc2_conf}" -f "${SYSRC_CONF}" test_enable
+	atf_check -o inline:"test_enable: NO\n" \
+	    sysrc -f "${SYSRC_CONF}" -f "${sysrc2_conf}" test_enable
+	atf_check -o inline:"test_enable: YES\ntest_list: item1\n" \
+	    sysrc -f "${sysrc2_conf}" -f "${SYSRC_CONF}" -a
+}
+
+atf_test_case F_flag
+F_flag_head()
+{
+	atf_set "descr" "Verify -F behavior"
+}
+F_flag_body()
+{
+	local sysrc2_conf="${PWD}/sysrc2.conf"
+	echo 'test_list="item1"' > "${sysrc2_conf}"
+	echo 'test_enable="NO"' > "${SYSRC_CONF}"
+
+	atf_check -o inline:"test_enable: ${SYSRC_CONF}\n" \
+	    sysrc -f "${SYSRC_CONF}" -F test_enable
+	atf_check -o inline:"test_list: ${sysrc2_conf}\n" \
+	    sysrc -f "${sysrc2_conf}" -F test_list
+
+	cat <<- EOF > expected
+		test_enable: ${SYSRC_CONF}
+		test_list: ${sysrc2_conf}
+	EOF
+	atf_check -o file:expected sysrc -f "${SYSRC_CONF}" \
+	    -f ${sysrc2_conf} -F test_enable test_list
+}
+
+atf_init_test_cases()
+{
+	atf_add_test_case check_variable
+	atf_add_test_case set_variable
+	atf_add_test_case remove_variable_x_flag
+	atf_add_test_case append_list
+	atf_add_test_case subtract_list
+	atf_add_test_case multiple_operations
+	atf_add_test_case a_flag
+	atf_add_test_case A_flag
+	atf_add_test_case c_flag
+	atf_add_test_case d_flag
+	atf_add_test_case f_flag
+	atf_add_test_case F_flag
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504281821.53SILB7X093137>