mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-21 07:08:12 +00:00
test(packaging): run the generated Debian repository helper
Build a real package and repository, then execute the generated helper with representative host architectures and releases. Check its apt configuration and preserve unrelated sources.
This commit is contained in:
@@ -77,7 +77,7 @@ jobs:
|
||||
run: |
|
||||
log=$(mktemp)
|
||||
trap 'rm -f -- "$log"' EXIT
|
||||
prove -v xCAT-test/native/install_profile_riscv64.t xCAT-test/native/netboot_profile_riscv64.t | tee "$log"
|
||||
prove -v xCAT-test/native/install_profile_riscv64.t xCAT-test/native/netboot_profile_riscv64.t xCAT-test/native/builddebs_riscv64.t | tee "$log"
|
||||
! grep -qi skipped "$log"
|
||||
rpm_lifecycle_test:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Path qw(make_path);
|
||||
use File::Slurper qw(read_text write_text);
|
||||
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::Process qw(run_command);
|
||||
use XCAT::Test::Sandbox qw(sandbox_root sandbox_run);
|
||||
|
||||
plan skip_all => 'requires a Debian-family package builder'
|
||||
unless $^O eq 'linux' && -f '/etc/debian_version';
|
||||
require Dpkg::Control::Info;
|
||||
|
||||
my $build = tempdir(CLEANUP => 1);
|
||||
make_path("$build/source", "$build/home");
|
||||
for my $entry (qw(builddebs.pl build-utils Version Release xCAT-buildkit)) {
|
||||
system('cp', '-a', repo_path($entry), "$build/source/") == 0 or die "Cannot copy $entry";
|
||||
}
|
||||
{
|
||||
local %ENV = (%ENV, HOME => "$build/home", SOURCE_DATE_EPOCH => 1750000000,
|
||||
PATH => '/usr/bin:/bin', LC_ALL => 'C');
|
||||
my ($status, $output) = run_command($^X, "$build/source/builddebs.pl",
|
||||
'--package', 'xCAT-buildkit', '--dist', 'noble', '--release', 'test1',
|
||||
'--dest', "$build/output");
|
||||
is($status, 0, 'the real Debian builder creates a package and repository') or diag($output);
|
||||
die 'the builder did not complete' if $status;
|
||||
}
|
||||
my $repository = "$build/output/xcat-core";
|
||||
ok(-x "$repository/mklocalrepo.sh", 'the builder delivers an executable repository helper');
|
||||
ok(-f "$repository/dists/noble/Release", 'the helper accompanies a published repository');
|
||||
|
||||
for my $case (['riscv64', 'riscv64'], ['ppc64le', 'ppc64el'], ['x86_64', 'amd64']) {
|
||||
my ($machine, $architecture) = @$case;
|
||||
for my $release (qw(noble jammy)) {
|
||||
subtest "$machine $release" => sub {
|
||||
my $root = sandbox_root();
|
||||
make_path("$root/etc/apt/sources.list.d");
|
||||
write_text("$root/etc/lsb-release", "DISTRIB_CODENAME=$release\n");
|
||||
write_text("$root/bin/uname", "#!/bin/sh\n[ \"\$*\" = -m ] || exit 2\nprintf '%s\\n' '$machine'\n");
|
||||
chmod 0755, "$root/bin/uname" or die $!;
|
||||
write_text("$root/etc/apt/sources.list.d/administrator.list", "preserved\n");
|
||||
for my $pass (1, 2) {
|
||||
my ($status, $output) = sandbox_run($root,
|
||||
{read_only => {$repository => '/repo'}}, '/repo/mklocalrepo.sh');
|
||||
is($status, 0, "pass $pass executes the generated helper unchanged") or diag($output);
|
||||
is(read_text("$root/etc/apt/sources.list.d/xcat-core.list"),
|
||||
"deb [arch=$architecture] file:///repo $release main\n",
|
||||
"pass $pass selects the host architecture and distribution");
|
||||
is(read_text("$root/etc/apt/sources.list.d/administrator.list"), "preserved\n",
|
||||
"pass $pass preserves unrelated sources");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for my $case (['xCAT', 'xcat'], ['xCATsn', 'xcatsn']) {
|
||||
my ($component, $package) = @$case;
|
||||
my $control = Dpkg::Control::Info->new(repo_path("$component/debian/control"));
|
||||
my ($binary) = grep { $_->{Package} eq $package } $control->get_packages();
|
||||
ok($binary, "$package has a binary package stanza");
|
||||
my %architecture = map { $_ => 1 } split /\s+/, $binary->{Architecture} // '';
|
||||
ok($architecture{$_}, "$package supports $_") for qw(riscv64 amd64 ppc64el);
|
||||
}
|
||||
|
||||
done_testing();
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Spec;
|
||||
use File::Temp qw(tempdir);
|
||||
use FindBin;
|
||||
use Test::More;
|
||||
|
||||
# A riscv64 management node needs an xcat and xcatsn deb built for the architecture and a
|
||||
# mklocalrepo.sh that points the host at the matching repository instead of amd64.
|
||||
#
|
||||
# The generated script is extracted from builddebs.pl and run with a stub uname ahead of
|
||||
# $PATH, so the mapping under test is the shipped code. Only the path it writes is
|
||||
# redirected into the sandbox, because it writes an apt source list.
|
||||
|
||||
my $repo_root = File::Spec->rel2abs( File::Spec->catdir( $FindBin::Bin, '..', '..' ) );
|
||||
my $builder = File::Spec->catfile( $repo_root, 'builddebs.pl' );
|
||||
plan skip_all => "builddebs.pl not found" unless -f $builder;
|
||||
|
||||
my $src = do { local $/; open my $fh, '<', $builder or die $!; <$fh> };
|
||||
|
||||
# BAIL_OUT rather than skip: a rename that stops this matching must fail loudly instead of
|
||||
# silently covering nothing.
|
||||
my ($script) = $src =~ /write_script\("\$repodir\/mklocalrepo\.sh", <<'SCRIPT'\);\n(.*?)\nSCRIPT\n/ms;
|
||||
BAIL_OUT('could not extract mklocalrepo.sh from builddebs.pl') unless defined $script;
|
||||
|
||||
my $dir = tempdir( CLEANUP => 1 );
|
||||
my $run = 0;
|
||||
|
||||
# Run the generated script for one host architecture and return the apt source line it wrote.
|
||||
sub sources_line_for {
|
||||
my ($uname) = @_;
|
||||
$run++;
|
||||
my $root = File::Spec->catdir( $dir, "run$run" );
|
||||
mkdir $root;
|
||||
mkdir "$root/bin";
|
||||
|
||||
open( my $stub, '>', "$root/bin/uname" ) or die $!;
|
||||
print {$stub} "#!/bin/bash\necho $uname\n";
|
||||
close($stub);
|
||||
chmod 0755, "$root/bin/uname";
|
||||
|
||||
my $release = File::Spec->catfile( $root, 'lsb-release' );
|
||||
open( my $rel, '>', $release ) or die $!;
|
||||
print {$rel} "DISTRIB_CODENAME=noble\n";
|
||||
close($rel);
|
||||
|
||||
my $listed = File::Spec->catfile( $root, 'sources.list' );
|
||||
( my $sandboxed = $script ) =~ s{/etc/lsb-release}{$release};
|
||||
$sandboxed =~ s{/etc/apt/sources\.list\.d/\S+}{$listed};
|
||||
|
||||
my $harness = File::Spec->catfile( $root, 'harness.sh' );
|
||||
open( my $fh, '>', $harness ) or die $!;
|
||||
print {$fh} "#!/bin/bash\n$sandboxed\n";
|
||||
close($fh);
|
||||
|
||||
local $ENV{PATH} = "$root/bin:$ENV{PATH}";
|
||||
system( '/bin/bash', $harness );
|
||||
open( my $out, '<', $listed ) or die $!;
|
||||
my $line = do { local $/; <$out> };
|
||||
close($out);
|
||||
return $line;
|
||||
}
|
||||
|
||||
for my $case (
|
||||
[ 'riscv64', 'riscv64' ],
|
||||
[ 'ppc64le', 'ppc64el' ],
|
||||
[ 'x86_64', 'amd64' ],
|
||||
)
|
||||
{
|
||||
my ( $uname, $want ) = @$case;
|
||||
like( sources_line_for($uname), qr/^deb \[arch=\Q$want\E\] /,
|
||||
"mklocalrepo.sh gives a $uname host the $want repository" );
|
||||
}
|
||||
|
||||
# The debs themselves must exist for the architecture.
|
||||
for my $case ( [ 'xCAT', 'xcat' ], [ 'xCATsn', 'xcatsn' ] ) {
|
||||
my ( $component, $package ) = @$case;
|
||||
my $control = File::Spec->catfile( $repo_root, $component, 'debian', 'control' );
|
||||
my $text = do { local $/; open my $fh, '<', $control or die $!; <$fh> };
|
||||
my ($arches) = $text =~ /^Package: \Q$package\E\nArchitecture: (.*)$/m;
|
||||
ok( defined $arches, "$package declares an architecture" );
|
||||
like( $arches || '', qr/\briscv64\b/, "$package is built for riscv64" );
|
||||
like( $arches || '', qr/\bamd64\b.*\bppc64el\b/, "$package keeps amd64 and ppc64el" );
|
||||
}
|
||||
|
||||
done_testing();
|
||||
Reference in New Issue
Block a user