# # Copyright (c) 2026 Devin Teske # # SPDX-License-Identifier: BSD-2-Clause # # # Resolve the sysconf binary: honor SYSCONF if set, else the sibling # build product (objdir layout: .../sysconf/tests next to .../sysconf/sysconf), # else PATH. Require a regular file: when installed under # /usr/tests/usr.sbin/sysconf, `../sysconf' is this directory itself and # `[ -x dir ]' is true for searchable directories. # find_sysconf() { if [ -n "$SYSCONF" ] && [ -f "$SYSCONF" ] && [ -x "$SYSCONF" ]; then return fi if [ -f "$( atf_get_srcdir )/../sysconf" ] && [ -x "$( atf_get_srcdir )/../sysconf" ] then SYSCONF="$( atf_get_srcdir )/../sysconf" elif [ -f "$( pwd )/../sysconf" ] && [ -x "$( pwd )/../sysconf" ]; then SYSCONF="$( pwd )/../sysconf" else SYSCONF=$( command -v sysconf ) || atf_skip "sysconf binary not found" fi } setup_root() { find_sysconf ROOT="$( pwd )/root" mkdir -p "$ROOT/etc" "$ROOT/boot/defaults" } cleanup_root() { rm -rf "$( pwd )/root" } atf_test_case make_append_accumulate cleanup make_append_accumulate_head() { atf_set "descr" \ "make += accumulates on read and appends a line on write" } make_append_accumulate_body() { setup_root printf 'foo=1\n' > "$ROOT/etc/make.conf" atf_check -o inline:'foo: 1\n' "$SYSCONF" make -R "$ROOT" foo printf 'foo+=2\n' >> "$ROOT/etc/make.conf" atf_check -o inline:'foo: 1 2\n' "$SYSCONF" make -R "$ROOT" foo atf_check -o inline:'foo: 1 2 -> 1 2 -O2\n' \ "$SYSCONF" make -R "$ROOT" 'foo+=-O2' atf_check -o inline:'foo: 1 2 -O2\n' "$SYSCONF" make -R "$ROOT" foo atf_check -o match:'foo\+=-O2' cat "$ROOT/etc/make.conf" # -V on a new += statement reports (added), not `+= -> +=value' atf_check -o match:'make.conf:[0-9]*: foo\+=-O3 \(added\)' \ "$SYSCONF" make -R "$ROOT" -V 'foo+=-O3' atf_check -o inline:'foo: 1 2 -O2 -O3\n' "$SYSCONF" make -R "$ROOT" foo # Identical += is a no-op (append_present) before=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check "$SYSCONF" make -R "$ROOT" -c 'foo+=-O2' after=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after" } make_append_accumulate_cleanup() { cleanup_root } atf_test_case src_triad_and_trail cleanup src_triad_and_trail_head() { atf_set "descr" "src triad order, -V trail, writes prefer src.conf" } src_triad_and_trail_body() { setup_root printf 'CFLAGS=-O0\n' > "$ROOT/etc/src-env.conf" printf 'CFLAGS+=-g\n' > "$ROOT/etc/make.conf" printf 'CFLAGS+=-pipe\n' > "$ROOT/etc/src.conf" atf_check -o inline:'CFLAGS: -O0 -g -pipe\n' \ "$SYSCONF" src -R "$ROOT" CFLAGS atf_check -o match:'src-env.conf:1: CFLAGS=-O0' \ -o match:'make.conf:1: CFLAGS\+=-g -> -O0 -g' \ -o match:'src.conf:1: CFLAGS\+=-pipe -> -O0 -g -pipe' \ "$SYSCONF" src -R "$ROOT" -V CFLAGS atf_check -o match:'src.conf' \ "$SYSCONF" src -R "$ROOT" -v CFLAGS # New directive lands in src.conf atf_check "$SYSCONF" src -R "$ROOT" -q WITHOUT_FOO= atf_check -o match:'WITHOUT_FOO=' cat "$ROOT/etc/src.conf" atf_check -o not-match:'WITHOUT_FOO' cat "$ROOT/etc/make.conf" } src_triad_and_trail_cleanup() { cleanup_root } atf_test_case src_env_rejected src_env_rejected_head() { atf_set "descr" "src-env keyword is rejected with a hint toward src" } src_env_rejected_body() { find_sysconf atf_check -s not-exit:0 -e match:'src-env' -e match:'src' \ "$SYSCONF" src-env foo } atf_test_case env_overrides cleanup env_overrides_head() { atf_set "descr" "SRC_ENV_CONF / __MAKE_CONF / SRCCONF remap the triad" } env_overrides_body() { setup_root mkdir -p "$ROOT/alt" printf 'X=from-env\n' > "$ROOT/alt/se.conf" printf 'X+=from-make\n' > "$ROOT/alt/mk.conf" printf 'X+=from-src\n' > "$ROOT/alt/sc.conf" # Empty stock files so -R still resolves the triad slots :> "$ROOT/etc/src-env.conf" :> "$ROOT/etc/make.conf" :> "$ROOT/etc/src.conf" export SRC_ENV_CONF="$ROOT/alt/se.conf" export __MAKE_CONF="$ROOT/alt/mk.conf" export SRCCONF="$ROOT/alt/sc.conf" atf_check -o inline:'X: from-env from-make from-src\n' \ "$SYSCONF" src -R "$ROOT" X unset SRC_ENV_CONF __MAKE_CONF SRCCONF } env_overrides_cleanup() { cleanup_root } atf_test_case attached_f_passthrough cleanup attached_f_passthrough_head() { atf_set "descr" \ "Attached -fPATH does not steal the next argv (rc as name)" } attached_f_passthrough_body() { setup_root mkdir -p "$ROOT/boot" printf 'zfs_load="YES"\n' > "$ROOT/boot/loader.conf" # # If find_target consumed 'loader' as -f's argument, 'rc' would become # the target and exec sysrc(8). Correctly, target is loader and 'rc' # is an unknown directive name. # atf_check -s not-exit:0 -e match:'unknown directive' \ "$SYSCONF" -R "$ROOT" -f/boot/loader.conf loader rc } attached_f_passthrough_cleanup() { cleanup_root } atf_test_case verbatim_backslash cleanup verbatim_backslash_head() { atf_set "descr" \ "verbatim_ok re-examines the byte after an even \\\\ run" } verbatim_backslash_body() { setup_root printf 'foo=1\n' > "$ROOT/etc/make.conf" # Even-length \\ before # must not skip #: put must reject (Faraz) atf_check -s not-exit:0 -e match:'Invalid argument' \ "$SYSCONF" make -R "$ROOT" 'foo=a\\#b' # A value without a comment marker still writes. atf_check -o match:'foo:' \ "$SYSCONF" make -R "$ROOT" 'foo=a\\b' atf_check -o match:'foo=a\\\\b' cat "$ROOT/etc/make.conf" } verbatim_backslash_cleanup() { cleanup_root } atf_test_case make_strike_last_assign cleanup make_strike_last_assign_head() { atf_set "descr" \ "make -= strikes the last assignment containing the word" } make_strike_last_assign_body() { setup_root printf 'bar+=1\nbar+=1 2\nbar+=1 2 3\n' > "$ROOT/etc/make.conf" atf_check -o match:'->' "$SYSCONF" make -R "$ROOT" 'bar-=3' atf_check -o inline:'bar+=1\nbar+=1 2\nbar+=1 2\n' \ cat "$ROOT/etc/make.conf" atf_check -o match:'->' "$SYSCONF" make -R "$ROOT" 'bar-=2' atf_check -o inline:'bar+=1\nbar+=1 2\nbar+=1\n' \ cat "$ROOT/etc/make.conf" atf_check -o match:'->' "$SYSCONF" make -R "$ROOT" 'bar-=1' atf_check -o inline:'bar+=1\nbar+=1 2\n' cat "$ROOT/etc/make.conf" atf_check -o match:'->' "$SYSCONF" make -R "$ROOT" 'bar-=1' atf_check -o inline:'bar+=1\nbar+=2\n' cat "$ROOT/etc/make.conf" atf_check -o match:'->' "$SYSCONF" make -R "$ROOT" 'bar-=2' atf_check -o inline:'bar+=1\n' cat "$ROOT/etc/make.conf" atf_check -o inline:'bar: 1 (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" 'bar-=9' # Emptying the last word deletes the statement: (removed), like (added) printf 'z+=only\n' >>"$ROOT/etc/make.conf" atf_check -o match:'make.conf:[0-9]*: z\+=only \(removed\)' \ "$SYSCONF" make -R "$ROOT" -V 'z-=only' atf_check -o not-match:'^z\+=' cat "$ROOT/etc/make.conf" } make_strike_last_assign_cleanup() { cleanup_root } atf_test_case equal_value_nocheck_mtime cleanup equal_value_nocheck_mtime_head() { atf_set "descr" "Equal-value write and -c leave mtime alone" } equal_value_nocheck_mtime_body() { setup_root printf 'bar=1\n' > "$ROOT/etc/make.conf" sleep 1 before=$( stat -f '%m' "$ROOT/etc/make.conf" ) # Equal-value write: informational echo, file untouched atf_check -o inline:'bar: 1 (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" bar=1 # -e uses `=' for write echoes the same as for reads atf_check -o inline:'bar=1 (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" -e bar=1 after=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after" # -q suppresses the echo; -c is silent and does not write atf_check -o empty "$SYSCONF" make -R "$ROOT" -q bar=1 atf_check -o empty "$SYSCONF" make -R "$ROOT" -c bar=1 after2=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after2" atf_check -o inline:'bar=1 # -> 2\n' \ "$SYSCONF" make -R "$ROOT" -e bar=2 atf_check -o inline:'bar=2\n' \ "$SYSCONF" make -R "$ROOT" -e bar } equal_value_nocheck_mtime_cleanup() { cleanup_root } atf_test_case sysctl_oid_range cleanup sysctl_oid_range_head() { atf_set "descr" \ "sysctl target rejects values that overflow the OID CTLTYPE" } sysctl_oid_range_body() { find_sysconf case "$( uname -s )" in FreeBSD) ;; *) atf_skip "requires FreeBSD sysctl OIDFMT" ;; esac # -f alone (no -R) still validates against the running kernel. conf="$( pwd )/sysctl.conf" :> "$conf" atf_check -s exit:1 -e match:'out of range for integer' \ "$SYSCONF" sysctl -f "$conf" \ security.bsd.see_other_uids=99999999999 atf_check -o empty cat "$conf" atf_check -s exit:1 -e match:'out of range for unsigned integer' \ "$SYSCONF" sysctl -f "$conf" kern.ipc.somaxconn=-1 atf_check -s exit:1 -e match:'out of range for unsigned integer' \ "$SYSCONF" sysctl -f "$conf" kern.ipc.somaxconn=abc atf_check -o match:'see_other_uids' \ "$SYSCONF" sysctl -f "$conf" security.bsd.see_other_uids=0 atf_check -o match:'see_other_uids=0' cat "$conf" } sysctl_oid_range_cleanup() { rm -f "$( pwd )/sysctl.conf" } atf_test_case make_src_knobs cleanup make_src_knobs_head() { atf_set "descr" \ "-s WITH_/WITHOUT_ presence, query display, unchanged, -x" } make_src_knobs_body() { setup_root :> "$ROOT/etc/make.conf" :> "$ROOT/etc/sysctl.conf" :> "$ROOT/etc/src-env.conf" :> "$ROOT/etc/src.conf" # -s only on make/src atf_check -s exit:1 -e match:'only valid for make and src' \ "$SYSCONF" sysctl -R "$ROOT" -s WITHOUT_FOO # name must be WITH_/WITHOUT_ atf_check -s exit:1 -e match:'WITH_ or WITHOUT_' \ "$SYSCONF" make -R "$ROOT" -s CFLAGS # no value with -s atf_check -s exit:1 -e match:'does not take a value' \ "$SYSCONF" make -R "$ROOT" -s 'WITHOUT_FOO=' atf_check -o inline:'WITHOUT_FOO: (not present) -> (present)\n' \ "$SYSCONF" make -R "$ROOT" -s WITHOUT_FOO atf_check -o match:'^WITHOUT_FOO=$' cat "$ROOT/etc/make.conf" atf_check -o inline:'WITHOUT_FOO (present)\n' \ "$SYSCONF" make -R "$ROOT" WITHOUT_FOO atf_check -o inline:'WITHOUT_FOO=\n' \ "$SYSCONF" make -R "$ROOT" -e WITHOUT_FOO atf_check -o inline:'\n' \ "$SYSCONF" make -R "$ROOT" -n WITHOUT_FOO before=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check -o inline:'WITHOUT_FOO: (present) (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" -s WITHOUT_FOO after=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after" # Non-empty placeholder (=t) still means present (defined()) atf_check -o inline:'WITHOUT_BAR: (not present) -> (present)\n' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_BAR=t' atf_check -o match:'^WITHOUT_BAR=t$' cat "$ROOT/etc/make.conf" atf_check -o inline:'WITHOUT_BAR (present)\n' \ "$SYSCONF" make -R "$ROOT" WITHOUT_BAR atf_check -o inline:'WITHOUT_BAR=t\n' \ "$SYSCONF" make -R "$ROOT" -e WITHOUT_BAR atf_check -o inline:'t\n' \ "$SYSCONF" make -R "$ROOT" -n WITHOUT_BAR before=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check -o inline:'WITHOUT_BAR: (present) (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" -s WITHOUT_BAR after=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after" atf_check -o match:'^WITHOUT_BAR=t$' cat "$ROOT/etc/make.conf" # Explicit name= always writes (incl. empty); echo value changes atf_check -o inline:'WITHOUT_BAR: t -> \n' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_BAR=' atf_check -o match:'^WITHOUT_BAR=$' cat "$ROOT/etc/make.conf" atf_check -o inline:'WITHOUT_BAR: -> 123\n' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_BAR=123' atf_check -o match:'^WITHOUT_BAR=123$' cat "$ROOT/etc/make.conf" atf_check -o inline:'WITHOUT_BAR: 123 -> 456\n' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_BAR=456' atf_check -o match:'^WITHOUT_BAR=456$' cat "$ROOT/etc/make.conf" # -s still no-op while present with a value before=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check -o inline:'WITHOUT_BAR: (present) (unchanged)\n' \ "$SYSCONF" make -R "$ROOT" -s WITHOUT_BAR after=$( stat -f '%m' "$ROOT/etc/make.conf" ) atf_check_equal "$before" "$after" atf_check -o match:'^WITHOUT_BAR=456$' cat "$ROOT/etc/make.conf" # src prefers src.conf atf_check -o inline:'WITHOUT_LLDB: (not present) -> (present)\n' \ "$SYSCONF" src -R "$ROOT" -s WITHOUT_LLDB atf_check -o match:'^WITHOUT_LLDB=$' cat "$ROOT/etc/src.conf" # -x is quiet unless -v/-V (same as non-knob removals) atf_check -o empty \ "$SYSCONF" src -R "$ROOT" -x WITHOUT_LLDB atf_check -o empty cat "$ROOT/etc/src.conf" atf_check -o inline:'WITHOUT_LLDB: (not present) -> (present)\n' \ "$SYSCONF" src -R "$ROOT" -s WITHOUT_LLDB atf_check -o match:'WITHOUT_LLDB \(removed\)' \ "$SYSCONF" src -R "$ROOT" -vx WITHOUT_LLDB atf_check -o empty cat "$ROOT/etc/src.conf" # WITH_*=no (exact lowercase) warns like bsd.mkopt.mk; WITHOUT_*=no # and WITH_*=NO do not atf_check -e match:'Use WITHOUT_FOO=1 instead of WITH_FOO=no' \ -o match:'WITH_FOO' \ "$SYSCONF" make -R "$ROOT" 'WITH_FOO=no' atf_check -o match:'^WITH_FOO=no$' cat "$ROOT/etc/make.conf" atf_check -e empty -o match:'WITH_BAR' \ "$SYSCONF" make -R "$ROOT" 'WITH_BAR=NO' atf_check -e empty -o match:'WITHOUT_BAZ' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_BAZ=no' # Reads remind with file:line (presence display hides =no) atf_check -e match:'make.conf:[0-9]+: Use WITHOUT_FOO=1 instead of WITH_FOO=no' \ -o inline:'WITH_FOO (present)\n' \ "$SYSCONF" make -R "$ROOT" WITH_FOO atf_check -e match:'make.conf:[0-9]+: Use WITHOUT_FOO=1 instead of WITH_FOO=no' \ -o match:'WITH_FOO \(present\)' \ "$SYSCONF" make -R "$ROOT" -a atf_check -e match:'make.conf:[0-9]+: Use WITHOUT_FOO=1 instead of WITH_FOO=no' \ -o inline:'WITH_FOO=no\n' \ "$SYSCONF" make -R "$ROOT" -e WITH_FOO atf_check -e empty -o inline:'WITH_FOO (present)\n' \ "$SYSCONF" make -R "$ROOT" -q WITH_FOO # WITHOUT_MODULES is not a presence knob atf_check -s exit:1 -e match:'WITHOUT_MODULES takes a module list' \ "$SYSCONF" make -R "$ROOT" -s WITHOUT_MODULES atf_check -o match:'WITHOUT_MODULES: -> plip' \ "$SYSCONF" make -R "$ROOT" 'WITHOUT_MODULES=plip' atf_check -o inline:'WITHOUT_MODULES: plip\n' \ "$SYSCONF" make -R "$ROOT" WITHOUT_MODULES } make_src_knobs_cleanup() { cleanup_root } atf_test_case max_bytes_cap cleanup max_bytes_cap_head() { atf_set "descr" "BSDCONF_MAX_BYTES bounds parse input" } max_bytes_cap_body() { setup_root printf 'foo=ok\n' > "$ROOT/etc/make.conf" atf_check -o inline:'foo: ok\n' "$SYSCONF" make -R "$ROOT" foo # A tight cap rejects an otherwise valid file atf_check -s not-exit:0 -e match:'File too large' \ env BSDCONF_MAX_BYTES=4 "$SYSCONF" make -R "$ROOT" foo got=$( printf 'bar=piped\n' | "$SYSCONF" generic -f - bar ) || atf_fail "pipe parse failed" atf_check_equal "bar: piped" "$got" } max_bytes_cap_cleanup() { cleanup_root } atf_test_case target_prefix cleanup target_prefix_head() { atf_set "descr" \ "Unique target prefixes resolve; ambiguous and unknown fail" } target_prefix_body() { find_sysconf setup_root :> "$ROOT/etc/make.conf" :> "$ROOT/etc/src-env.conf" :> "$ROOT/etc/src.conf" printf 'foo=1\n' > "$ROOT/etc/make.conf" # Unique prefixes atf_check -o inline:'foo: 1\n' "$SYSCONF" m -R "$ROOT" foo atf_check -o inline:'foo: 1\n' "$SYSCONF" ma -R "$ROOT" foo atf_check -o inline:'foo: 1\n' "$SYSCONF" make -R "$ROOT" foo atf_check -o inline:'foo: 1\n' "$SYSCONF" sr -R "$ROOT" foo printf 'kern.foo=1\n' > "$ROOT/etc/sysctl.conf" atf_check -o inline:'kern.foo: 1\n' "$SYSCONF" sy -R "$ROOT" kern.foo # generic requires -f atf_check -s not-exit:0 -e match:'no default files' \ "$SYSCONF" g -R "$ROOT" foo atf_check -o inline:'foo: 1\n' \ "$SYSCONF" g -R "$ROOT" -f /etc/make.conf foo # Ambiguous: src and sysctl atf_check -s not-exit:0 \ -e match:'ambiguous target' \ -e match:'src' \ -e match:'sysctl' \ "$SYSCONF" s foo # Exact still wins atf_check -o inline:'foo: 1\n' "$SYSCONF" src -R "$ROOT" foo # Infix is not a prefix atf_check -s not-exit:0 -e match:'unknown target' \ "$SYSCONF" ctl foo # src-env is not a prefix of src atf_check -s not-exit:0 -e match:'src-env' -e match:'src' \ "$SYSCONF" src-env foo } target_prefix_cleanup() { cleanup_root } atf_test_case poudriere_sysrc cleanup poudriere_sysrc_head() { atf_set "descr" \ "poudriere target feeds sysrc -f over the conf collection" } poudriere_sysrc_body() { find_sysconf command -v sysrc > /dev/null 2>&1 || atf_skip "sysrc not installed" ETC="$( pwd )/petc" mkdir -p "$ETC/poudriere.d" printf 'ZPOOL=old\nFOO=global\n' > "$ETC/poudriere.conf" printf 'FOO=jail\nJOBS=2\n' \ > "$ETC/poudriere.d/131amd64-poudriere.conf" export POUDRIERE_ETC="$ETC" # -l / -L are printed here, one path per line (not sysrc -L) atf_check -o inline:"$ETC/poudriere.conf\n" \ "$SYSCONF" p -l atf_check -o inline:"$ETC/poudriere.conf\n$ETC/poudriere.d/poudriere.conf\n" \ "$SYSCONF" p -L atf_check -o inline:"$ETC/poudriere.conf\n$ETC/poudriere.d/131amd64-poudriere.conf\n" \ "$SYSCONF" p --jail 131amd64 -l atf_check -o inline:"$ETC/poudriere.conf\n$ETC/poudriere.d/poudriere.conf\n$ETC/poudriere.d/131amd64-poudriere.conf\n" \ "$SYSCONF" p --jail 131amd64 -L atf_check -o inline:"$ETC/poudriere.conf\n" \ "$SYSCONF" p --jail 99amd64 -l atf_check -o match:'99amd64-poudriere.conf' \ -o not-match:'rc\.conf' \ "$SYSCONF" p --jail 99amd64 -L atf_check -o inline:"$ETC/poudriere.conf\n" \ "$SYSCONF" p -E -L atf_check -o inline:"$ETC/poudriere.conf\n$ETC/poudriere.d/131amd64-poudriere.conf\n" \ "$SYSCONF" p --jail 131amd64 -E -L atf_check -s not-exit:0 -e match:'take no names' \ "$SYSCONF" p -l ZPOOL # Shorthand p; read from the global file atf_check -o match:'ZPOOL: old' \ "$SYSCONF" p ZPOOL # Write a new name into the first file atf_check -o match:'BASEFS' \ "$SYSCONF" poudriere BASEFS=/poudriere atf_check -o match:'BASEFS=' cat "$ETC/poudriere.conf" atf_check -o not-match:'BASEFS' \ cat "$ETC/poudriere.d/131amd64-poudriere.conf" # Overlay collection: --jail appends the jail overlay last atf_check -o match:'FOO: jail' \ "$SYSCONF" poudriere --jail 131amd64 FOO # Without --jail the overlay is not in the collection atf_check -o match:'FOO: global' \ "$SYSCONF" poudriere FOO # --tree is an alias of --ports printf 'FOO=tree\n' > "$ETC/poudriere.d/default-poudriere.conf" atf_check -o match:'FOO: tree' \ "$SYSCONF" poudriere --tree default FOO atf_check -o match:'FOO: tree' \ "$SYSCONF" poudriere --ports default FOO # Rewrite the overlay's existing var atf_check -o match:'JOBS' \ "$SYSCONF" poudriere --jail 131amd64 JOBS=8 atf_check -o match:'JOBS: 8' \ "$SYSCONF" poudriere --jail 131amd64 JOBS # Attached --jail= atf_check -o match:'FOO: jail' \ "$SYSCONF" poudriere --jail=131amd64 FOO # `--' ends the nested keyword; colliding names are variables printf 'src=from-conf\nm=short\n' >> "$ETC/poudriere.conf" printf 'src=from-overlay\n' > "$ETC/poudriere.d/src.conf" atf_check -o match:'src: from-conf' \ "$SYSCONF" p -- src atf_check -o match:'m: short' \ "$SYSCONF" p -- m atf_check -s not-exit:0 -e match:"unknown variable 'make'" \ "$SYSCONF" p -- make atf_check -o match:'src: from-overlay' \ "$SYSCONF" p src src # -f replaces discovery printf 'BAR=only\n' > "$ETC/other.conf" atf_check -o match:'BAR: only' \ "$SYSCONF" poudriere -f "$ETC/other.conf" BAR # Missing globals unset POUDRIERE_ETC export POUDRIERE_ETC="$( pwd )/missing-etc" mkdir -p "$POUDRIERE_ETC" atf_check -s not-exit:0 -e match:'poudriere.conf' \ "$SYSCONF" p ZPOOL } poudriere_sysrc_cleanup() { rm -rf "$( pwd )/petc" "$( pwd )/missing-etc" } atf_test_case poudriere_overlays cleanup poudriere_overlays_head() { atf_set "descr" \ "poudriere make/src/src-env overlays with --jail/--tree/--set" } poudriere_overlays_body() { find_sysconf ETC="$( pwd )/petc" D="$ETC/poudriere.d" mkdir -p "$D" export POUDRIERE_ETC="$ETC" printf 'CFLAGS=global\n' > "$D/make.conf" printf 'CFLAGS=jail\n' > "$D/131amd64-make.conf" printf 'CFLAGS=tree\n' > "$D/default-make.conf" printf 'CFLAGS=set\n' > "$D/dev-make.conf" printf 'CFLAGS=combo\n' > "$D/131amd64-default-make.conf" # Shorthand p m atf_check -o inline:'CFLAGS: global\n' \ "$SYSCONF" p m CFLAGS atf_check -o inline:'CFLAGS: jail\n' \ "$SYSCONF" poudriere make --jail 131amd64 CFLAGS atf_check -o inline:'CFLAGS: tree\n' \ "$SYSCONF" p m --tree default CFLAGS atf_check -o inline:'CFLAGS: tree\n' \ "$SYSCONF" poudriere make --ports default CFLAGS atf_check -o inline:'CFLAGS: set\n' \ "$SYSCONF" poudriere make --set dev CFLAGS # jail-tree combo is last of those two atf_check -o inline:'CFLAGS: combo\n' \ "$SYSCONF" poudriere make --jail 131amd64 --tree default CFLAGS # Rewrite overlay's existing name; new name goes to global atf_check -o match:'CFLAGS' \ "$SYSCONF" poudriere make --jail 131amd64 CFLAGS=-O2 atf_check -o match:'CFLAGS=-O2' cat "$D/131amd64-make.conf" atf_check -o match:'CFLAGS=global' cat "$D/make.conf" atf_check -o match:'CXXFLAGS' \ "$SYSCONF" poudriere make --jail 131amd64 CXXFLAGS=-pipe atf_check -o match:'CXXFLAGS=-pipe' cat "$D/make.conf" atf_check -o not-match:'CXXFLAGS' cat "$D/131amd64-make.conf" # Create missing global rm -f "$D/make.conf" atf_check -o match:'LDFLAGS' \ "$SYSCONF" p m LDFLAGS=-L/usr/local/lib atf_check -o match:'LDFLAGS=-L/usr/local/lib' cat "$D/make.conf" # src vs src-env; --tree ignored (no tree-src.conf in poudriere(8)) printf 'WITHOUT_FOO=\n' > "$D/src.conf" printf 'WITHOUT_TREE=\n' > "$D/default-src.conf" printf 'SRC_ENV_VAR=1\n' > "$D/src-env.conf" printf 'SRC_ENV_VAR=tree\n' > "$D/default-src-env.conf" atf_check -o inline:'WITHOUT_FOO (present)\n' \ "$SYSCONF" poudriere src WITHOUT_FOO atf_check -s not-exit:0 -e match:'unknown directive' \ "$SYSCONF" poudriere src --tree default WITHOUT_TREE atf_check -o inline:'SRC_ENV_VAR: 1\n' \ "$SYSCONF" poudriere src-env SRC_ENV_VAR atf_check -o inline:'SRC_ENV_VAR: 1\n' \ "$SYSCONF" poudriere src-env --tree default SRC_ENV_VAR atf_check -o inline:'SRC_ENV_VAR: 1\n' \ "$SYSCONF" p src-e SRC_ENV_VAR # Ambiguous nested prefix atf_check -s not-exit:0 -e match:'ambiguous' -e match:'src' \ -e match:'src-env' \ "$SYSCONF" p s FOO # -l lists the collection atf_check -o match:'make.conf' -o match:'131amd64-make.conf' \ "$SYSCONF" poudriere make --jail 131amd64 -l # -L lists every poudriere(8) stem, including files not on disk atf_check -o inline:"$D/make.conf\n$D/abc-make.conf\n$D/xyz-make.conf\n$D/160-make.conf\n$D/xyz-abc-make.conf\n$D/160-xyz-make.conf\n$D/160-abc-make.conf\n$D/160-xyz-abc-make.conf\n" \ "$SYSCONF" p m --jail 160 --set abc --tree xyz -L atf_check -o inline:"$D/make.conf\n$D/xyz-make.conf\n$D/160-make.conf\n$D/160-xyz-make.conf\n" \ "$SYSCONF" p m --jail 160 --tree xyz -L atf_check -o inline:"$D/make.conf\n" \ "$SYSCONF" p m --jail 160 --set abc --tree xyz -l atf_check -o inline:"$D/make.conf\n" \ "$SYSCONF" p m --jail 160 --set abc --tree xyz -E -L atf_check -o inline:"$D/src.conf\n$D/abc-src.conf\n$D/160-src.conf\n" \ "$SYSCONF" p src --jail 160 --set abc --tree xyz -L atf_check -o inline:"$D/src.conf\n$D/160-src.conf\n" \ "$SYSCONF" p src --jail 160 --tree xyz -L atf_check -o inline:"$D/src-env.conf\n$D/abc-src-env.conf\n$D/160-src-env.conf\n" \ "$SYSCONF" p src-env --jail 160 --set abc --tree xyz -L atf_check -o inline:"$D/src-env.conf\n" \ "$SYSCONF" p src-env --jail 160 --set abc --tree xyz -E -L } poudriere_overlays_cleanup() { rm -rf "$( pwd )/petc" } atf_init_test_cases() { atf_add_test_case make_src_knobs atf_add_test_case make_append_accumulate atf_add_test_case make_strike_last_assign atf_add_test_case src_triad_and_trail atf_add_test_case src_env_rejected atf_add_test_case env_overrides atf_add_test_case attached_f_passthrough atf_add_test_case verbatim_backslash atf_add_test_case equal_value_nocheck_mtime atf_add_test_case sysctl_oid_range atf_add_test_case max_bytes_cap atf_add_test_case target_prefix atf_add_test_case poudriere_sysrc atf_add_test_case poudriere_overlays }