mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-20 22:55:40 +00:00
test(packaging): query resolved RPM dependencies
This commit is contained in:
@@ -17,12 +17,14 @@ jobs:
|
||||
- name: Test Debian package lifecycle
|
||||
run: prove -v xCAT-test/native/xcatd_debian_lifecycle.t xCAT-test/native/xcatd_restart_callers.t xCAT-test/native/apache_package_lifecycle.t xCAT-test/native/package_upgrade_logging.t
|
||||
- name: Install package test dependencies
|
||||
run: sudo apt-get install -y --no-install-recommends cpio createrepo-c rsync gnupg libxml-libxml-perl
|
||||
run: sudo apt-get install -y --no-install-recommends cpio createrepo-c rsync gnupg libxml-libxml-perl python3-rpm
|
||||
- name: Exercise probe package payloads
|
||||
if: ${{ !cancelled() }}
|
||||
run: prove xCAT-test/native/probe_package_payload.t
|
||||
- name: Exercise release repositories
|
||||
run: prove xCAT-test/native/release_repository.t
|
||||
- name: Check parsed package relations
|
||||
run: prove xCAT-test/native/package_relations.t
|
||||
- name: Prepare xCAT syslog directory
|
||||
if: ${{ !cancelled() }}
|
||||
run: sudo install -d -o syslog -g adm -m 0750 /var/log/xcat
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Temp qw(tempdir);
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
use Test::More;
|
||||
use XCAT::Test::File qw(repo_path);
|
||||
use XCAT::Test::Package qw(run_in);
|
||||
|
||||
plan skip_all => 'requires Linux RPM tooling' unless $^O eq 'linux';
|
||||
local %ENV = (%ENV, HOME => tempdir(CLEANUP => 1));
|
||||
delete @ENV{qw(pcm fsm s390x)};
|
||||
my @platforms = (
|
||||
['EL7', 'rhel 7', 0], ['EL8', 'rhel 8', 1], ['EL9', 'rhel 9', 1],
|
||||
['EL10', 'rhel 10', 1], ['Fedora', 'fedora 44', 1],
|
||||
['SLES12', 'suse_version 1315', 0], ['SLES15', 'suse_version 1500', 1],
|
||||
['openEuler', 'openEuler 2', 0],
|
||||
);
|
||||
my @images = map { "xCAT-genesis-openembedded-$_" } qw(x86_64 ppc64le riscv64 s390x);
|
||||
my %legacy = (x86_64 => 'x86_64', ppc64le => 'ppc64', aarch64 => 'aarch64');
|
||||
for my $platform (@platforms) {
|
||||
my ($name, $macro, $weak) = @$platform;
|
||||
for my $arch (qw(x86_64 ppc64le aarch64 riscv64 s390x)) {
|
||||
for my $pkg (qw(xCAT xCATsn)) {
|
||||
my $requires = query($pkg, $arch, $macro, '--requires');
|
||||
my $recommends = query($pkg, $arch, $macro, '--recommends');
|
||||
unlike($requires, qr/xCAT-genesis-openembedded-/, "$name $arch $pkg never requires optional images");
|
||||
my @actual = sort grep { /^xCAT-genesis-openembedded-/ } split /\n/, $recommends;
|
||||
is_deeply(\@actual, $weak ? [sort @images] : [], "$name $arch $pkg optional image recommendations");
|
||||
my @scripts = grep { /^xCAT-genesis-scripts-/ } split /\n/, $requires;
|
||||
is_deeply(\@scripts, $legacy{$arch}
|
||||
? ["xCAT-genesis-scripts-$legacy{$arch} = 1:9.9.9-1"] : [],
|
||||
"$name $arch $pkg required legacy Genesis scripts");
|
||||
if ($arch eq 'riscv64') {
|
||||
like($requires, $pkg eq 'xCAT' ? qr/^ipmitool-xcat >= 1\.8\.18-4$/m : qr/^ipmitool-xcat >= 1\.8\.17-1$/m,
|
||||
"$name $pkg RISC-V IPMI dependency");
|
||||
unlike($requires, qr/xCAT-genesis-scripts-|xnba-undi|syslinux-xcat|elilo-xcat|%\{/,
|
||||
"$name $pkg RISC-V has no unavailable legacy payload or unresolved macro");
|
||||
}
|
||||
}
|
||||
}
|
||||
for my $s390 (0, 1) {
|
||||
local $ENV{s390x} = $s390;
|
||||
my $requires = query('xCAT-server', 'x86_64', $macro, '--requires');
|
||||
like($requires, qr/^perl\(Digest::SHA\)$/m, "$name server s390x=$s390 requires Digest::SHA");
|
||||
next if $s390;
|
||||
my $recommends = query('xCAT-server', 'x86_64', $macro, '--recommends');
|
||||
is(scalar(grep { $_ eq 'perl-DB_File' } split /\n/, $requires), $name eq 'EL10' ? 0 : 1,
|
||||
"$name server hard DB_File dependency");
|
||||
is(scalar(grep { $_ eq 'perl-DB_File' } split /\n/, $recommends), $name eq 'EL10' ? 1 : 0,
|
||||
"$name server weak DB_File dependency");
|
||||
like($requires, qr/^\Q$_\E$/m, "$name server keeps $_")
|
||||
for qw(perl-Net-Telnet perl-Net-DNS perl-Crypt-CBC perl-Crypt-Rijndael);
|
||||
}
|
||||
}
|
||||
|
||||
for my $platform (@platforms) {
|
||||
my ($name, $macro) = @$platform;
|
||||
my ($rc, $filter, $err) = run_in(repo_path('.'), 'python3', '-c', <<'PY', repo_path('xCAT-server/xCAT-server.spec'), $macro);
|
||||
import rpm, sys
|
||||
for name in ('rhel', 'fedora', 'suse_version', 'openEuler'):
|
||||
rpm.delMacro(name)
|
||||
name, value = sys.argv[2].split()
|
||||
rpm.addMacro(name, value)
|
||||
rpm.addMacro('version', '9.9.9')
|
||||
rpm.addMacro('release', '1')
|
||||
rpm.addMacro('__requires_exclude', '^retained$')
|
||||
rpm.spec(sys.argv[1])
|
||||
print(rpm.expandMacro('%{?__requires_exclude}'))
|
||||
PY
|
||||
is($rc, 0, "$name parses server dependency generator policy") or BAIL_OUT($err);
|
||||
chomp $filter;
|
||||
ok('retained' =~ /$filter/, "$name keeps an inherited dependency filter");
|
||||
is('perl(DB_File)' =~ /$filter/ ? 1 : 0, $name eq 'EL10' ? 1 : 0,
|
||||
"$name automatic DB_File dependency exclusion");
|
||||
unlike('perl(Digest::SHA)', qr/$filter/, "$name keeps automatic Digest::SHA dependencies");
|
||||
}
|
||||
|
||||
for my $case (['Linux', 'rhel 8', 'iproute'], ['SUSE', 'suse_version 1500', 'iproute2']) {
|
||||
my ($name, $macro, $provider) = @$case;
|
||||
my $requires = query('xCAT-probe', 'x86_64', $macro, '--requires');
|
||||
my @providers = grep { /^iproute2?$/ } split /\n/, $requires;
|
||||
is_deeply(\@providers, [$provider], "$name probe socket tool provider");
|
||||
}
|
||||
done_testing();
|
||||
|
||||
sub query {
|
||||
my ($package, $arch, $macro, $relation) = @_;
|
||||
my $format = $relation eq '--requires'
|
||||
? '[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]'
|
||||
: '[%{RECOMMENDNAME}\n]';
|
||||
my ($rc, $out, $err) = run_in(repo_path('.'), 'rpmspec', '-q', '--target', $arch,
|
||||
(map { ('--undefine', $_) } qw(rhel fedora suse_version openEuler)),
|
||||
'--define', $macro, '--define', 'version 9.9.9', '--define', 'release 1',
|
||||
'--qf', $format, repo_path("$package/$package.spec"));
|
||||
BAIL_OUT("$package $arch $macro: $err") if $rc;
|
||||
$out =~ s/[^\S\n]+$//mg;
|
||||
return $out;
|
||||
}
|
||||
@@ -8,28 +8,6 @@ use Test::More;
|
||||
|
||||
use XCAT::Test::File qw(slurp_repo_file);
|
||||
|
||||
my $rpm_weak_dependencies = join(
|
||||
"\n",
|
||||
'%if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?suse_version} >= 1500',
|
||||
'Recommends: xCAT-genesis-openembedded-x86_64',
|
||||
'Recommends: xCAT-genesis-openembedded-ppc64le',
|
||||
'Recommends: xCAT-genesis-openembedded-riscv64',
|
||||
'Recommends: xCAT-genesis-openembedded-s390x',
|
||||
'%endif',
|
||||
);
|
||||
|
||||
my $rpm_spec = slurp_repo_file('xCAT/xCAT.spec');
|
||||
like(
|
||||
$rpm_spec,
|
||||
qr/^\Q$rpm_weak_dependencies\E$/m,
|
||||
'RPM weak dependencies stay inside their compatibility guard',
|
||||
);
|
||||
unlike(
|
||||
$rpm_spec,
|
||||
qr/^Requires:\s+xCAT-genesis-openembedded-/m,
|
||||
'missing OpenEmbedded images do not block an RPM upgrade',
|
||||
);
|
||||
|
||||
my $deb_control = slurp_repo_file('xCAT/debian/control');
|
||||
like(
|
||||
$deb_control,
|
||||
@@ -57,13 +35,6 @@ unlike(
|
||||
'missing OpenEmbedded images do not block a DEB upgrade',
|
||||
);
|
||||
|
||||
my $sn_rpm_spec = slurp_repo_file('xCATsn/xCATsn.spec');
|
||||
like(
|
||||
$sn_rpm_spec,
|
||||
qr/^\Q$rpm_weak_dependencies\E$/m,
|
||||
'service-node weak dependencies stay inside their compatibility guard',
|
||||
);
|
||||
|
||||
my $sn_deb_control = slurp_repo_file('xCATsn/debian/control');
|
||||
like(
|
||||
$sn_deb_control,
|
||||
|
||||
@@ -7,66 +7,9 @@ use lib "$FindBin::Bin/../lib";
|
||||
use lib "$FindBin::Bin/../../build-utils/lib";
|
||||
use Test::More;
|
||||
|
||||
use XCAT::Test::File qw(repo_path slurp_repo_file);
|
||||
use XCAT::Test::File qw(repo_path);
|
||||
use XCAT::BuildUtils qw(targetarch_from_target);
|
||||
|
||||
# riscv64 packaging: the arch-named packages (xCAT, xCATsn) must resolve their
|
||||
# architecture token and dependencies for riscv64, and the build scripts must
|
||||
# know the riscv64 package names. The Genesis image comes from the OpenEmbedded
|
||||
# packages, so there is no arch-named Genesis package to resolve here.
|
||||
|
||||
my $xcat = slurp_repo_file('xCAT/xCAT.spec');
|
||||
my ($xcat_rv) = $xcat =~ /^%ifarch riscv64\n((?:#[^\n]*\n|Requires:[^\n]*\n)*)%endif$/m;
|
||||
like( $xcat_rv || '', qr/^Requires: ipmitool-xcat >= 1\.8\.18-4$/m, 'xCAT.spec requires ipmitool-xcat on riscv64' );
|
||||
unlike( $xcat_rv || '', qr/xnba-undi|syslinux-xcat|elilo-xcat/, 'xCAT.spec does not require the x86 PXE loaders on riscv64' );
|
||||
|
||||
# riscv64 has no legacy Genesis package: the requirement must disappear rather than
|
||||
# resolve to an unsatisfiable name, and the OpenEmbedded image is recommended instead.
|
||||
like( $xcat, qr/^%\{\?genesistarch:Requires: xCAT-genesis-scripts-%\{genesistarch\} = 1:%\{version\}-%\{release\}\}$/m, 'xCAT.spec asks for the legacy Genesis package only where the architecture has one' );
|
||||
like( $xcat, qr/^Recommends: xCAT-genesis-openembedded-riscv64$/m, 'xCAT.spec recommends the RISC-V OpenEmbedded Genesis image' );
|
||||
|
||||
SKIP: {
|
||||
my $rpmspec = qx(command -v rpmspec 2>/dev/null);
|
||||
chomp($rpmspec);
|
||||
skip 'rpmspec is not installed', 2 unless $rpmspec && -x $rpmspec;
|
||||
|
||||
my $spec = repo_path('xCAT/xCAT.spec');
|
||||
open( my $requires_fh, '-|',
|
||||
$rpmspec, '-q', '--target', 'riscv64', '--requires', $spec )
|
||||
or BAIL_OUT("unable to run $rpmspec: $!");
|
||||
my $requires = do { local $/; <$requires_fh> };
|
||||
close($requires_fh)
|
||||
or BAIL_OUT("rpmspec failed for $spec with status " . ($? >> 8));
|
||||
|
||||
unlike( $requires, qr/genesis-scripts/, 'a riscv64 build requires no legacy Genesis package' );
|
||||
unlike( $requires, qr/\Q%{genesistarch}\E/, 'a riscv64 build leaves no unexpanded architecture macro' );
|
||||
}
|
||||
|
||||
my $xcatsn = slurp_repo_file('xCATsn/xCATsn.spec');
|
||||
my ($xcatsn_rv) = $xcatsn =~ /^%ifarch [^\n]*\briscv64\b[^\n]*\n((?:#[^\n]*\n|Requires:[^\n]*\n)*)%endif$/m;
|
||||
like( $xcatsn_rv || '', qr/^Requires: ipmitool-xcat >= 1\.8\.17-1$/m, 'xCATsn.spec requires ipmitool-xcat on riscv64' );
|
||||
like( $xcatsn, qr/^Recommends: xCAT-genesis-openembedded-riscv64$/m, 'xCATsn.spec recommends the RISC-V OpenEmbedded Genesis image' );
|
||||
|
||||
my $server = slurp_repo_file('xCAT-server/xCAT-server.spec');
|
||||
like( $server, qr/^Recommends: perl-DB_File$/m, 'xCAT-server.spec recommends perl-DB_File on EL10 (riscv64 has no EPEL to provide it)' );
|
||||
like(
|
||||
$server,
|
||||
qr/^%if 0%\{\?rhel\} >= 10\nRecommends: perl-DB_File\n/m,
|
||||
'the weak perl-DB_File dependency is limited to EL10, where riscv64 has no EPEL',
|
||||
);
|
||||
like(
|
||||
$server,
|
||||
qr/^%else\nRequires: perl-DB_File\n%endif$/m,
|
||||
'build hosts without weak dependencies keep the hard perl-DB_File requirement',
|
||||
);
|
||||
like(
|
||||
$server,
|
||||
qr/^%global __requires_exclude %\{\?__requires_exclude:%\{__requires_exclude\}\|\}\^perl\\\\\(DB_File\\\\\)\$$/m,
|
||||
'xCAT-server.spec appends the generated perl(DB_File) requirement to the build root filter',
|
||||
);
|
||||
like( $server, qr/^Requires: perl-Net-Telnet perl-Net-DNS perl-Crypt-CBC perl-Crypt-Rijndael$/m, 'xCAT-server.spec keeps the other EL perl requires' );
|
||||
|
||||
|
||||
my $architectures = repo_path('build-utils/rpm-architectures.sh');
|
||||
is(system('sh', '-n', $architectures), 0, 'the shared build architecture data parses as POSIX shell');
|
||||
open(
|
||||
|
||||
@@ -1,42 +1,14 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Spec;
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
use Test::More;
|
||||
use XCAT::Test::File qw(slurp_repo_file);
|
||||
|
||||
my $repo_root = File::Spec->rel2abs(
|
||||
File::Spec->catdir( $FindBin::Bin, '..', '..' )
|
||||
);
|
||||
|
||||
sub read_file {
|
||||
my ($filename) = @_;
|
||||
open( my $fh, '<', $filename )
|
||||
or die "Unable to read $filename: $!";
|
||||
my $content = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
return $content;
|
||||
}
|
||||
|
||||
my $rpm_spec = read_file(
|
||||
File::Spec->catfile( $repo_root, 'xCAT-server', 'xCAT-server.spec' )
|
||||
);
|
||||
my @rpm_sha_requirements =
|
||||
$rpm_spec =~ /^Requires:.*\bperl\(Digest::SHA\)(?:\s|$)/mg;
|
||||
is(
|
||||
scalar(@rpm_sha_requirements),
|
||||
2,
|
||||
'both RPM architecture branches require Digest::SHA',
|
||||
);
|
||||
|
||||
my $debian_control = read_file(
|
||||
File::Spec->catfile( $repo_root, 'xCAT-server', 'debian', 'control' )
|
||||
);
|
||||
like(
|
||||
$debian_control,
|
||||
qr/^Depends:.*\blibdigest-sha-perl\b/m,
|
||||
'the Debian package requires Digest::SHA',
|
||||
);
|
||||
my $control = slurp_repo_file('xCAT-server/debian/control');
|
||||
my ($server) = $control =~ /^Package: xcat-server\n(.*?)(?:\n\n|\z)/ms;
|
||||
like($server // '', qr/^Depends:.*\blibdigest-sha-perl\b/m,
|
||||
'the Debian server package requires Digest::SHA');
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user