2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-12 12:36:23 +00:00

test(genesis): cover release manifest guards

This commit is contained in:
Vinícius Ferrão
2026-09-04 16:16:23 -03:00
parent 2a434beaad
commit be52c514d0
3 changed files with 132 additions and 21 deletions
+35 -6
View File
@@ -49,7 +49,6 @@ if (@missing_requirements) {
my $tmp = tempdir(CLEANUP => 1);
my $target = 'alma+epel-10-' . do { my $m = `uname -m`; chomp $m; $m };
my @architectures = architectures();
my $architecture_count = scalar(@architectures);
my $xcat_version = '2.19.0';
my $xcat_release = 'snap202609040000';
my $xcat_revision = 'c' x 40;
@@ -85,8 +84,9 @@ write_checksums($VERSION_1_RELEASE);
{
my %m = read_manifest("$RealBin/../packages-manifest.conf");
ok($m{common} && %{ $m{common} }, 'the shipped manifest has a [common] section');
my @missing = grep { !exists $m{common}{ rpm_package_name($_) } } @architectures;
is_deeply(\@missing, [],
my @expected = sort map { rpm_package_name($_) }
qw(x86 x86_64 ppc64 ppc64le armv7hf aarch64 riscv64 s390x);
is_deeply([ sort keys %{ $m{common} } ], \@expected,
'the shared RPM manifest lists every Genesis architecture');
}
@@ -166,19 +166,48 @@ sub run_publish {
{
my ($rc, $out, $common) = run_publish($RELEASE, 'full');
is($rc, 0, 'a complete release publishes') or diag($out);
is(scalar(grep { !/\.src\.rpm$/ } glob("$common/*.rpm")), $architecture_count,
is(scalar(grep { !/\.src\.rpm$/ } glob("$common/*.rpm")), 8,
'the published shared repo carries every architecture');
like($out, qr/\[verify-repo\] common complete/, 'the shared repo is gated against [common]');
like($out, qr/\[verify-repo\] common complete: 8 packages present/,
'the shared repo is gated against [common]');
}
{
my ($rc, $out, $common) = run_publish($VERSION_1_RELEASE, 'version-1');
is($rc, 0, 'a complete version 1 release publishes') or diag($out);
is(scalar(grep { !/\.src\.rpm$/ } glob("$common/*.rpm")),
scalar(@version_1_architectures),
7,
'the version 1 repository keeps its seven architectures');
ok(!glob("$common/" . rpm_package_name('s390x') . '-*.rpm'),
'the version 1 repository does not require s390x');
like($out, qr/\[verify-repo\] common complete: 7 packages present/,
'the version 1 repository is gated against seven packages');
}
{
my ($rc, $out, $common) = run_publish(
$VERSION_1_RELEASE,
'missing-current-package',
sub { delete $_[0]->{ rpm_package_name('s390x') } },
);
isnt($rc, 0, 'a version 1 release does not hide an incomplete current manifest');
like($out, qr/\[common\] is missing supported packages: .*s390x/,
'the manifest failure identifies the missing current package');
ok(!-d $common || !glob("$common/*.rpm"),
'an incomplete current manifest publishes nothing');
}
{
my ($rc, $out, $common) = run_publish(
$RELEASE,
'unknown-current-package',
sub { $_[0]->{'xCAT-genesis-openembedded-unknown'} = '>= 2.18.0' },
);
isnt($rc, 0, 'an unknown shared manifest package is refused');
like($out, qr/\[common\] has unsupported packages: xCAT-genesis-openembedded-unknown/,
'the manifest failure identifies the unknown package');
ok(!-d $common || !glob("$common/*.rpm"),
'an unknown shared manifest package publishes nothing');
}
# ---- an incomplete release is refused, and publishes nothing --------------------------------------
+66 -12
View File
@@ -75,7 +75,7 @@ SKIP: {
}
SKIP: {
skip 'APT repository tools are not installed', 62
skip 'APT repository tools are not installed', 69
unless $^O eq 'linux'
&& command_exists('dpkg-deb')
&& command_exists('apt-ftparchive');
@@ -301,14 +301,7 @@ sub run_apt_consumer {
my $manifest = $args{manifest};
unless ($manifest) {
$manifest = "$args{output}/manifest.conf";
make_path($args{output});
# plus the shipped [shared] section verbatim: publishing a release gates the shared pool
# against it, and a manifest without it is refused rather than silently ungated.
my $shipped = read_binary("$repo_root/debs-manifest.conf");
my ($shared) = $shipped =~ /^(\[shared\]\n(?:[^\[]*))/ms;
BAIL_OUT('debs-manifest.conf has no [shared] section') unless $shared;
write_binary($manifest,
join('', map { "[$_-amd64]\nxcat-genesis-base=*\n" } @APT_SUITES) . "\n" . $shared);
write_apt_manifest($manifest);
}
return run_capture(
$args{log},
@@ -326,6 +319,23 @@ sub run_apt_consumer {
);
}
sub write_apt_manifest {
my ($path, $mutate) = @_;
my $shipped = read_binary("$repo_root/debs-manifest.conf");
my ($section) = $shipped =~ /^\[shared\]\n([^\[]*)/ms;
BAIL_OUT('debs-manifest.conf has no [shared] section') unless defined $section;
my %shared = map { /^([^=]+)=(.*)$/ ? ($1 => $2) : () }
grep { length } split(/\n/, $section);
$mutate->(\%shared) if $mutate;
make_path((File::Basename::dirname($path)));
write_binary(
$path,
join('', map { "[$_-amd64]\nxcat-genesis-base=*\n" } @APT_SUITES)
. "\n[shared]\n"
. join('', map { "$_=$shared{$_}\n" } sort keys %shared),
);
}
# Stage one legacy genesis-base deb for the noble suite only -- enough for the runs that publish
# no Genesis release.
sub stage_legacy_deb {
@@ -398,9 +408,8 @@ sub test_deb_consumer {
} architectures();
is_deeply([ genesis_deb_names($shared_pool) ], \@expected_packages,
'shared APT pool contains one complete Genesis release');
my $architecture_count = scalar(architectures());
like(read_binary($log),
qr/\[verify-repo\] shared pool complete: \Q$architecture_count\E packages present/,
qr/\[verify-repo\] shared pool complete: 8 packages present/,
'the shared pool is gated against the manifest\'s [shared] section');
my @suite_packages;
for my $codename (@APT_SUITES) {
@@ -549,10 +558,55 @@ sub test_version_1_deb_consumer {
my $pool = "$apt_root/pool/main/xcat-genesis-openembedded";
is($status, 0, 'APT accepts a complete version 1 release');
is(scalar(genesis_deb_names($pool)), scalar(@release_architectures),
is(scalar(genesis_deb_names($pool)), 7,
'the version 1 pool keeps its seven architectures');
is(scalar(grep { /s390x/ } genesis_deb_names($pool)), 0,
'the version 1 pool does not require s390x');
like(read_binary($log),
qr/\[verify-repo\] shared pool complete: 7 packages present/,
'the version 1 pool is gated against seven packages');
my $missing_manifest = "$tmp/deb-version-1-missing.conf";
write_apt_manifest(
$missing_manifest,
sub { delete $_[0]->{ deb_package_name('s390x') } },
);
my $missing_apt = "$tmp/apt-version-1-missing";
my $missing_output = "$tmp/deb-version-1-missing-output";
stage_apt_suites($missing_output, "$tmp/deb-version-1-missing-legacy");
my $missing_log = "$tmp/deb-version-1-missing.log";
my $missing_status = run_apt_consumer(
log => $missing_log, output => $missing_output, apt_dir => $missing_apt,
manifest => $missing_manifest,
extra => [ '--genesis-release', $release_root ],
);
isnt($missing_status, 0,
'a version 1 release does not hide an incomplete current shared manifest');
like(read_binary($missing_log), qr/\[shared\] is missing supported packages: .*s390x/,
'the shared manifest failure identifies the missing current package');
ok(!-d "$missing_apt/pool/main/xcat-genesis-openembedded",
'an incomplete shared manifest publishes nothing');
my $unknown_manifest = "$tmp/deb-version-1-unknown.conf";
write_apt_manifest(
$unknown_manifest,
sub { $_[0]->{'xcat-genesis-openembedded-unknown'} = '2.*' },
);
my $unknown_apt = "$tmp/apt-version-1-unknown";
my $unknown_output = "$tmp/deb-version-1-unknown-output";
stage_apt_suites($unknown_output, "$tmp/deb-version-1-unknown-legacy");
my $unknown_log = "$tmp/deb-version-1-unknown.log";
my $unknown_status = run_apt_consumer(
log => $unknown_log, output => $unknown_output, apt_dir => $unknown_apt,
manifest => $unknown_manifest,
extra => [ '--genesis-release', $release_root ],
);
isnt($unknown_status, 0, 'an unknown shared manifest package is refused');
like(read_binary($unknown_log),
qr/\[shared\] has unsupported packages: xcat-genesis-openembedded-unknown/,
'the shared manifest failure identifies the unknown package');
ok(!-d "$unknown_apt/pool/main/xcat-genesis-openembedded",
'an unknown shared manifest package publishes nothing');
}
sub test_signed_common_rpm_repository {
+31 -3
View File
@@ -216,6 +216,19 @@ write_checksums($legacy_release);
ok(validate_complete_release($legacy_release),
'complete version 1 releases remain publishable');
my $invalid_legacy_release = "$tmp/invalid-legacy-release";
copy_tree($complete_release, $invalid_legacy_release);
write_release_manifest(
$invalid_legacy_release, $version, $release, $revision, $epoch,
join(',', architectures()), 'deb,rpm', 1,
);
write_checksums($invalid_legacy_release);
dies_like(
sub { validate_release($invalid_legacy_release) },
qr/Genesis architecture s390x is not valid in release version 1/,
'version 1 rejects the version 2 architecture vocabulary',
);
my $unknown_release_version = "$tmp/unknown-release-version";
copy_tree($complete_release, $unknown_release_version);
write_release_manifest(
@@ -259,12 +272,13 @@ dies_like(sub { validate_release($missing_release) }, qr/Genesis release is miss
'incomplete architecture set fails');
SKIP: {
skip 'git is not installed', 2 unless command_exists('git');
skip 'git is not installed', 4 unless command_exists('git');
my $source = "$tmp/dirty-xcat-core";
make_path("$source/xCAT-genesis-builder/oe");
make_path("$source/xCAT-genesis-builder/oe/kas");
write_binary("$source/Version", "$version\n");
write_binary("$source/xCAT-genesis-builder/oe/build", "#!/bin/sh\nexit 99\n");
write_binary("$source/xCAT-genesis-builder/oe/export", "#!/bin/sh\nexit 99\n");
write_binary("$source/xCAT-genesis-builder/oe/kas/x86_64.yml", "header: {}\n");
for my $command (
[ 'git', '-C', $source, 'init', '-q' ],
[ 'git', '-C', $source, 'add', '.' ],
@@ -286,6 +300,19 @@ SKIP: {
);
like(read_binary($log), qr/xcat-core checkout is not clean/,
'dirty checkout failure is explicit');
my $target_log = "$tmp/missing-target.log";
isnt(
run_capture(
$target_log, $builder, '--xcat-source', $source,
'--architecture', 's390x',
'--output-dir', "$tmp/missing-target-output",
),
0,
'release builder rejects an unsupported xcat-core target',
);
like(read_binary($target_log), qr/does not support Genesis architecture s390x/,
'missing target failure identifies the required xcat-core support');
}
SKIP: {
@@ -484,8 +511,9 @@ sub exercise_packager_from_unsearchable_cwd {
sub exercise_builder_tmpdir {
my $source = "$tmp/tmpdir-xcat-core";
my $oe = "$source/xCAT-genesis-builder/oe";
make_path($oe);
make_path("$oe/kas");
write_binary("$source/Version", "$version\n");
write_binary("$oe/kas/x86_64.yml", "header: {}\n");
write_binary(
"$oe/build",
<<'BUILD',