| git.druid.rocks | index | druid520 | mp | test/ | suites/ | portformat.sh |
test/suites/portformat.sh
# suite: mplib::portformat -- parse_pkg_use/resolve_slot/enabled_use
# matrices and pkg.conf grammar corners, all perl-level (no installs).
# one parse_pkg_use case: dumps a canonical map and asserts it.
puse_case() {
# $1 name, $2 pkg_use string, $3 expected dump
t_begin "$1"
reset_state
out=$(cd /root/mpbuildtest && perl -I. -Implib -Mmplib::portformat=parse_pkg_use -e '
my $u = parse_pkg_use($ARGV[0]);
for my $f (sort keys %$u) {
print "$f:", ($u->{$f}{build} ? "b" : "r"), ($u->{$f}{default} ? "d" : "-"), ":", join(",", @{$u->{$f}{deps}}), ";";
}
' "$2" 2>&1)
if [ "$out" != "$3" ]; then
t_fail "$CUR_TEST (parse_pkg_use($2) = $out, expected $3)"
return
fi
t_pass
}
run_parse_pkg_use_matrix() {
puse_case puse_single_flag 'ssl' 'ssl:r-:;'
puse_case puse_flag_with_dep 'ssl:%openssl' 'ssl:r-:%openssl;'
puse_case puse_multi_deps 'x11:libxcb,libx11' 'x11:r-:libxcb,libx11;'
puse_case puse_buildonly 'test:b:check' 'test:b-:check;'
puse_case puse_bare_and_deps 'oss x11:libxcb' 'oss:r-:;x11:r-:libxcb;'
puse_case puse_buildonly_multi 'doc:b:gtk-doc,doxygen' 'doc:b-:gtk-doc,doxygen;'
puse_case puse_empty '' ''
puse_case puse_trailing_colon 'ssl:' 'ssl:r-:;'
puse_case puse_empty_flag ':dep' ''
puse_case puse_whitespace 'ssl x11:libx11' 'ssl:r-:;x11:r-:libx11;'
puse_case puse_flag_with_slot_dep 'v:%curl:nossl' 'v:r-:%curl:nossl;'
# "+flag" (default-enabled -- mplib::portformat::enabled_use's own
# fallback-when-nothing-configured, see the enuse_default_* cases
# below) strips the leading "+" from the flag's NAME (it is not part
# of it -- an exported USE_+flag=1 wouldn't even parse as a shell
# variable) while still accepting the same b:/deps grammar after it.
puse_case puse_default_bare '+ssl' 'ssl:rd:;'
puse_case puse_default_with_dep '+ssl:%openssl' 'ssl:rd:%openssl;'
puse_case puse_default_buildonly '+test:b:check' 'test:bd:check;'
puse_case puse_default_and_normal '+a b' 'a:rd:;b:r-:;'
}
# one resolve_slot case: builds a fake pc hash and asserts the composed
# slot under a given enabled-USE set.
rslot_case() {
# $1 name, $2 pkg_slot, $3 pkg_slot_use, $4 enabled flags, $5 expected
t_begin "$1"
reset_state
out=$(cd /root/mpbuildtest && perl -I. -Implib -Mmplib::portformat=resolve_slot -e '
my $pc = { pkg_slot => $ARGV[0] ne "-" ? $ARGV[0] : "", pkg_slot_use => $ARGV[1] ne "-" ? $ARGV[1] : "" };
my %en = map { $_ => 1 } grep { length } split / /, $ARGV[2];
local *mplib::portformat::enabled_use = sub { return \%en };
print resolve_slot($pc, "p");
' "$2" "$3" "$4" 2>&1)
if [ "$out" != "$5" ]; then
t_fail "$CUR_TEST (resolve_slot($2,$3,{$4}) = $out, expected $5)"
return
fi
t_pass
}
run_resolve_slot_matrix() {
rslot_case rslot_no_use - - '' ''
rslot_case rslot_static_only '12' - '' '12'
rslot_case rslot_one_flag '' 'ssl' 'ssl' 'ssl'
rslot_case rslot_flag_off '' 'ssl' '' ''
rslot_case rslot_static_plus_flag '12' 'ssl' 'ssl' '12-ssl'
rslot_case rslot_static_flag_off '12' 'ssl' '' '12'
rslot_case rslot_two_flags '' 'ssl lto' 'ssl lto' 'ssl-lto'
rslot_case rslot_two_flags_one_on '' 'ssl lto' 'ssl' 'ssl'
rslot_case rslot_order_declared '' 'lto ssl' 'ssl lto' 'lto-ssl'
rslot_case rslot_three_flags '9' 'a b c' 'a c' '9-a-c'
rslot_case rslot_extra_enabled_ignored '' 'ssl' 'ssl lto xyz' 'ssl'
}
# one enabled_use case: global USE= plus a per-package section, asserts
# the effective set.
enuse_case() {
# $1 name, $2 pkg name, $3 global USE line (or -), $4 pconf USE line (or -)
# $5 expected set
t_begin "$1"
reset_state
printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
[ "$3" != "-" ] && printf 'USE=%s\n' "$3" >> "$CONF"
if [ "$4" != "-" ]; then
printf '%s:\n\tUSE=%s\n' "$2" "$4" >> "$CONF"
fi
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw($CFG load);
use mplib::portformat qw(enabled_use);
load({ FORCE=>0, NODEPS=>0, UNMASK=>0, DRYRUN=>0, CLIOVERLAY=>[] });
my %en = %{enabled_use($ARGV[0])};
print join(",", sort keys %en);
' "$2" 2>&1)
if [ "$out" != "$5" ]; then
t_fail "$CUR_TEST (enabled_use($2) = $out, expected $5)"
return
fi
t_pass
}
run_enabled_use_matrix() {
enuse_case enuse_global_only 'p' 'ssl x11' - 'ssl,x11'
enuse_case enuse_perpkg_wins 'p' 'ssl' 'nossl' 'nossl'
enuse_case enuse_perpkg_only 'p' - 'ssl' 'ssl'
enuse_case enuse_none 'p' - - ''
enuse_case enuse_slotted_fallback 'p:v' - 'ssl' 'ssl'
enuse_case enuse_ignores_undeclared 'p' 'ssl' - 'ssl'
}
# like enuse_case, but ALSO passes a pkg_use string through to
# enabled_use's second (optional) argument -- proves the "+flag"
# default-enabled fallback (see puse_default_* above) only ever applies
# when NEITHER a global nor a per-package USE= is configured at all (an
# empty one still wins outright, same as a non-empty one), and that
# USE_NONE -- not a merely-empty persisted value -- is what "explicitly
# nothing, including no defaults" round-trips as.
enuse_default_case() {
# $1 name, $2 pkg name, $3 pkg_use string, $4 global USE line (or -),
# $5 pconf USE line (or -), $6 expected set
t_begin "$1"
reset_state
printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
[ "$4" != "-" ] && printf 'USE=%s\n' "$4" >> "$CONF"
if [ "$5" != "-" ]; then
printf '%s:\n\tUSE=%s\n' "$2" "$5" >> "$CONF"
fi
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw($CFG load);
use mplib::portformat qw(enabled_use parse_pkg_use);
load({ FORCE=>0, NODEPS=>0, UNMASK=>0, DRYRUN=>0, CLIOVERLAY=>[] });
my $declared = parse_pkg_use($ARGV[1]);
my %en = %{enabled_use($ARGV[0], $declared)};
print join(",", sort keys %en);
' "$2" "$3" 2>&1)
if [ "$out" != "$6" ]; then
t_fail "$CUR_TEST (enabled_use($2,{$3}) = $out, expected $6)"
return
fi
t_pass
}
run_enabled_use_default_matrix() {
enuse_default_case enuse_default_fallback 'p' '+ssl +lto' - - 'lto,ssl'
enuse_default_case enuse_default_mixed 'p' '+ssl lto' - - 'ssl'
enuse_default_case enuse_default_none_declared 'p' 'ssl' - - ''
# global USE= is a flat, system-wide list never written with THIS
# package's own defaults in mind (the pre-existing design: flip on a
# same-named flag on whatever port happens to declare it) -- it ADDS
# to declared defaults rather than replacing them outright, or an
# unrelated global USE=x11 (say, meant for some other port entirely)
# would silently disable every "+flag" default on every OTHER
# package too, exactly the real bug a NetBSD install of meta/mp's own
# command/extension flags hit.
enuse_default_case enuse_default_global_adds 'p' '+ssl' 'x11' - 'ssl,x11'
enuse_default_case enuse_default_empty_global_keeps_defaults 'p' '+ssl' '' - 'ssl'
# a per-package override, by contrast, IS specific to this exact
# package and IS authoritative/complete -- mp.use's own toggle
# mechanism already folds this package's defaults into it the moment
# anything is first toggled, so replacing outright (not adding) is
# correct here, and is exactly what makes "mp use pkg -lastdefault"
# (see enuse_default_none_sentinel below) actually turn it off.
enuse_default_case enuse_default_perpkg_overrides 'p' '+ssl' - 'x11' 'x11'
enuse_default_case enuse_default_none_sentinel 'p' '+ssl' - '-none-' ''
# the exact reported real-world shape: several "+flag" defaults (like
# meta/mp's own ~34 command/extension flags), a global USE= set for
# something completely unrelated to any of them -- every declared
# default must still survive, not just one.
enuse_default_case enuse_default_many_survive_unrelated_global \
'p' '+install +remove +commands' 'totally_unrelated_flag' - \
'commands,install,remove,totally_unrelated_flag'
# a raw USE= value isn't limited to a plain bare-name list -- "mp use"
# is a convenience wrapper, not the only way to express a toggle. a
# +flag/-flag token in a raw USE= (global or per-package) is a DELTA
# over declared defaults, the exact same +/- syntax "mp use" itself
# takes as CLI arguments, just hand-written directly into mp.conf.
# this is the exact real-world shape that motivated it: several
# "+flag" defaults (commands/extensions), one turned off by hand.
enuse_default_case enuse_default_perpkg_delta \
'p' '+ssl +lto' - '-ssl +extra' 'extra,lto'
enuse_default_case enuse_default_global_delta \
'p' '+install +remove +commands' '-commands' - 'install,remove'
# a delta value with nothing enabled at all round-trips as genuinely
# empty, same as a bare empty per-package override does.
enuse_default_case enuse_default_perpkg_delta_to_none \
'p' '+ssl' - '-ssl' ''
}
# like enuse_default_case, but for a USE= value expected to fail() --
# mixing a bare token into a +/- delta is ambiguous (add-to-defaults, or
# the complete literal set?) and rejected the same way use.pl itself
# rejects a bare CLI argument.
enuse_default_fail_case() {
# $1 name, $2 pkg name, $3 pkg_use string, $4 global USE line (or -),
# $5 pconf USE line (or -), $6 expected substring in the error
t_begin "$1"
reset_state
printf 'GLOBAL_DEPS=" "\n' >> "$CONF"
[ "$4" != "-" ] && printf 'USE=%s\n' "$4" >> "$CONF"
if [ "$5" != "-" ]; then
printf '%s:\n\tUSE=%s\n' "$2" "$5" >> "$CONF"
fi
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw($CFG load);
use mplib::portformat qw(enabled_use parse_pkg_use);
load({ FORCE=>0, NODEPS=>0, UNMASK=>0, DRYRUN=>0, CLIOVERLAY=>[] });
my $declared = parse_pkg_use($ARGV[1]);
my %en = %{enabled_use($ARGV[0], $declared)};
print join(",", sort keys %en);
' "$2" "$3" 2>&1)
rc=$?
assert_exit_nonzero "$rc" "$CUR_TEST (expected failure, got success: $out)" || return
assert_contains "$out" "$6" "$CUR_TEST (error text: $out)" || return
t_pass
}
run_enabled_use_delta_fail_matrix() {
enuse_default_fail_case enuse_delta_perpkg_mixed_bare \
'p' '+ssl +lto' - 'ssl +extra' "mixes a bare flag ('ssl')"
enuse_default_fail_case enuse_delta_global_mixed_bare \
'p' '+ssl +lto' 'lto -ssl' - "mixes a bare flag ('lto')"
}
run_portformat_suite() {
run_parse_pkg_use_matrix
run_resolve_slot_matrix
run_enabled_use_matrix
run_enabled_use_default_matrix
run_enabled_use_delta_fail_matrix
}