| git.druid.rocks | index | druid520 | mp | test/ | suites/ | config_matrix.sh |
test/suites/config_matrix.sh
# suite: mplib::config -- read_conf grammar corners (quotes, comments,
# sections, indentation), write_conf round-trips, and load() precedence
# (system < user < cli overlay < sysroot < pkgconf.conf). perl-level.
# one read_conf case: writes a config file, dumps the parsed conf/pconf,
# asserts the canonical dump.
rconf_case() {
# $1 name, $2 file content, $3 expected dump
t_begin "$1"
reset_state
printf '%s' "$2" > /tmp/cm_rc.conf
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw(read_conf);
my ($c, $pc) = read_conf("/tmp/cm_rc.conf");
for my $k (sort keys %$c) { print "G:$k=$c->{$k};"; }
for my $n (sort keys %$pc) {
for my $k (sort keys %{$pc->{$n}}) { print "P:$n:$k=$pc->{$n}{$k};"; }
}
' 2>&1)
rm -f /tmp/cm_rc.conf
if [ "$out" != "$3" ]; then
t_fail "$CUR_TEST (read_conf dump = $out, expected $3)"
return
fi
t_pass
}
run_read_conf_matrix() {
rconf_case rconf_global_simple 'KEY=value
' 'G:KEY=value;'
rconf_case rconf_quoted_spaces 'KEY="a b c"
' 'G:KEY=a b c;'
rconf_case rconf_single_quoted "KEY='a b'
" 'G:KEY=a b;'
rconf_case rconf_inline_comment 'KEY=value # trailing comment
' 'G:KEY=value;'
rconf_case rconf_quoted_comment_kept 'KEY="a # not a comment"
' 'G:KEY=a # not a comment;'
rconf_case rconf_blank_and_comment '
# full line comment
KEY=x
' 'G:KEY=x;'
rconf_case rconf_section 'name:
K1=v1
K2=v2
' 'P:name:K1=v1;P:name:K2=v2;'
rconf_case rconf_section_global_mix 'GLOBAL=g
name:
K1=v1
GLOBAL2=g2
' 'G:GLOBAL=g;G:GLOBAL2=g2;P:name:K1=v1;'
rconf_case rconf_section_colon_name 'gcc:12:
CC=x
' 'P:gcc:12:CC=x;'
rconf_case rconf_port_colon_form 'port:name:
K=v
' 'P:name:K=v;'
rconf_case rconf_indented_after_section_closes 'name:
K=v
SIBLING=y
' 'G:SIBLING=y;P:name:K=v;'
rconf_case rconf_unindented_key_closes_section 'name:
K=v
OTHER=x
name:
K2=v2
' 'G:OTHER=x;P:name:K=v;P:name:K2=v2;'
rconf_case rconf_key_with_plus 'DEPS+=x
' 'G:DEPS+=x;'
rconf_case rconf_key_with_hyphen 'hook-pre=x
' 'G:hook-pre=x;'
}
# one write_conf -> read_conf round-trip case.
wconf_case() {
# $1 name, $2 perl expr producing %pconf, $3 expected key dumps
t_begin "$1"
reset_state
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw(write_conf read_conf);
my %in;
'"$2"'
write_conf("/tmp/cm_wc.conf", \%in);
my (undef, $back) = read_conf("/tmp/cm_wc.conf");
unlink("/tmp/cm_wc.conf");
for my $n (sort keys %$back) {
for my $k (sort keys %{$back->{$n}}) { print "$n:$k=$back->{$n}{$k};"; }
}
' 2>&1)
if [ "$out" != "$3" ]; then
t_fail "$CUR_TEST (write_conf round-trip = $out, expected $3)"
return
fi
t_pass
}
run_write_conf_matrix() {
wconf_case wconf_plain ' $in{p}{A} = "v";' 'p:A=v;'
wconf_case wconf_space_hash ' $in{p}{CFLAGS} = "-O2 #tuned";' 'p:CFLAGS=-O2 #tuned;'
wconf_case wconf_both_quotes ' $in{p}{X} = q{a"b};' 'p:X=a"b;'
wconf_case wconf_empty_value ' $in{p}{A} = "";' 'p:A=;'
wconf_case wconf_two_sections ' $in{p}{A} = "1"; $in{q}{B} = "2";' 'p:A=1;q:B=2;'
wconf_case wconf_delete_last_key ' $in{p}{A} = "1";' 'p:A=1;'
}
# one load() precedence case: system conf, user conf, cli overlay, and
# pkgconf.conf each set the same key; the highest-precedence wins.
prec_case() {
# $1 name, $2 system value (or -), $3 user value (or -),
# $4 cli overlay value (or -), $5 pkgconf value (or -), $6 expected
t_begin "$1"
reset_state
cp "$HOME/.mp.conf" /tmp/cm_home.orig 2>/dev/null
[ "$2" != "-" ] && printf 'PREC_KEY=%s\n' "$2" >> "$CONF"
if [ "$3" != "-" ]; then
printf 'PREC_KEY=%s\n' "$3" > "$HOME/.mp.conf"
else
rm -f "$HOME/.mp.conf"
fi
cliarg=""
if [ "$4" != "-" ]; then
printf 'PREC_KEY=%s\n' "$4" > /tmp/cm_cli.conf
cliarg="/tmp/cm_cli.conf"
fi
if [ "$5" != "-" ]; then
printf 'p:\n\tPREC_KEY=%s\n' "$5" > "$WD/pkgconf.conf"
fi
out=$(cd /root/mpbuildtest && perl -I. -Implib -e '
use mplib::config qw($CFG load);
my @cli = $ARGV[0] ne "" ? ($ARGV[0]) : ();
load({ FORCE=>0, NODEPS=>0, UNMASK=>0, DRYRUN=>0, CLIOVERLAY=>\@cli });
print "G=" . ($CFG->{conf}{PREC_KEY} // "-") . " P=" . ($CFG->{pconf}{p}{PREC_KEY} // "-") . "\n";
' "$cliarg" 2>&1)
rm -f /tmp/cm_cli.conf
if [ -f /tmp/cm_home.orig ]; then
cp /tmp/cm_home.orig "$HOME/.mp.conf"
else
rm -f "$HOME/.mp.conf"
fi
rm -f /tmp/cm_home.orig
if [ "$out" != "$6" ]; then
t_fail "$CUR_TEST (precedence dump = $out, expected $6)"
return
fi
t_pass
}
run_precedence_matrix() {
prec_case prec_system_only 'sys' - - - 'G=sys P=-'
prec_case prec_cli_over_system 'sys' - 'cli' - 'G=cli P=-'
prec_case prec_user_over_system 'sys' 'user' - - 'G=user P=-'
prec_case prec_cli_over_user 'sys' 'user' 'cli' - 'G=cli P=-'
prec_case prec_pkgconf_over_cli 'sys' 'user' 'cli' 'pkg' 'G=cli P=pkg'
prec_case prec_missing_user_keeps_system 'sys' - - - 'G=sys P=-'
}
run_config_matrix_suite() {
run_read_conf_matrix
run_write_conf_matrix
run_precedence_matrix
}