From 3fa8446d0832b82447f133769f95e9219ce4e642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Mon, 24 Aug 2026 21:25:14 -0300 Subject: [PATCH] test(genesis): cover boot consumer gaps --- xCAT-test/unit/destiny_genesis_architecture.t | 59 +++++++++++++++++++ xCAT-test/unit/mknb_exported_genesis.t | 10 ++++ xCAT-test/unit/xcat_release_package.t | 5 ++ .../unit/xcatconfig_genesis_openembedded.t | 49 ++++++++++++--- 4 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 xCAT-test/unit/destiny_genesis_architecture.t diff --git a/xCAT-test/unit/destiny_genesis_architecture.t b/xCAT-test/unit/destiny_genesis_architecture.t new file mode 100644 index 000000000..4bfa74f11 --- /dev/null +++ b/xCAT-test/unit/destiny_genesis_architecture.t @@ -0,0 +1,59 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use File::Path qw(make_path); +use File::Temp qw(tempdir); +use FindBin; +use Test::More; + +my $source = "$FindBin::Bin/../../xCAT-server/lib/xcat/plugins/destiny.pm"; +open(my $source_fh, '<', $source) or die "open $source: $!"; +my $content = do { local $/; <$source_fh> }; +close($source_fh) or die "close $source: $!"; + +my @routines; +for my $name (qw(_genesis_boot_arch _genesis_uses_power_console)) { + my ($routine) = $content =~ /^(sub \Q$name\E\s*\{.*?^\})/ms; + BAIL_OUT("could not extract $name from destiny.pm") unless $routine; + push(@routines, $routine); +} +eval join("\n", @routines); ## no critic (BuiltinFunctions::ProhibitStringyEval) +BAIL_OUT("could not load Genesis architecture helpers: $@") if $@; + +my $tftp = tempdir(CLEANUP => 1); +make_path("$tftp/xcat"); + +is( + _genesis_boot_arch($tftp, 'ppc64le'), + 'ppc64', + 'ppc64le keeps the legacy POWER fallback when no exact image exists', +); + +open(my $kernel_fh, '>', "$tftp/xcat/genesis.kernel.ppc64le") + or die "create exact POWER kernel: $!"; +close($kernel_fh) or die "close exact POWER kernel: $!"; + +is( + _genesis_boot_arch($tftp, 'ppc64le'), + 'ppc64le', + 'ppc64le uses the exact OpenEmbedded boot artifact', +); +is( + _genesis_boot_arch($tftp, 'ppc64el'), + 'ppc64le', + 'the Debian spelling resolves to the exact ppc64le artifact', +); +is(_genesis_boot_arch($tftp, 'x86_64'), 'x86_64', 'other architectures are unchanged'); + +ok(_genesis_uses_power_console('ppc64'), 'legacy POWER uses the hypervisor console'); +ok(_genesis_uses_power_console('ppc64le'), 'ppc64le uses the hypervisor console'); +ok(!_genesis_uses_power_console('x86_64'), 'x86_64 keeps the serial console path'); + +like( + $content, + qr/my \$arch = _genesis_boot_arch\(\$tftpdir, \$ent->\{arch\}\);/, + 'destiny applies the tested architecture selection to nodeset', +); + +done_testing(); diff --git a/xCAT-test/unit/mknb_exported_genesis.t b/xCAT-test/unit/mknb_exported_genesis.t index 760b51c80..c93b2b504 100644 --- a/xCAT-test/unit/mknb_exported_genesis.t +++ b/xCAT-test/unit/mknb_exported_genesis.t @@ -393,6 +393,16 @@ is($selected_dir, $legacy_x86, 'legacy Genesis remains the fallback'); is($selected_arch, 'x86_64', 'the legacy x86_64 name is unchanged'); is($selected_type, 'legacy', 'the fallback source is identified'); +my $linked_legacy = "$tmpdir/linked-legacy-x86_64"; +make_path("$linked_legacy/fs"); +remove_tree($legacy_x86); +symlink($linked_legacy, $legacy_x86) + or die "Unable to create legacy Genesis directory symlink: $!"; +($selected_dir, $selected_arch, $selected_type) = + xCAT_plugin::mknb::_select_genesis_source($selection_root, 'x86_64'); +is($selected_dir, $legacy_x86, 'legacy Genesis directory symlinks remain usable'); +is($selected_type, 'legacy', 'a linked legacy source keeps its source type'); + my $openembedded_ppc64le = "$selection_root/share/xcat/netboot/genesis-openembedded/ppc64le"; my $legacy_ppc64 = "$selection_root/share/xcat/netboot/genesis/ppc64"; diff --git a/xCAT-test/unit/xcat_release_package.t b/xCAT-test/unit/xcat_release_package.t index 44d369810..b8e1f55e4 100644 --- a/xCAT-test/unit/xcat_release_package.t +++ b/xCAT-test/unit/xcat_release_package.t @@ -37,6 +37,11 @@ like( my $common_dep = read_file('xCAT-release/xcat-dep-common.repo'); assert_repo_security($common_dep, 'common dependency'); +like( + $common_dep, + qr/^skip_if_unavailable=1$/m, + 'an unavailable common repository does not block package operations', +); like( $common_dep, qr{^baseurl=https://xcat\.org/files/xcat/repos/yum/latest/xcat-dep/common$}m, diff --git a/xCAT-test/unit/xcatconfig_genesis_openembedded.t b/xCAT-test/unit/xcatconfig_genesis_openembedded.t index 5619fa61b..def087fee 100644 --- a/xCAT-test/unit/xcatconfig_genesis_openembedded.t +++ b/xCAT-test/unit/xcatconfig_genesis_openembedded.t @@ -2,7 +2,7 @@ use strict; use warnings; -use File::Path qw(make_path); +use File::Path qw(make_path remove_tree); use File::Temp qw(tempdir); use FindBin; use Test::More; @@ -12,11 +12,14 @@ open(my $source_fh, '<', $source) or die "open $source: $!"; my $content = do { local $/; <$source_fh> }; close($source_fh) or die "close $source: $!"; -my ($routine) = $content =~ /^(sub _installed_genesis_architectures\s*\{.*?^\})/ms; -BAIL_OUT('could not extract _installed_genesis_architectures from xcatconfig') - unless $routine; -eval $routine; ## no critic (BuiltinFunctions::ProhibitStringyEval) -BAIL_OUT("could not load _installed_genesis_architectures: $@") if $@; +my @routines; +for my $name (qw(_installed_genesis_architectures _genesis_architectures_to_build)) { + my ($routine) = $content =~ /^(sub \Q$name\E\s*\{.*?^\})/ms; + BAIL_OUT("could not extract $name from xcatconfig") unless $routine; + push(@routines, $routine); +} +eval join("\n", @routines); ## no critic (BuiltinFunctions::ProhibitStringyEval) +BAIL_OUT("could not load Genesis architecture helpers: $@") if $@; my $tmpdir = tempdir(CLEANUP => 1); make_path( @@ -26,18 +29,46 @@ make_path( "$tmpdir/share/xcat/netboot/genesis-openembedded/ppc64le", "$tmpdir/share/xcat/netboot/genesis-openembedded/x86_64", ); +my $symlink_target = "$tmpdir/openembedded-riscv64"; +make_path($symlink_target); +symlink( + $symlink_target, + "$tmpdir/share/xcat/netboot/genesis-openembedded/riscv64", +) or die "create OpenEmbedded directory symlink: $!"; is_deeply( [ _installed_genesis_architectures($tmpdir) ], - [ qw(aarch64 ppc64 ppc64le x86_64) ], - 'xcatconfig finds exact OpenEmbedded architectures and installed legacy images', + [ qw(aarch64 ppc64 ppc64le riscv64 x86_64) ], + 'xcatconfig finds exact OpenEmbedded architectures, symlinks, and legacy images', +); + +is_deeply( + [ _genesis_architectures_to_build($tmpdir, 0) ], + [ qw(aarch64 ppc64le riscv64 x86_64) ], + 'an ordinary xCAT update rebuilds only installed OpenEmbedded images', +); +is_deeply( + [ _genesis_architectures_to_build($tmpdir, 1) ], + [ qw(aarch64 ppc64 ppc64le riscv64 x86_64) ], + 'a legacy package trigger rebuilds every installed Genesis image', ); make_path("$tmpdir/share/xcat/netboot/genesis-openembedded/unsupported"); is_deeply( [ _installed_genesis_architectures($tmpdir) ], - [ qw(aarch64 ppc64 ppc64le x86_64) ], + [ qw(aarch64 ppc64 ppc64le riscv64 x86_64) ], 'unknown directories are not passed to mknb', ); +remove_tree("$tmpdir/share/xcat/netboot/genesis/ppc64"); +my $legacy_target = "$tmpdir/legacy-ppc64"; +make_path("$legacy_target/fs"); +symlink($legacy_target, "$tmpdir/share/xcat/netboot/genesis/ppc64") + or die "create legacy directory symlink: $!"; +is_deeply( + [ _installed_genesis_architectures($tmpdir) ], + [ qw(aarch64 ppc64 ppc64le riscv64 x86_64) ], + 'legacy Genesis directory symlinks remain supported', +); + done_testing();