From 7082fabe0b64545fdec4559613c78cd8612599e7 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Tue, 1 Sep 2026 18:50:31 -0300 Subject: [PATCH] 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> --- xCAT-test/unit/ubuntu_subiquity_boot_flip.t | 25 ++++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/xCAT-test/unit/ubuntu_subiquity_boot_flip.t b/xCAT-test/unit/ubuntu_subiquity_boot_flip.t index 8102718d0..7cc1a9ab2 100644 --- a/xCAT-test/unit/ubuntu_subiquity_boot_flip.t +++ b/xCAT-test/unit/ubuntu_subiquity_boot_flip.t @@ -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'); }