2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-21 07:08:12 +00:00

test(probe): exercise the built RPM payload

This commit is contained in:
Vinícius Ferrão
2026-10-08 22:40:49 -03:00
parent be9c063981
commit aebc350e1a
4 changed files with 106 additions and 134 deletions
+5
View File
@@ -16,6 +16,11 @@ jobs:
run: sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-install-suggests ucf debconf-utils systemd libxml-simple-perl apache2 curl
- 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
- name: Exercise probe package payloads
if: ${{ !cancelled() }}
run: prove xCAT-test/native/probe_package_payload.t
- name: Prepare xCAT syslog directory
if: ${{ !cancelled() }}
run: sudo install -d -o syslog -g adm -m 0750 /var/log/xcat
+26
View File
@@ -0,0 +1,26 @@
package XCAT::Test::Package;
use strict;
use warnings;
use Cwd qw(getcwd);
use Exporter qw(import);
use XCAT::Test::Lifecycle ();
our @EXPORT_OK = qw(run_in);
sub run_in {
my ($directory, @command) = @_;
my $previous = getcwd();
chdir($directory) or die "chdir $directory: $!";
my ($stdout, $stderr, $status);
my $ok = eval {
($status, $stdout, $stderr) = XCAT::Test::Lifecycle::command(@command);
1;
};
my $error = $@;
chdir($previous) or die "chdir $previous: $!";
die $error unless $ok;
return ($status, $stdout, $stderr);
}
1;
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env perl
use strict;
use warnings;
use File::Path qw(make_path);
use File::Slurper qw(read_binary write_text);
use File::Temp qw(tempdir);
use FindBin;
use lib "$FindBin::Bin/../lib", "$FindBin::Bin/../../build-utils/lib";
use Test::More;
use XCAT::BuildUtils qw(stage_xcat_probe_sources);
use XCAT::Test::File qw(repo_path slurp_repo_file);
use XCAT::Test::Package qw(run_in);
plan skip_all => 'requires Linux package tools' unless $^O eq 'linux';
BAIL_OUT('run package builds as an unprivileged user') unless $>;
my $root = tempdir(CLEANUP => 1);
make_path(map { "$root/$_" } qw(SOURCES BUILD BUILDROOT RPMS SRPMS SPECS home));
local %ENV = (%ENV, HOME => "$root/home", LC_ALL => 'C');
delete @ENV{qw(PERL5LIB PERL5OPT PERLLIB XCATROOT XCATCFG)};
stage_xcat_probe_sources(repo_path('.'), "$root/SOURCES", '9.9.9', 1600000000);
my @helpers = qw(CommandUtils.pm GlobalDef.pm NetworkUtils.pm PacketCapture.pm ServiceNodeUtils.pm);
my @commands = qw(code_template detect_dhcpd discovery osdeploy xcatmn);
sub command {
my ($directory, @args) = @_;
my ($rc, $out, $err) = run_in($directory, @args);
unless (is($rc, 0, "$args[0] completes")) {
diag($out, $err);
BAIL_OUT("@args failed");
}
return $out;
}
command($root, 'rpmbuild', '-bb', '--define', "_topdir $root",
'--define', 'version 9.9.9', '--define', 'release 1', repo_path('xCAT-probe/xCAT-probe.spec'));
my @rpms = glob("$root/RPMS/noarch/xCAT-probe-*.rpm");
is(scalar(@rpms), 1, 'build produces one probe RPM') or BAIL_OUT('missing probe RPM');
my $requires = command($root, 'rpm', '-qp', '--requires', $rpms[0]);
like($requires, qr/^iproute$/m, 'RPM requires the Linux socket tool provider');
make_path("$root/rpm");
command($root, 'bash', '-o', 'pipefail', '-c',
'cd "$1" && rpm2cpio "$2" | cpio -idm --quiet', 'bash', "$root/rpm", $rpms[0]);
check_payload("$root/rpm", 'RPM');
sub check_payload {
my ($destination, $label) = @_;
my $prefix = "$destination/opt/xcat";
my $helper_dir = "$prefix/probe/lib/perl/xCAT";
ok(-x $helper_dir, "$label helper directory is searchable")
or BAIL_OUT(sprintf('%s has mode %04o', $helper_dir, (stat($helper_dir))[2] & 0777));
for my $helper (@helpers) {
my $path = "$prefix/probe/lib/perl/xCAT/$helper";
ok(-f $path, "$label carries $helper") or BAIL_OUT("missing $path");
is(read_binary($path), slurp_repo_file("perl-xCAT/xCAT/$helper"),
"$label carries the canonical $helper bytes");
is((stat($path))[2] & 0777, 0644, "$label helper is readable without execute permission");
}
write_text("$prefix/bin/xcatclient", "#!/bin/sh\nprintf '[ok]:fixture client\\n'\n");
chmod 0755, "$prefix/bin/xcatclient" or die $!;
local $ENV{XCATROOT} = $prefix;
local $ENV{PATH} = "$prefix/bin:$ENV{PATH}";
for my $name (@commands) {
my $out = command($root, "$prefix/probe/subcmds/$name", '-T');
like($out, qr/^\[ok\]\s*:/m, "$label $name self-test is ready");
}
my $list = command($root, "$prefix/bin/xcatprobe", '-l');
like($list, qr/^\Q$_\E\s/m, "$label lists $_") for @commands;
}
done_testing();
+5 -134
View File
@@ -1,143 +1,14 @@
#!/usr/bin/env perl
use strict;
use warnings;
use File::Copy qw(copy);
use File::Path qw(make_path);
use File::Slurper qw(write_text);
use File::Spec;
use File::Temp qw(tempdir);
use FindBin;
use lib "$FindBin::Bin/../lib";
use lib "$FindBin::Bin/../../build-utils/lib";
use Test::More;
use XCAT::Test::File qw(slurp_repo_file);
use XCAT::BuildUtils qw(XCAT_PROBE_HELPERS stage_probe_helpers);
use XCAT::Test::File qw(repo_path slurp_repo_file);
my @helpers = qw(
CommandUtils.pm
GlobalDef.pm
NetworkUtils.pm
PacketCapture.pm
ServiceNodeUtils.pm
);
my @affected_subcommands = qw(
code_template
detect_dhcpd
discovery
osdeploy
xcatmn
);
# How buildrpms.pl stages the xCAT-probe sources is asserted by
# xcat_probe_sources_staged.t, which runs the staging and reads the archive. Seven assertions
# here matched the text of buildrpms.pl instead, and four of them could not fail: three matched
# the xCAT-release routine, which stages the same way, and one spanned the rest of the file. All
# seven stayed green while the staging directory was unset and every RPM target died.
my $installed_probe_test =
slurp_repo_file('xCAT-test/autotest/testcase/probe/xcatproble_list');
my $rpm_spec = slurp_repo_file('xCAT-probe/xCAT-probe.spec');
my $debian_control = slurp_repo_file('xCAT-probe/debian/control');
like(
$rpm_spec,
qr/%if 0%\{\?suse_version\}\s+Requires: iproute2\s+%else\s+Requires: iproute\s+%endif/s,
'RPM package requires the distro-specific provider of ss'
);
like(
$debian_control,
qr/^Depends:.*\biproute2\s*\|\s*net-tools\b/m,
'Debian package requires ss or the legacy netstat provider'
);
# The Debian builder stages the helpers by calling stage_probe_helpers, so run it and
# look at what it produced. The predecessor matched a `cp -f` line in build-ubunturepo,
# which passed whenever that text was reformatted and failed whenever it moved.
my $staged_probe_dir = File::Spec->catdir(tempdir(CLEANUP => 1), 'lib', 'perl', 'xCAT');
stage_probe_helpers(repo_path(File::Spec->catdir('perl-xCAT', 'xCAT')), $staged_probe_dir);
for my $helper (@helpers) {
my $source = repo_path(File::Spec->catfile('perl-xCAT', 'xCAT', $helper));
ok(-f $source, "$helper source exists");
ok(
scalar(grep { $_ eq $helper } XCAT_PROBE_HELPERS),
"the shared builder helper list carries $helper"
);
ok(
-f File::Spec->catfile($staged_probe_dir, $helper),
"Debian builder stages $helper"
);
like(
$installed_probe_test,
qr/cmd:for module in [^;]*\b\Q$helper\E\b[^;]*; do test -r/,
"installed probe payload checks $helper"
);
}
my $tmpdir = tempdir(CLEANUP => 1);
my $xcatroot = File::Spec->catdir($tmpdir, 'opt', 'xcat');
my $probe_root = File::Spec->catdir($xcatroot, 'probe');
my $bin_dir = File::Spec->catdir($xcatroot, 'bin');
my $subcmd_dir = File::Spec->catdir($probe_root, 'subcmds');
my $helper_dir = File::Spec->catdir($probe_root, 'lib', 'perl', 'xCAT');
make_path($probe_root, $bin_dir);
copy_tree(repo_path(File::Spec->catdir('xCAT-probe', 'lib')), File::Spec->catdir($probe_root, 'lib'));
copy_tree(repo_path(File::Spec->catdir('xCAT-probe', 'subcmds')), $subcmd_dir);
my $xcatprobe_source = repo_path(File::Spec->catfile('xCAT-probe', 'xcatprobe'));
my $xcatprobe = File::Spec->catfile($bin_dir, 'xcatprobe');
copy($xcatprobe_source, $xcatprobe) or die "copy $xcatprobe_source: $!";
chmod 0755, $xcatprobe or die "chmod $xcatprobe: $!";
make_path($helper_dir, File::Spec->catdir($subcmd_dir, 'bin'));
for my $helper (@helpers) {
my $source = repo_path(File::Spec->catfile('perl-xCAT', 'xCAT', $helper));
my $destination = File::Spec->catfile($helper_dir, $helper);
copy($source, $destination) or die "copy $source: $!";
chmod 0644, $destination or die "chmod $destination: $!";
}
my $xcatclient = File::Spec->catfile($bin_dir, 'xcatclient');
write_text($xcatclient, "#!/bin/sh\nprintf '[ok]:dummy xcatclient\\n'\n");
chmod 0755, $xcatclient or die "chmod $xcatclient: $!";
local $ENV{XCATROOT} = $xcatroot;
local $ENV{PATH} = "$bin_dir:$ENV{PATH}";
local $ENV{PERL5LIB};
local $ENV{PERL5OPT};
local $ENV{PERLLIB};
delete $ENV{PERL5LIB};
delete $ENV{PERL5OPT};
delete $ENV{PERLLIB};
for my $subcommand (@affected_subcommands) {
my $command = File::Spec->catfile($subcmd_dir, $subcommand);
my ($rc, $output) = run_command($command, '-T');
is($rc, 0, "$subcommand self-test exits successfully") or diag($output);
like($output, qr/^\[ok\]\s*:/m, "$subcommand self-test reports ready");
}
my ($list_rc, $list_output) = run_command($xcatprobe, '-l');
is($list_rc, 0, 'xcatprobe list exits successfully') or diag($list_output);
my %listed = map { /^([^\s].*?)\s/ ? ($1 => 1) : () } split /\n/, $list_output;
for my $subcommand (@affected_subcommands) {
ok($listed{$subcommand}, "xcatprobe lists $subcommand") or diag($list_output);
}
my $control = slurp_repo_file('xCAT-probe/debian/control');
my ($probe) = $control =~ /^Package: xcat-probe\n(.*?)(?:\n\n|\z)/ms;
like($probe // '', qr/^Depends:.*\biproute2\s*\|\s*net-tools\b/m,
'Debian probe keeps the socket-tool alternatives');
done_testing();
sub copy_tree {
my ($source, $destination) = @_;
my $rc = system('cp', '-R', $source, $destination);
is($rc, 0, "copied $source into the package fixture")
or die("unable to create package fixture from $source");
}
sub run_command {
my (@command) = @_;
open(my $fh, '-|', @command) or die "run @command: $!";
my $output = do { local $/; <$fh> };
close($fh);
return ($? >> 8, $output // '');
}