mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-21 08:33:20 +00:00
test(xcat-core): capture the Debian genesis dependency ignoring the architecture
The ppc64el and riscv64 xcat debs depend on xcat-genesis-scripts-amd64, and xcat-genesis-scripts-ppc64 depends on xcat-genesis-base-ppc64, a package no repository publishes. Nothing reports either one: the amd64 scripts package is Architecture: all, so it installs on any architecture, and the broken ppc64 dependency is never reached because nothing pulls that package. Extend debian_control_arch_coverage.t. It now reads the Depends field of xCAT/debian/control and xCATsn/debian/control, applies each architecture restriction the way dpkg-gencontrol does, and asserts that the genesis scripts a given architecture receives are that architecture's own. It also asserts that xCAT-genesis-scripts/debian/control-<arch> builds xcat-genesis-scripts-<arch> and depends on xcat-genesis-base-<arch>. Eight of the eighteen assertions fail on this tree. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
@@ -37,4 +37,102 @@ for my $ctl (@controls) {
|
||||
}
|
||||
}
|
||||
|
||||
# The genesis dependency must follow the architecture. xCAT and xCATsn are built once per
|
||||
# architecture from one control file, so an unrestricted "Depends: xcat-genesis-scripts-amd64"
|
||||
# reaches the ppc64el and riscv64 debs too. That package is Architecture: all, so it installs and
|
||||
# apt reports no error -- it lays down the x86_64 Genesis tree and pulls the 128 MB amd64
|
||||
# genesis-base, and the management node gets no Genesis for its own architecture. The rpm side
|
||||
# already selects per architecture through %{?genesistarch:Requires: xCAT-genesis-scripts-...}.
|
||||
#
|
||||
# xCAT-genesis-scripts keeps one control file per Debian architecture, and the file name is the
|
||||
# Debian architecture. Its package name and its genesis-base dependency must carry that same
|
||||
# architecture: xcat-genesis-base-ppc64 is a name no repository publishes, while the base deb
|
||||
# that builddeb-genesis-base builds for ppc64el is xcat-genesis-base-ppc64el.
|
||||
|
||||
# Return the folded value of a control field, or undef.
|
||||
sub control_field {
|
||||
my ($text, $name) = @_;
|
||||
return $1 if $text =~ /^\Q$name\E:[ \t]*(.*(?:\n[ \t]+.*)*)/m;
|
||||
return;
|
||||
}
|
||||
|
||||
# Split a dependency field into [package name, architecture restriction] pairs. Alternatives
|
||||
# separated by "|" are returned one by one, because a restriction binds to one alternative.
|
||||
sub dependency_terms {
|
||||
my ($field) = @_;
|
||||
my @terms;
|
||||
return @terms unless defined $field;
|
||||
$field =~ s/\n/ /g;
|
||||
for my $dep (split /,/, $field) {
|
||||
for my $alt (split /\|/, $dep) {
|
||||
next unless $alt =~ /^\s*([A-Za-z0-9][A-Za-z0-9+.-]*)\s*(?:\([^)]*\))?\s*(?:\[([^\]]*)\])?/;
|
||||
push @terms, [ $1, $2 ];
|
||||
}
|
||||
}
|
||||
return @terms;
|
||||
}
|
||||
|
||||
# dpkg-gencontrol drops a dependency whose architecture restriction excludes the build
|
||||
# architecture. No restriction means the dependency reaches every architecture.
|
||||
sub term_applies {
|
||||
my ($restriction, $arch) = @_;
|
||||
return 1 unless defined $restriction;
|
||||
my @tokens = grep { length } split /\s+/, $restriction;
|
||||
return 1 unless @tokens;
|
||||
my $negated = ($tokens[0] =~ /^!/) ? 1 : 0;
|
||||
my %named = map { my $t = $_; $t =~ s/^!//; $t =~ s/^any-//; ($t => 1) } @tokens;
|
||||
return $negated ? (exists $named{$arch} ? 0 : 1) : (exists $named{$arch} ? 1 : 0);
|
||||
}
|
||||
|
||||
# The architectures xCAT-genesis-scripts is packaged for, taken from its per-architecture control
|
||||
# files. riscv64 has none on purpose: its Genesis is the OpenEmbedded image.
|
||||
my $scripts_debian = "$root/xCAT-genesis-scripts/debian";
|
||||
my @scripts_arches = sort map { m{/control-(.+)$} ? $1 : () } glob("$scripts_debian/control-*");
|
||||
|
||||
SKIP: {
|
||||
skip 'xCAT-genesis-scripts has no per-architecture control files', 1 unless @scripts_arches;
|
||||
|
||||
for my $arch (@scripts_arches) {
|
||||
my $ctl = "$scripts_debian/control-$arch";
|
||||
open my $fh, '<', $ctl or die "read $ctl: $!";
|
||||
local $/; my $text = <$fh>; close $fh;
|
||||
|
||||
my ($package) = ($text =~ /^Package:\s*(\S+)/m);
|
||||
is($package, "xcat-genesis-scripts-$arch",
|
||||
"control-$arch builds xcat-genesis-scripts-$arch");
|
||||
|
||||
my @bases = grep { /^xcat-genesis-base-/ }
|
||||
map { $_->[0] } dependency_terms(control_field($text, 'Depends'));
|
||||
is_deeply(\@bases, ["xcat-genesis-base-$arch"],
|
||||
"xcat-genesis-scripts-$arch depends on xcat-genesis-base-$arch");
|
||||
}
|
||||
|
||||
for my $ctl (@controls) {
|
||||
open my $fh, '<', $ctl or die "read $ctl: $!";
|
||||
local $/; my $text = <$fh>; close $fh;
|
||||
(my $short = $ctl) =~ s{^\Q$root\E/}{};
|
||||
|
||||
my ($arch_line) = ($text =~ /^Architecture:\s*(.+)$/m);
|
||||
next unless defined $arch_line;
|
||||
my @built = grep { !/^(?:any|all)$/ } split /\s+/, $arch_line;
|
||||
|
||||
my @genesis = grep { $_->[0] =~ /^xcat-genesis-scripts-/ }
|
||||
dependency_terms(control_field($text, 'Depends'));
|
||||
|
||||
for my $arch (@built) {
|
||||
my @reaching = map { $_->[0] }
|
||||
grep { term_applies($_->[1], $arch) } @genesis;
|
||||
my @foreign = grep { $_ ne "xcat-genesis-scripts-$arch" } @reaching;
|
||||
is_deeply(\@foreign, [],
|
||||
"$short on $arch depends on no other architecture's genesis scripts");
|
||||
|
||||
my %packaged = map { $_ => 1 } @scripts_arches;
|
||||
next unless $packaged{$arch};
|
||||
ok(scalar(grep { $_ eq "xcat-genesis-scripts-$arch" } @reaching),
|
||||
"$short on $arch depends on xcat-genesis-scripts-$arch");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user