2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-05 04:27:55 +00:00

test(subiquity): the boot-flip test skips wherever the suite runs

ubuntu_subiquity_boot_flip.t bound 3002 on the loopback to check it was free
and skip_all'd when it was not. 3002 is the install-monitor port, so on any
management node xcatd is already listening there -- which is precisely where
the suite runs. The CI log for #7761 reads

    ubuntu_subiquity_boot_flip.t ... skipped: port 3002 is not available on
    the loopback interface

so all 139 lines and 12 assertions never executed once, and never would have.
Coverage that reports as a skip is worse than none, because the gap is
invisible.

Take an ephemeral port from the kernel and rewrite the extracted command to use
it, in both the /dev/tcp target and the log message. The port number is not what
is under test -- the retry-and-log behaviour is.

The template's own port is read out of the command rather than hard-coded, and
asserted to be 3002, so moving the install-monitor still leaves the file
covering something instead of silently testing a port nothing uses.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-01 18:50:31 -03:00
parent 5ce5edf24b
commit 7082fabe0b
+19 -6
View File
@@ -19,12 +19,15 @@ use Test::More;
my $tmpl = "$FindBin::Bin/../../xCAT-server/share/xcat/install/ubuntu/compute.subiquity.tmpl";
plan skip_all => 'compute.subiquity.tmpl not found' unless -r $tmpl;
my $XCATD_PORT = 3002; # the install-monitor port the template addresses
# The template addresses the install-monitor on 3002, and on any management node xcatd is
# already listening there -- so binding it here made the whole file skip_all exactly where the
# suite runs. Take an ephemeral port from the kernel instead and rewrite the extracted command
# to use it: what is under test is the retry-and-log behaviour, not the port number.
my $probe = IO::Socket::INET->new(
LocalAddr => '127.0.0.1', LocalPort => $XCATD_PORT, Proto => 'tcp',
Listen => 5, ReuseAddr => 1);
plan skip_all => "port $XCATD_PORT is not available on the loopback interface" unless $probe;
LocalAddr => '127.0.0.1', LocalPort => 0, Proto => 'tcp',
Listen => 5, ReuseAddr => 1)
or BAIL_OUT("could not take an ephemeral port on the loopback interface: $!");
my $XCATD_PORT = $probe->sockport;
close $probe; # each case below opens its own listener, or none at all
open(my $fh, '<', $tmpl) or die "open $tmpl: $!";
@@ -35,6 +38,13 @@ close $fh;
my ($command) = $source =~ m{- \['bash', '-c', '(.*?/dev/tcp/.*?)'\]};
BAIL_OUT('no late-command in the template performs the boot flip over /dev/tcp') unless $command;
# Read the port out of the template rather than hard-coding it, so a template that moves the
# install-monitor still gets covered instead of silently testing the wrong port.
my ($TEMPLATE_PORT) = $command =~ m{/dev/tcp/\$xm/(\d+)};
BAIL_OUT('could not read the install-monitor port from the boot-flip command')
unless $TEMPLATE_PORT;
is($TEMPLATE_PORT, 3002, 'the template addresses the install-monitor port xcatd listens on');
# Run the command with the install server pointed at our stand-in, and its log inside a scratch
# tree. Everything else is the template's own text.
sub run_flip {
@@ -45,6 +55,9 @@ sub run_flip {
my $script = $command;
$script =~ s/\#XCATVAR:XCATMASTER\#/127.0.0.1/;
# point the flip at the ephemeral listener, in both the /dev/tcp target and the log message
$script =~ s{/dev/tcp/\$xm/\Q$TEMPLATE_PORT\E\b}{/dev/tcp/\$xm/$XCATD_PORT};
$script =~ s{\$xm:\Q$TEMPLATE_PORT\E\b}{\$xm:$XCATD_PORT}g;
$script =~ s{/target/var/log/xcat/xcat\.log}{$root/target/var/log/xcat/xcat.log};
$script =~ s/sleep 5/sleep 1/; # shorten the retry pause, keep the retry
@@ -105,7 +118,7 @@ sub run_flip {
is($r->{rc}, 0, 'a failed flip still exits 0 rather than aborting the install');
like($r->{log}, qr/FAILED to flip/,
'a failed flip is recorded in the install log instead of PXE-looping silently');
like($r->{log}, qr/127\.0\.0\.1:3002/,
like($r->{log}, qr/127\.0\.0\.1:\Q$XCATD_PORT\E\b/,
'the log names the install server and port that could not be reached');
}