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 @@ -1,1283 +1,1285 @@ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 tags=package=tests . atf_python sys net .. netlink .. netpfil ipfw .. .. .. .. bin cat .. chflags .. chmod .. cp .. date .. dd .. echo .. expr .. hostname .. ln .. ls .. mkdir .. mv .. pax .. pkill .. pwait .. rm .. rmdir .. sh builtins .. errors .. execution .. expansion .. invocation .. parameters .. parser .. set-e .. .. sleep .. test .. timeout .. .. cddl lib .. sbin .. usr.bin ctfconvert .. ztest .. .. usr.sbin dtrace amd64 arrays .. .. common aggs .. arithmetic .. arrays .. assocs .. begin .. bitfields .. buffering .. builtinvar .. cg .. clauses .. cpc .. decls .. drops .. dtraceUtil .. end .. enum .. env .. error .. exit .. fbtprovider .. funcs .. grammar .. include .. inline .. io .. ip .. java_api .. json .. kinst .. lexer .. llquantize .. mdb .. mib .. misc .. multiaggs .. offsetof .. oformat .. operators .. pid .. plockstat .. pointers .. pragma .. predicates .. preprocessor .. print .. printa .. printf .. privs .. probes .. proc .. profile-n .. providers .. raise .. rates .. safety .. scalars .. sched .. scripting .. sdt .. sizeof .. speculation .. stability .. stack .. stackdepth .. stop .. strlen .. strtoll .. struct .. sugar .. syscall .. sysevent .. tick-n .. trace .. tracemem .. translators .. typedef .. types .. uctf .. union .. usdt .. ustack .. vars .. version .. .. i386 arrays .. funcs .. pid .. ustack .. .. .. zfsd .. .. .. etc rc.d .. .. examples .. games .. gnu lib .. usr.bin diff .. .. .. include .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. csu dynamic .. dynamiclib .. dynamicpie .. static .. .. googletest gmock .. gmock_main .. gtest .. gtest_main .. .. libarchive .. libbe .. libbsnmp .. libc c063 .. db .. gen execve .. posix_spawn .. .. hash data .. .. iconv .. inet .. locale .. net getaddrinfo data .. .. .. nss .. regex data .. .. resolv .. rpc .. secure .. setjmp .. ssp .. stdio .. stdlib .. stdtime .. string .. sys .. termios .. time .. tls dso .. .. ttyio .. .. libcam .. libcasper services cap_dns .. cap_fileargs .. cap_grp .. cap_net .. cap_netdb .. cap_pwd .. cap_sysctl .. .. .. libcrypt .. libdevdctl .. libdiff .. libexecinfo .. libkvm .. libmd .. libmp .. libnv .. libproc .. libregex data .. .. librt .. libsbuf .. libsysdecode .. libthr dlopen .. .. libutil .. libxo .. msun .. .. libexec atf atf-check .. atf-pytest-wrapper .. atf-sh .. .. nuageinit .. rc .. rtld-elf rtld_deepbind .. .. tftpd .. .. sbin bectl .. devd .. dhclient .. growfs .. ifconfig .. ipfw .. md5 .. mdconfig .. newfs_msdos .. nvmecontrol .. pfctl files .. .. ping .. route .. savecore .. sysctl .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. googletest .. plain .. tap .. .. .. zoneinfo .. .. sys acl .. aio .. audit .. auditpipe .. cam ctl .. .. capsicum .. cddl zfs bin .. include .. tests acl cifs .. nontrivial .. trivial .. .. atime .. bootfs .. cache .. cachefile .. clean_mirror .. cli_root zdb .. zfs .. zfs_clone .. zfs_copies .. zfs_create .. zfs_destroy .. zfs_diff .. zfs_get .. zfs_inherit .. zfs_mount .. zfs_promote .. zfs_property .. zfs_receive .. zfs_rename .. zfs_reservation .. zfs_rollback .. zfs_send .. zfs_set .. zfs_share .. zfs_snapshot .. zfs_unmount .. zfs_unshare .. zfs_upgrade .. zpool .. zpool_add .. zpool_attach .. zpool_clear .. zpool_create .. zpool_destroy .. zpool_detach .. zpool_expand .. zpool_export .. zpool_get .. zpool_history .. zpool_import blockfiles .. .. zpool_offline .. zpool_online .. zpool_remove .. zpool_replace .. zpool_scrub .. zpool_set .. zpool_status .. zpool_upgrade blockfiles .. .. .. cli_user misc .. zfs_list .. zpool_iostat .. zpool_list .. .. compression .. ctime .. delegate .. devices .. exec .. grow_pool .. grow_replicas .. history .. hotplug .. hotspare .. inheritance .. interop .. inuse .. iscsi .. large_files .. largest_pool .. link_count .. migration .. mmap .. mount .. mv_files .. nestedfs .. no_space .. online_offline .. pool_names .. poolversion .. quota .. redundancy .. refquota .. refreserv .. rename_dirs .. replacement .. reservation .. rootpool .. rsend .. scrub_mirror .. slog .. snapshot .. snapused .. sparse .. threadsappend .. truncate .. txg_integrity .. userquota .. utils_test .. write_dirs .. xattr .. zfsd .. zil .. zinject .. zones .. zvol zvol_ENOSPC .. zvol_cli .. zvol_misc .. zvol_swap .. .. zvol_thrash .. .. .. .. common .. compat32 .. devrandom .. dtrace .. fifo .. file .. fs fusefs .. tarfs .. tmpfs .. .. geom class concat .. eli .. gate .. gpt .. mirror .. multipath .. nop .. part .. raid3 .. shsec .. stripe .. union .. uzip etalon .. .. virstor .. .. .. kern acct .. execve .. pipe .. tty .. .. kqueue libkqueue .. .. mac bsdextended .. ipacl .. portacl .. .. mqueue .. net bpf .. if_ovpn ccd .. .. routing .. .. netgraph .. netinet libalias .. .. netinet6 frag6 .. .. netipsec tunnel .. .. netlink .. netmap .. netpfil common .. ipfw .. pf ioctl .. .. .. opencrypto .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. utimensat .. .. posixshm .. ses .. sound .. sys .. vfs .. vm stack .. .. vmm .. .. usr.bin apply .. asa .. awk bugs-fixed .. netbsd .. .. basename .. bintrans .. bmake archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. bsdcat .. calendar .. cmp .. col .. comm .. compress .. cpio .. csplit .. cut .. diff .. diff3 .. dirname .. du .. env .. factor .. file .. file2c .. find .. fold .. getconf .. gh-bc scripts .. tests bc errors .. scripts .. .. dc errors .. scripts .. .. .. .. grep .. gzip .. head .. hexdump .. ident .. indent .. join .. jot .. lastcomm .. limits .. locale .. lockf .. lorder .. m4 .. mail .. mkimg .. mktemp .. ncal .. opensm .. patch .. pr .. printenv .. printf .. procstat .. renice .. rs .. sdiff .. sed regress.multitest.out .. .. seq .. soelim .. sort .. split .. stat .. tail .. tar .. tee .. tftp .. touch .. tr .. truncate .. tsort .. unifdef .. uniq .. units .. unzip .. vmstat .. wc .. xargs .. xinstall .. xo .. yacc yacc .. .. .. usr.sbin chown .. ctladm .. daemon .. etcupdate .. extattr .. fstyp .. jail .. makefs .. mixer .. newsyslog .. nmtree .. praudit .. pw .. rpcbind .. sa .. syslogd .. + sysrc + .. .. .. # vim: set expandtab ts=4 sw=4: 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 + SCRIPTS= sysrc MAN= sysrc.8 +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + .include 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 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 +# + +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 +}