2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-21 15:18:19 +00:00

test(packaging): exercise upgrade logging and failure policy

Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com>
This commit is contained in:
Vinícius Ferrão
2026-10-11 11:50:49 -03:00
parent 13d106f3db
commit 41839052cc
2 changed files with 88 additions and 2 deletions
+2 -2
View File
@@ -15,7 +15,7 @@ jobs:
- name: Install lifecycle test dependencies
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
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: Prepare xCAT syslog directory
if: ${{ !cancelled() }}
run: sudo install -d -o syslog -g adm -m 0750 /var/log/xcat
@@ -45,4 +45,4 @@ jobs:
- name: Enable lifecycle test namespaces
run: sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- name: Test RPM package lifecycle
run: su -s /bin/sh nobody -c 'prove -v xCAT-test/native/xcatd_rpm_lifecycle.t xCAT-test/native/apache_rpm_configuration.t xCAT-test/native/apache_package_lifecycle.t'
run: su -s /bin/sh nobody -c 'prove -v xCAT-test/native/xcatd_rpm_lifecycle.t xCAT-test/native/apache_rpm_configuration.t xCAT-test/native/apache_package_lifecycle.t xCAT-test/native/package_upgrade_logging.t'
@@ -0,0 +1,86 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Test::More;
use XCAT::Test::Lifecycle;
use XCAT::Test::RPM;
plan skip_all => 'Run as an ordinary user on a native Debian or RPM distribution'
unless $^O eq 'linux' && $< != 0 && (-f '/etc/debian_version' || -f '/etc/redhat-release');
my $debian = -f '/etc/debian_version';
my $first = $debian ? XCAT::Test::Lifecycle::build_deb('xCAT') : XCAT::Test::RPM->build('xCAT', 1);
my $second = $debian ? $first : XCAT::Test::RPM->build('xCAT', 2);
my $warning = "WARNING: mknb did not complete, so the Genesis netboot image may be missing or out of date.\n" .
" See /var/log/xcat/upgrade.log, then rerun 'mknb <arch>' once the cause is resolved.\n";
sub install_package {
my ($root, $package) = @_;
return $debian ? $root->install_deb($package) : $root->install($package);
}
for my $case (qw(fresh success warning stderr-warning historic-warning command-failure warning-failure temporary-failure)) {
subtest $case => sub {
my $root = $debian ? XCAT::Test::Lifecycle->new : XCAT::Test::RPM->new;
$root->write('/opt/xcat/share/xcat/scripts/xHRM', '');
$root->record_command('/etc/init.d/apache2');
$root->write('/opt/xcat/sbin/xcatconfig', <<'SHELL', 0755);
#!/bin/sh
printf '%s\n' "$*" >> /config-calls
if [ -f /command-output ]; then cat /command-output; fi
if [ -f /command-error ]; then cat /command-error >&2; fi
if [ -f /command-status ]; then exit "$(cat /command-status)"; fi
SHELL
if ($case ne 'fresh') {
my ($status, $out, $err) = install_package($root, $first);
is($status, 0, 'install the prior package') or diag "$out$err";
unlike($err, qr/scriptlet failed|scriptlet failure/i, 'prior package scriptlets complete');
}
$root->write('/config-calls', '');
my $prior = $case eq 'historic-warning' ? "old command returned error code\n" : "earlier log\n";
$root->write('/var/log/xcat/upgrade.log', $prior);
$root->write('/test-bin/date', "#!/bin/sh\nprintf 'upgrade timestamp\\n'\n", 0755);
my $output = $case eq 'warning' || $case eq 'warning-failure' ? "command returned error code 17\n" : "current output\n";
my $error = $case eq 'stderr-warning' ? "command returned error code 17\n" : "current stderr\n";
$root->write('/command-output', $output);
$root->write('/command-error', $error);
my $failed = $case eq 'command-failure' || $case eq 'warning-failure';
$root->write('/command-status', "17\n") if $failed;
if ($case eq 'temporary-failure') {
$root->write('/test-bin/mktemp', "#!/bin/sh\necho 'temporary allocation failed' >&2\nexit 19\n", 0755);
}
for my $service (qw(installservice udpservice mainservice)) {
$root->write("/tmp/xcat/$service.pid", "$service pid\n");
}
my ($status, $out, $err) = install_package($root, $second);
my $stopped = $debian && ($failed || $case eq 'temporary-failure');
is($status == 0 ? 1 : 0, $stopped ? 0 : 1, 'transaction retains its failure policy') or diag "$out$err";
unlike($err, qr/scriptlet failed|scriptlet failure/i, 'RPM scriptlet finishes') unless $debian;
is($root->read('/config-calls'), $case eq 'temporary-failure' ? '' : $case eq 'fresh' ? "-i\n" : "-u -V\n",
'package invokes the correct configuration action');
my $expected_log = $prior;
if ($case ne 'fresh') {
$expected_log .= "upgrade timestamp\n";
$expected_log .= $output . $error unless $stopped || $case eq 'temporary-failure';
}
is($root->read('/var/log/xcat/upgrade.log'), $expected_log, 'log appends only the output reached by this transaction');
my $warnings = join '', $out =~ /^(WARNING: mknb[^\n]*\n See [^\n]*\n)/mg;
my $warned = !$stopped && ($case eq 'warning' || $case eq 'warning-failure' || $case eq 'stderr-warning');
is($warnings, $warned ? $warning : '', 'only the current captured failure triggers the warning');
unlike($out, qr/^current (?:output|stderr)$/m, 'upgrade output stays in the log') unless $case eq 'fresh';
my @temporary = glob $root->path('/tmp/xcat-upgrade.*');
is(scalar @temporary, $debian && $failed ? 1 : 0, 'temporary capture retains caller cleanup policy');
is($root->read('/tmp/' . (split m{/}, $temporary[0])[-1]), $output . $error,
'failed Debian command retains captured diagnostics') if @temporary;
if ($debian) {
is(-e $root->path('/tmp/xCAT_upgrade.tmp') ? 1 : 0, $stopped ? 1 : 0, 'upgrade marker follows transaction completion');
}
for my $service (qw(installservice udpservice mainservice)) {
my $destination = $case eq 'fresh' ? '/tmp/xcat' : '/var/run/xcat';
is($root->read("$destination/$service.pid"), "$service pid\n", 'PID relocation remains in the caller');
}
};
}
done_testing;