tests: skip gracefully when the tested binary's own package isn't installed

pkgbase splits programs and their tests into separate packages (e.g.
unifdef/yacc/indent/file2c -> toolchain, jail -> jail, etc), while their
tests always land in the generic tests package.  Installing just the
tests package therefore leaves these suites unable to find the binary
they exercise, and they fail confusingly instead of skipping.

Rather than force all packages to be installed for the tests package,
make the tests cope with the missing packages.  Add require.progs (or,
for TAP/PLAIN-style suites with no atf_set hook: TEST_METADATA
required_programs) for the binary under test in: bectl, certctl,
ctfconvert, dhclient, file2c, indent, ipfw, jail, lastcomm, mixer,
newsyslog, nvmecontrol, pfctl, praudit, sa, syslogd, tunefs, unifdef,
yacc, ztest.

I skipped adding data for all the binaries in the base runtime
package for simplicity.

Assisted-by:		Claude Code (Sonnet 5)
Sponsored by:		Netflix
Reviewed by:		ngie
Differential Revision:	https://reviews.freebsd.org/D58262
This commit is contained in:
Warner Losh committed 2026-09-10 23:42:25 -06:00
1 parent 73df5f2ec9
commit a259b98fa2
21 files changed
+93 -2

No files matched your search

+1
View File
@@ -7,6 +7,7 @@ ztest_head()
atf_set "descr" "Run ztest"
atf_set "timeout" 900
atf_set "require.config" "rt_long"
atf_set "require.progs" ztest
}
ztest_body()
@@ -43,6 +43,7 @@ basic_body() {
atf_test_case lastline
lastline_head() {
atf_set "descr" "Checks with directive on last line (PR bin/47068)"
atf_set "require.progs" "unifdef"
}
lastline_body() {
+10 -1
View File
@@ -74,6 +74,7 @@ bectl_create_head()
{
atf_set "descr" "Check the various forms of bectl create"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_create_body()
{
@@ -145,6 +146,7 @@ bectl_destroy_head()
{
atf_set "descr" "Check bectl destroy"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_destroy_body()
{
@@ -233,6 +235,7 @@ bectl_export_import_head()
{
atf_set "descr" "Check bectl export and import"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_export_import_body()
{
@@ -269,6 +272,7 @@ bectl_list_head()
{
atf_set "descr" "Check bectl list"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_list_body()
{
@@ -312,6 +316,7 @@ bectl_mount_head()
{
atf_set "descr" "Check bectl mount/unmount"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_mount_body()
{
@@ -354,6 +359,7 @@ bectl_rename_head()
{
atf_set "descr" "Check bectl rename"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_rename_body()
{
@@ -388,7 +394,7 @@ bectl_jail_head()
{
atf_set "descr" "Check bectl rename"
atf_set "require.user" root
atf_set "require.progs" jail
atf_set "require.progs" jail bectl
}
bectl_jail_body()
{
@@ -504,6 +510,7 @@ bectl_promotion_head()
{
atf_set "descr" "Check bectl promotion upon activation"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_promotion_body()
{
@@ -557,6 +564,7 @@ bectl_destroy_bootonce_head()
{
atf_set "descr" "Check bectl destroy (bootonce)"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_destroy_bootonce_body()
{
@@ -601,6 +609,7 @@ bectl_rename_bootonce_head()
{
atf_set "descr" "Check bectl destroy (bootonce)"
atf_set "require.user" root
atf_set "require.progs" bectl
}
bectl_rename_bootonce_body()
{
+2
View File
@@ -53,6 +53,7 @@ normal_head()
{
atf_set descr 'test dhclient against a server'
atf_set require.user root
atf_set "require.progs" dhclient
}
normal_body()
@@ -107,6 +108,7 @@ pcp_head()
{
atf_set descr 'test dhclient on pcp interface'
atf_set require.user root
atf_set "require.progs" dhclient
}
pcp_body()
+1
View File
@@ -12,6 +12,7 @@ nptv6_head()
atf_set "descr" "Test creation of NPTv6 rules"
atf_set "require.user" "root"
atf_set "require.kmods" "ipfw_nptv6"
atf_set "require.progs" ipfw
}
nptv6_body()
{
+10
View File
@@ -44,6 +44,7 @@ fake_lib_head()
{
atf_set "descr" "check loading of a library from /lib"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
fake_lib_body()
{
@@ -67,6 +68,7 @@ fake_local_lib_head()
{
atf_set "descr" "check loading of a library from /usr/local/lib"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
fake_local_lib_body()
{
@@ -90,6 +92,7 @@ admin_passthru_head()
{
atf_set "descr" "check the admin-passthru command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
admin_passthru_body()
{
@@ -106,6 +109,7 @@ devlist_head()
{
atf_set "descr" "check the devlist command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
devlist_body()
{
@@ -122,6 +126,7 @@ identify_head()
{
atf_set "descr" "check the identify command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
identify_body()
{
@@ -138,6 +143,7 @@ io_passthru_head()
{
atf_set "descr" "check the io-passthru command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
io_passthru_body()
{
@@ -154,6 +160,7 @@ logpage_head()
{
atf_set "descr" "check the logpage command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
logpage_body()
{
@@ -170,6 +177,7 @@ nsid_head()
{
atf_set "descr" "check the nsid command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
nsid_body()
{
@@ -186,6 +194,7 @@ power_head()
{
atf_set "descr" "check the power command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
power_body()
{
@@ -202,6 +211,7 @@ reset_head()
{
atf_set "descr" "check the reset command"
atf_set "require.user" "root"
atf_set "require.progs" nvmecontrol
}
reset_body()
{
+1
View File
@@ -4,6 +4,7 @@ space_head()
{
atf_set descr "Test macros with spaces"
atf_set require.kmods "pf"
atf_set require.progs "pfctl"
}
space_body()
+4
View File
@@ -272,6 +272,7 @@ do_selfpf_test(const char *number, const atf_tc_t *tc)
{ \
atf_tc_set_md_var(tc, "descr", descr); \
atf_tc_set_md_var(tc, "require.kmods", "pf"); \
atf_tc_set_md_var(tc, "require.progs", "pfctl"); \
} \
ATF_TC_BODY(pf##number, tc) \
{ \
@@ -282,6 +283,7 @@ do_selfpf_test(const char *number, const atf_tc_t *tc)
{ \
atf_tc_set_md_var(tc, "descr", "Self " descr); \
atf_tc_set_md_var(tc, "require.kmods", "pf"); \
atf_tc_set_md_var(tc, "require.progs", "pfctl"); \
} \
ATF_TC_BODY(selfpf##number, tc) \
{ \
@@ -294,6 +296,7 @@ do_selfpf_test(const char *number, const atf_tc_t *tc)
{ \
atf_tc_set_md_var(tc, "descr", descr); \
atf_tc_set_md_var(tc, "require.kmods", "pf"); \
atf_tc_set_md_var(tc, "require.progs", "pfctl"); \
} \
ATF_TC_BODY(pf##number, tc) \
{ \
@@ -308,6 +311,7 @@ do_selfpf_test(const char *number, const atf_tc_t *tc)
atf_tc_set_md_var(tc, "execenv", "jail"); \
atf_tc_set_md_var(tc, "execenv.jail.params", "vnet"); \
atf_tc_set_md_var(tc, "require.kmods", "pf"); \
atf_tc_set_md_var(tc, "require.progs", "pfctl"); \
} \
ATF_TC_BODY(pf##number, tc) \
{ \
+6
View File
@@ -64,6 +64,7 @@ posixacl_head()
{
atf_set descr "Turn POSIX.1e ACLs on and off"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
posixacl_body()
{
@@ -81,6 +82,7 @@ nfs4acl_head()
{
atf_set descr "Turn NFSv4 ACLs on and off"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
nfs4acl_body()
{
@@ -98,6 +100,7 @@ sunoj_head()
{
atf_set descr "Turn Soft Updates on and off"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
sunoj_body()
{
@@ -115,6 +118,7 @@ suj_head()
{
atf_set descr "Turn Soft Updates journaling on and off"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
suj_body()
{
@@ -132,6 +136,7 @@ gjournal_head()
{
atf_set descr "Turn GEOM journaling on and off"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
gjournal_body()
{
@@ -149,6 +154,7 @@ conflict_head()
{
atf_set descr "Soft Updates and GEOM journaling are mutually exclusive"
atf_set require.user "root"
atf_set "require.progs" tunefs
}
conflict_body()
{
+1
View File
@@ -1,6 +1,7 @@
PACKAGE= tests
TAP_TESTS_SH= legacy_test
TEST_METADATA.legacy_test+= required_programs="file2c"
${PACKAGE}FILES+= regress.1.out
${PACKAGE}FILES+= regress.2.out
+5
View File
@@ -53,11 +53,16 @@ add_legacy_testcase()
local tc=${1}
atf_test_case ${tc%.[0-9]}
eval "${tc%.[0-9]}_head() { atf_set \"require.progs\" indent; }"
eval "${tc%.[0-9]}_body() { check ${tc}; }"
atf_add_test_case ${tc%.[0-9]}
}
atf_test_case backup_suffix
backup_suffix_head()
{
atf_set "require.progs" indent
}
backup_suffix_body()
{
local argmax=$(sysctl -n kern.argmax)
+1
View File
@@ -2,6 +2,7 @@ PACKAGE= tests
TAP_TESTS_SH= legacy_test
TEST_METADATA.legacy_test+= allowed_architectures="amd64 i386"
TEST_METADATA.legacy_test+= required_programs="lastcomm"
${PACKAGE}FILES+= v1-amd64-acct.in
${PACKAGE}FILES+= v1-amd64.out
+3
View File
@@ -7,6 +7,7 @@
atf_test_case hash_comment
hash_comment_head() {
atf_set descr "multiline comment follows directive"
atf_set "require.progs" unifdef
}
hash_comment_body() {
cat >f <<EOF
@@ -21,6 +22,7 @@ EOF
atf_test_case redefine
redefine_head() {
atf_set descr "redefine the same symbol"
atf_set "require.progs" unifdef
}
redefine_body() {
cat >file <<EOF
@@ -41,6 +43,7 @@ EOF
atf_test_case sDU
sDU_head() {
atf_set descr "simultaneous use of -s and -D or -U"
atf_set "require.progs" unifdef
}
sDU_body() {
atf_check unifdef -s -DFOO -UFOO /dev/null
+1
View File
@@ -9,6 +9,7 @@ PLAIN_TESTS_SH= yacc_tests
# with root, this must be run as a non-privileged user; otherwise
# the testcases will fail unexpectedly.
TEST_METADATA.yacc_tests+= required_user="unprivileged"
TEST_METADATA.yacc_tests+= required_programs="yacc"
SCRIPTS= run_test
SCRIPTSDIR= ${TESTSDIR}
+6
View File
@@ -181,6 +181,7 @@ atf_test_case rehash
rehash_head()
{
atf_set "descr" "Test the rehash command"
atf_set "require.progs" certctl
}
rehash_body()
{
@@ -218,6 +219,7 @@ atf_test_case list
list_head()
{
atf_set "descr" "Test the list and untrusted commands"
atf_set "require.progs" certctl
}
list_body()
{
@@ -243,6 +245,7 @@ atf_test_case trust
trust_head()
{
atf_set "descr" "Test the trust command"
atf_set "require.progs" certctl
}
trust_body()
{
@@ -262,6 +265,7 @@ atf_test_case untrust
untrust_head()
{
atf_set "descr" "Test the untrust command"
atf_set "require.progs" certctl
}
untrust_body()
{
@@ -281,6 +285,7 @@ atf_test_case metalog
metalog_head()
{
atf_set "descr" "Verify the metalog"
atf_set "require.progs" certctl
}
metalog_body()
{
@@ -312,6 +317,7 @@ atf_test_case misc
misc_head()
{
atf_set "descr" "Test miscellaneous edge cases"
atf_set "require.progs" certctl
}
misc_body()
{
+7 -1
View File
@@ -29,6 +29,7 @@ basic_head()
{
atf_set descr 'Basic jail test'
atf_set require.user root
atf_set require.progs jail
}
basic_body()
@@ -63,6 +64,7 @@ list_head()
{
atf_set descr 'Specify some jail parameters as lists'
atf_set require.user root
atf_set require.progs jail
}
list_body()
@@ -92,6 +94,7 @@ nested_head()
{
atf_set descr 'Hierarchical jails test'
atf_set require.user root
atf_set require.progs jail
}
nested_body()
@@ -132,6 +135,7 @@ commands_head()
{
atf_set descr 'Commands jail test'
atf_set require.user root
atf_set require.progs jail
}
commands_body()
@@ -173,6 +177,7 @@ jid_name_set_head()
{
atf_set descr 'Test that one can set both the jid and name in a config file'
atf_set require.user root
atf_set require.progs jail
}
find_unused_jid()
@@ -245,6 +250,7 @@ param_consistency_head()
{
atf_set descr 'Test for consistency in jid/name params being set implicitly'
atf_set require.user root
atf_set require.progs jail
}
param_consistency_body()
@@ -315,7 +321,7 @@ setaudit_head()
{
atf_set descr 'Test that setaudit works in a jail when configured with allow.setaudit'
atf_set require.user root
atf_set require.progs setaudit
atf_set require.progs setaudit jail
}
setaudit_body()
+5
View File
@@ -68,6 +68,7 @@ o_flag_head()
{
atf_set "descr" "Verify that the output of the -o flag can be used " \
"as valid input"
atf_set "require.progs" mixer
}
o_flag_body()
{
@@ -85,6 +86,7 @@ atf_test_case d_flag cleanup
d_flag_head()
{
atf_set "descr" "Test default unit setting"
atf_set "require.progs" mixer
}
d_flag_body()
{
@@ -106,6 +108,7 @@ atf_test_case volume cleanup
volume_head()
{
atf_set "descr" "Test volume setting"
atf_set "require.progs" mixer
}
volume_body()
{
@@ -191,6 +194,7 @@ atf_test_case mute cleanup
mute_head()
{
atf_set "descr" "Test muting"
atf_set "require.progs" mixer
}
mute_body()
{
@@ -224,6 +228,7 @@ atf_test_case recsrc cleanup
recsrc_head()
{
atf_set "descr" "Test recording source handling"
atf_set "require.progs" mixer
}
recsrc_body()
{
+1
View File
@@ -1,3 +1,4 @@
TAP_TESTS_SH= legacy_test
TEST_METADATA.legacy_test+= required_programs="newsyslog"
.include <bsd.test.mk>
+10
View File
@@ -29,6 +29,7 @@ atf_test_case praudit_delim_comma
praudit_delim_comma_head()
{
atf_set "descr" "Verify that comma delimiter is present with -d ',' cmd"
atf_set "require.progs" praudit
}
praudit_delim_comma_body()
@@ -42,6 +43,7 @@ atf_test_case praudit_delim_underscore
praudit_delim_underscore_head()
{
atf_set "descr" "Verify that underscore delimiter is present with -d _"
atf_set "require.progs" praudit
}
praudit_delim_underscore_body()
@@ -56,6 +58,7 @@ praudit_no_args_head()
{
atf_set "descr" "Verify that praudit outputs default form without " \
"any arguments"
atf_set "require.progs" praudit
}
praudit_no_args_body()
@@ -70,6 +73,7 @@ praudit_numeric_form_head()
{
atf_set "descr" "Verify that praudit outputs the numeric form " \
"with -n flag"
atf_set "require.progs" praudit
}
praudit_numeric_form_body()
@@ -83,6 +87,7 @@ atf_test_case praudit_raw_form
praudit_raw_form_head()
{
atf_set "descr" "Verify that praudit outputs the raw form with -r flag"
atf_set "require.progs" praudit
}
praudit_raw_form_body()
@@ -97,6 +102,7 @@ praudit_same_line_head()
{
atf_set "descr" "Verify that praudit outputs the trail in the same " \
"line with -l flag"
atf_set "require.progs" praudit
}
praudit_same_line_body()
@@ -111,6 +117,7 @@ praudit_short_form_head()
{
atf_set "descr" "Verify that praudit outputs the short form " \
"with -s flag"
atf_set "require.progs" praudit
}
praudit_short_form_body()
@@ -124,6 +131,7 @@ atf_test_case praudit_xml_form
praudit_xml_form_head()
{
atf_set "descr" "Verify that praudit outputs the XML file with -x flag"
atf_set "require.progs" praudit
}
praudit_xml_form_body()
@@ -139,6 +147,7 @@ praudit_sync_to_next_record_head()
atf_set "descr" "Verify that praudit(1) outputs the last few audit " \
"records when the initial part of the trail is " \
"corrputed."
atf_set "require.progs" praudit
}
praudit_sync_to_next_record_body()
@@ -158,6 +167,7 @@ praudit_raw_short_exclusive_head()
{
atf_set "descr" "Verify that praudit outputs usage message on stderr " \
"when both raw and short options are specified"
atf_set "require.progs" praudit
}
praudit_raw_short_exclusive_body()
+1
View File
@@ -2,6 +2,7 @@ PACKAGE= tests
TAP_TESTS_SH= legacy_test
TEST_METADATA.legacy_test+= allowed_architectures="amd64 i386"
TEST_METADATA.legacy_test+= required_programs="sa"
${PACKAGE}FILES+= v1-amd64-sav.in
${PACKAGE}FILES+= v1-amd64-sav.out
+16
View File
@@ -20,6 +20,7 @@ atf_test_case "unix" "cleanup"
unix_head()
{
atf_set descr "Messages are logged over UNIX transport"
atf_set "require.progs" syslogd
}
unix_body()
{
@@ -39,6 +40,7 @@ atf_test_case "inet" "cleanup"
inet_head()
{
atf_set descr "Messages are logged over INET transport"
atf_set "require.progs" syslogd
}
inet_body()
{
@@ -62,6 +64,7 @@ atf_test_case "inet6" "cleanup"
inet6_head()
{
atf_set descr "Messages are logged over INET6 transport"
atf_set "require.progs" syslogd
}
inet6_body()
{
@@ -85,6 +88,7 @@ atf_test_case "reload" "cleanup"
reload_head()
{
atf_set descr "SIGHUP correctly refreshes configuration"
atf_set "require.progs" syslogd
}
reload_body()
{
@@ -116,6 +120,7 @@ atf_test_case "prog_filter" "cleanup"
prog_filter_head()
{
atf_set descr "Messages are only received from programs in the filter"
atf_set "require.progs" syslogd
}
prog_filter_body()
{
@@ -159,6 +164,7 @@ atf_test_case "host_filter" "cleanup"
host_filter_head()
{
atf_set descr "Messages are only received from hostnames in the filter"
atf_set "require.progs" syslogd
}
host_filter_body()
{
@@ -198,6 +204,7 @@ atf_test_case "prop_filter" "cleanup"
prop_filter_head()
{
atf_set descr "Messages are received based on conditions in the propery based filter"
atf_set "require.progs" syslogd
}
prop_filter_body()
{
@@ -270,6 +277,7 @@ atf_test_case "host_action" "cleanup"
host_action_head()
{
atf_set descr "Sends a message to a specified host"
atf_set "require.progs" syslogd
}
host_action_body()
{
@@ -307,6 +315,7 @@ atf_test_case "pipe_action" "cleanup"
pipe_action_head()
{
atf_set descr "The pipe action evaluates provided command in sh(1)"
atf_set "require.progs" syslogd
}
pipe_action_body()
{
@@ -331,6 +340,7 @@ atf_test_case "pipe_action_reload" "cleanup"
pipe_action_reload_head()
{
atf_set descr "Pipe processes terminate gracefully on reload"
atf_set "require.progs" syslogd
}
pipe_action_reload_body()
{
@@ -372,6 +382,7 @@ jail_noinet_head()
{
atf_set descr "syslogd -ss can be run in a jail without INET support"
atf_set require.user root
atf_set "require.progs" syslogd
}
jail_noinet_body()
{
@@ -423,6 +434,7 @@ allowed_peer_head()
{
atf_set descr "syslogd -a works"
atf_set require.user root
atf_set "require.progs" syslogd
}
allowed_peer_body()
{
@@ -470,6 +482,7 @@ allowed_peer_forwarding_head()
{
atf_set descr "syslogd forwards messages from its listening port"
atf_set require.user root
atf_set "require.progs" syslogd
}
allowed_peer_forwarding_body()
{
@@ -503,6 +516,7 @@ allowed_peer_wildcard_head()
{
atf_set descr "syslogd -a works with port wildcards"
atf_set require.user root
atf_set "require.progs" syslogd
}
allowed_peer_wildcard_body()
{
@@ -541,6 +555,7 @@ forward_head()
{
atf_set descr "syslogd forwards messages to a remote host"
atf_set require.user root
atf_set "require.progs" syslogd
}
forward_body()
{
@@ -600,6 +615,7 @@ forward_reload_head()
{
atf_set descr "syslogd might start before routes are configured"
atf_set require.user root
atf_set "require.progs" syslogd
}
forward_reload_body()
{