From 3a715962d8c7e8f741e62ba01d1f92d4e15d9ad4 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Mon, 14 Sep 2026 08:24:54 -0300 Subject: [PATCH] test(xcat-core): a failed extraction in the Genesis build-root test stops the whole suite genesis_ubuntu_build_root.t called BAIL_OUT at four places where an extraction stopped matching. prove stops every remaining file on a bail-out, so one stale regex in this file hides the results of the tests that would have run after it. die is just as loud and costs only this file. Four comments in the same file also explained more than the code hides: the header retold the failure the test exists for, two narrated the two helper subroutines, and one traced the lease failure across doxcat, the image and the node. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> --- xCAT-test/unit/genesis_ubuntu_build_root.t | 42 ++++++++++------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/xCAT-test/unit/genesis_ubuntu_build_root.t b/xCAT-test/unit/genesis_ubuntu_build_root.t index bb086b9c6..cf8363b30 100755 --- a/xCAT-test/unit/genesis_ubuntu_build_root.t +++ b/xCAT-test/unit/genesis_ubuntu_build_root.t @@ -1,12 +1,11 @@ #!/usr/bin/env perl # The Ubuntu Genesis build root must carry every command the Ubuntu dracut module marks -# mandatory. dracut_install reports a missing command and returns, so a command the build -# root does not supply leaves a hole in the image and the build still exits 0. +# mandatory. dracut_install reports a missing command and returns 0, so a hole in the image +# does not fail the build. # -# The mandatory list is read by RUNNING the module: module-setup.sh is sourced with -# dracut_install shadowed, _dracut_install_opt neutralised (its callers are optional by -# construction), and install() is called. The package list is read by extracting the -# REQUIRED_PACKAGES assignment from builddeb-genesis-base and evaluating it. +# The mandatory list comes from RUNNING the module: module-setup.sh is sourced with +# dracut_install shadowed, _dracut_install_opt neutralised, and install() called. The +# package list comes from evaluating the REQUIRED_PACKAGES assignment in the build script. use strict; use warnings; @@ -23,9 +22,8 @@ plan skip_all => 'builddeb-genesis-base not found' unless -f $builder; plan skip_all => 'ubuntu module-setup.sh not found' unless -f $module; plan tests => 8; -# Commands the Ubuntu dracut module marks mandatory that a minimal Ubuntu server root does -# NOT already provide, and the package that supplies each one. Every entry here has to be in -# REQUIRED_PACKAGES or the image ships without the command. +# Mandatory commands a minimal Ubuntu server root does NOT already provide, and the package +# that supplies each one. my %PACKAGE_FOR = ( dhclient => 'isc-dhcp-client', ifenslave => 'ifenslave', @@ -41,19 +39,16 @@ for my $command (sort keys %PACKAGE_FOR) { "the build root installs $PACKAGE_FOR{$command}, which provides '$command'"); } -# doxcat asks dhclient for the provisioning lease. An image without it never gets an address, -# so the node netboots and never reports in -- the failure this test exists for. +# doxcat asks dhclient for the provisioning lease. ok($mandatory{dhclient} && scalar(grep { $_ eq 'isc-dhcp-client' } @packages), 'the Genesis image can obtain a DHCP lease'); -# dracut_install is silent about a hole, so the payload needs its own gate before it is -# packaged. This is the EL path's behaviour (xCAT-genesis-base.spec runs the same verifier). +# dracut_install is silent about a missing command, so the payload needs its own gate. +# xCAT-genesis-base.spec runs the same verifier on the EL path. my $text = do { open my $fh, '<', $builder or die "$builder: $!"; local $/; <$fh> }; like($text, qr{verify-genesis-payload}, 'builddeb-genesis-base verifies the payload it packages'); -# mandatory_commands($module): source the dracut module with dracut_install shadowed, call -# install(), and return the bare command names it installs unconditionally. Absolute paths are -# data files, not commands, and are left out. +# An absolute path in the install() output is a data file, not a command. sub mandatory_commands { my ($path) = @_; my $dir = tempdir(CLEANUP => 1); @@ -66,29 +61,28 @@ inst_multiple() { :; } inst() { :; } dpkg-architecture() { echo x86_64-linux-gnu; } . '$path' -# Every caller of _dracut_install_opt is optional by construction: it installs only what the -# build root already has. Neutralise it AFTER sourcing so it cannot add to the mandatory set. +# _dracut_install_opt installs only what the build root already has. Neutralise it after +# sourcing, so its commands stay out of the mandatory set. _dracut_install_opt() { :; } install BASH close $fh; my @out = qx{bash '$driver' 2>/dev/null}; - BAIL_OUT("running install() from $path produced nothing") unless @out; + die("running install() from $path produced nothing") unless @out; my %seen; my @names = grep { !$seen{$_}++ } grep { length && !m{^/} } map { chomp; $_ } @out; - BAIL_OUT("install() from $path named no bare commands") unless @names; + die("install() from $path named no bare commands") unless @names; return @names; } -# required_packages($path): extract the REQUIRED_PACKAGES assignment from the build script and -# evaluate it, so the list comes from the value the script actually uses. +# Evaluate the assignment rather than parse it, so the list is the value the script uses. sub required_packages { my ($path) = @_; my $text = do { open my $fh, '<', $path or die "$path: $!"; local $/; <$fh> }; my ($block) = $text =~ /^(REQUIRED_PACKAGES="[^"]*")/ms; - BAIL_OUT("no REQUIRED_PACKAGES assignment in $path") unless $block; + die("no REQUIRED_PACKAGES assignment in $path") unless $block; my $out = qx{bash -c 'set -u; $block; printf "%s\\n" \$REQUIRED_PACKAGES' 2>/dev/null}; my @packages = grep { length } split /\s+/, ($out // ''); - BAIL_OUT("REQUIRED_PACKAGES in $path evaluated to nothing") unless @packages; + die("REQUIRED_PACKAGES in $path evaluated to nothing") unless @packages; return @packages; }