From 7183fd8414152fef87d57bba24e5013283b7b4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:20:38 -0300 Subject: [PATCH] test(genesis): cover s390x boot behavior --- .../integration/dhcp_isc_config_validation.t | 7 +-- .../integration/dhcp_kea_config_validation.t | 4 +- xCAT-test/unit/dhcp_boot_policy.t | 44 ++----------------- xCAT-test/unit/dhcp_isc_client_arch.t | 9 +--- xCAT-test/unit/dhcp_kea_plugin_intent.t | 26 +++-------- xCAT-test/unit/genesis_openembedded.t | 44 ++++++++++++++++--- .../unit/genesis_openembedded_activation.t | 12 ++--- xCAT-test/unit/mknb_xcatd_address.t | 33 +++++++++----- 8 files changed, 78 insertions(+), 101 deletions(-) diff --git a/xCAT-test/integration/dhcp_isc_config_validation.t b/xCAT-test/integration/dhcp_isc_config_validation.t index 7a80e209a..aae60d304 100644 --- a/xCAT-test/integration/dhcp_isc_config_validation.t +++ b/xCAT-test/integration/dhcp_isc_config_validation.t @@ -28,16 +28,11 @@ my @config = ( " range 192.0.2.100 192.0.2.110;\n", ); -ok( - xCAT::DHCP::BootPolicy->ensure_isc_path_prefix_definition(\@config), - 'the upgrade path adds option 210 to an existing configuration', -); push @config, @{ xCAT::DHCP::BootPolicy->isc_client_architecture_lines( next_server => '192.0.2.1', portsuffix => '', net => '192.0.2.0', prefix => 24, - s390x_qemu_config_present => 1, ) }, "}\n"; my $configuration_root = -d '/etc/dhcp' ? '/etc/dhcp' : '/etc'; @@ -48,6 +43,6 @@ print {$config_file} @config; close($config_file) or die "Cannot close $path: $!"; my $status = system($dhcpd, '-t', '-cf', $path); -is($status, 0, 'ISC accepts the upgraded s390x boot policy'); +is($status, 0, 'ISC accepts the s390x boot policy'); done_testing(); diff --git a/xCAT-test/integration/dhcp_kea_config_validation.t b/xCAT-test/integration/dhcp_kea_config_validation.t index 125189705..86596f026 100644 --- a/xCAT-test/integration/dhcp_kea_config_validation.t +++ b/xCAT-test/integration/dhcp_kea_config_validation.t @@ -24,7 +24,6 @@ my $json = $backend->render_dhcp4_config( interfaces => ['*'], 'option-def' => [ { name => 'conf-file', code => 209, type => 'string', space => 'dhcp4' }, - { name => 'path-prefix', code => 210, type => 'string', space => 'dhcp4' }, { name => 'iscsi-initiator-iqn', code => 203, type => 'string', space => 'dhcp4' }, { name => 'cumulus-provision-url', code => 239, type => 'string', space => 'dhcp4' }, ], @@ -47,8 +46,7 @@ my $json = $backend->render_dhcp4_config( test => 'option[93].hex == 0x001f', additional_only => JSON::true, 'option-data' => [ - { name => 'conf-file', data => '192.168.122.0_24' }, - { name => 'path-prefix', data => 'pxelinux.cfg/s390x/' }, + { name => 'conf-file', data => 'pxelinux.cfg/s390x/192.168.122.0_24' }, ], }, { diff --git a/xCAT-test/unit/dhcp_boot_policy.t b/xCAT-test/unit/dhcp_boot_policy.t index a5d1e6610..2e6974708 100644 --- a/xCAT-test/unit/dhcp_boot_policy.t +++ b/xCAT-test/unit/dhcp_boot_policy.t @@ -218,9 +218,8 @@ unlike( ); my $s390x = xCAT::DHCP::BootPolicy->kea_s390x_network_classes( - net => '10.0.0.0', - prefix => 24, - qemu_config_present => 1, + net => '10.0.0.0', + prefix => 24, ); is_deeply( $s390x, @@ -232,12 +231,7 @@ is_deeply( 'option-data' => [ { name => 'conf-file', - data => '10.0.0.0_24', - 'always-send' => 1, - }, - { - name => 'path-prefix', - data => 'pxelinux.cfg/s390x/', + data => 'pxelinux.cfg/s390x/10.0.0.0_24', 'always-send' => 1, }, ], @@ -245,37 +239,5 @@ is_deeply( ], 's390x firmware receives its supported network configuration method', ); -is_deeply( - xCAT::DHCP::BootPolicy->kea_s390x_network_classes( - net => '10.0.0.0', prefix => 24 - ), - [], - 's390x classes require a generated network configuration', -); -my @legacy_isc_config = ( - "#xCAT generated dhcp configuration\n", - "\n", - "option conf-file code 209 = text;\n", -); -ok( - xCAT::DHCP::BootPolicy->ensure_isc_path_prefix_definition( - \@legacy_isc_config - ), - 'an older ISC configuration receives the path-prefix definition', -); -is( - $legacy_isc_config[1], - "option path-prefix code 210 = text;\n", - 'the definition is inserted in the global configuration header', -); -ok( - !xCAT::DHCP::BootPolicy->ensure_isc_path_prefix_definition( - \@legacy_isc_config - ), - 'an existing path-prefix definition is preserved', -); -my $definition_count = - grep { /^\s*option\s+path-prefix\s+code\s+210\b/ } @legacy_isc_config; -is($definition_count, 1, 'repeated updates do not duplicate the definition'); done_testing(); diff --git a/xCAT-test/unit/dhcp_isc_client_arch.t b/xCAT-test/unit/dhcp_isc_client_arch.t index d3b2fd85b..4757f56df 100644 --- a/xCAT-test/unit/dhcp_isc_client_arch.t +++ b/xCAT-test/unit/dhcp_isc_client_arch.t @@ -14,7 +14,6 @@ my $rendered = join '', @{ xCAT::DHCP::BootPolicy->isc_client_architecture_lines tftpdir => '/srv/tftp', net => '192.0.2.0', prefix => 24, - s390x_qemu_config_present => 1, ) }; like( @@ -39,7 +38,7 @@ like( ); like( $rendered, - qr/client-architecture = 00:1f \{ #QEMU s390x\n\s+option path-prefix = "pxelinux\.cfg\/s390x\/";\n\s+option conf-file = "192\.0\.2\.0_24";/, + qr/client-architecture = 00:1f \{ #QEMU s390x\n\s+option conf-file = "pxelinux\.cfg\/s390x\/192\.0\.2\.0_24";/, 'QEMU s390x receives its network configuration', ); @@ -62,10 +61,4 @@ cmp_ok($http_pos, '<', $opal_pos, 'the HTTP branch precedes the OPAL bran cmp_ok($http_pos, '<', $fallback_pos, 'the HTTP branch is reachable before the fallback'); like($rendered, qr/filename "\/yaboot";\n\s*\}\n\z/, 'the policy ends with the existing yaboot fallback'); -my $without_s390x = join '', @{ xCAT::DHCP::BootPolicy->isc_client_architecture_lines( - next_server => '192.0.2.10', net => '192.0.2.0', prefix => 24, - ) }; -unlike($without_s390x, qr/client-architecture = 00:1f/, - 'ISC does not advertise s390x without a generated network configuration'); - done_testing(); diff --git a/xCAT-test/unit/dhcp_kea_plugin_intent.t b/xCAT-test/unit/dhcp_kea_plugin_intent.t index 530690d2d..a3c97628a 100644 --- a/xCAT-test/unit/dhcp_kea_plugin_intent.t +++ b/xCAT-test/unit/dhcp_kea_plugin_intent.t @@ -8,7 +8,6 @@ use lib "$FindBin::Bin/../lib"; use lib "$FindBin::Bin/../../perl-xCAT"; use lib "$FindBin::Bin/../../xCAT-server/lib/perl"; -use File::Path qw(make_path); use File::Temp qw(tempdir); use Socket (); use Test::More; @@ -85,7 +84,7 @@ require xCAT::Utils; *xCAT::Utils::runcmd = sub { return; }; } -$xCAT::TableUtils::tftpdir = tempdir(CLEANUP => 1); +$xCAT::TableUtils::tftpdir = '/srv/tftp'; my $source_dhcp_plugin = repo_path('xCAT-server/lib/xcat/plugins/dhcp.pm'); require $source_dhcp_plugin; require xCAT::DHCP::Backend::Kea; @@ -123,24 +122,6 @@ my %network_entry = ( tftpserver => '', ); -{ - no warnings 'redefine'; - local *xCAT::NetworkUtils::thishostisnot = sub { return 0; }; - my $nettab = DHCPKeaIntentNetTable->new(\%network_entry); - my $subnet = xCAT_plugin::dhcp::kea_subnet4_intent( - $nettab, '10.0.0.0', '255.255.255.0', 'eth0', 0, 1, 80 - ); - my %classes = map { $_->{name} => $_ } @{ $subnet->{client_classes} }; - ok(!grep(/^xcat-s390x-/, keys %classes), - 'Kea omits s390x policy without a generated network configuration'); -} - -my $s390x_config_dir = - "$xCAT::TableUtils::tftpdir/pxelinux.cfg/s390x"; -make_path($s390x_config_dir); -open(my $s390x_config, '>', "$s390x_config_dir/10.0.0.0_24") - or die "Unable to create s390x test configuration: $!"; -close($s390x_config); { no warnings 'redefine'; local *xCAT::NetworkUtils::thishostisnot = sub { return 0; }; @@ -150,6 +131,11 @@ close($s390x_config); ); my %classes = map { $_->{name} => $_ } @{ $subnet->{client_classes} }; ok($classes{'xcat-s390x-qemu-10.0.0.0_24'}, 'the Kea subnet includes QEMU s390x boot policy'); + is( + $classes{'xcat-s390x-qemu-10.0.0.0_24'}{'option-data'}[0]{data}, + 'pxelinux.cfg/s390x/10.0.0.0_24', + 'the Kea subnet sends the complete s390x configuration path', + ); is_deeply( [ grep { /^xcat-s390x-/ } @{ $subnet->{additional_client_classes} } ], ['xcat-s390x-qemu-10.0.0.0_24'], diff --git a/xCAT-test/unit/genesis_openembedded.t b/xCAT-test/unit/genesis_openembedded.t index d595725df..4fd8cb537 100644 --- a/xCAT-test/unit/genesis_openembedded.t +++ b/xCAT-test/unit/genesis_openembedded.t @@ -2,12 +2,14 @@ use strict; use warnings; +use Cwd qw(abs_path); use Digest::SHA qw(sha256_hex); use File::Spec; +use File::Temp qw(tempdir); use FindBin; use Test::More; -my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' ); +my $repo_root = abs_path(File::Spec->catdir( $FindBin::Bin, '..', '..' )); sub read_file { my ($relative_path) = @_; @@ -103,11 +105,38 @@ like( $ppc64_kas, qr/^machine: xcat-genesis-ppc64$/m, 'ppc64 build selects its machine' ); my $build = read_file('xCAT-genesis-builder/oe/build'); -like( $build, - qr/aarch64\|armv7hf\|riscv64\|s390x\|x86\|x86_64\|ppc64\|ppc64le/, - 'build accepts each supported architecture' ); -like( $build, qr{kas/\$architecture\.yml}, - 'build selects the architecture configuration directly' ); +my $build_path = File::Spec->catfile( + $repo_root, qw(xCAT-genesis-builder oe build) +); +my $build_test_dir = tempdir(CLEANUP => 1); +my $kas_stub = File::Spec->catfile($build_test_dir, 'kas'); +my $kas_log = File::Spec->catfile($build_test_dir, 'kas.log'); +open(my $kas_stub_file, '>', $kas_stub) + or die "Unable to create $kas_stub: $!"; +print {$kas_stub_file} <<'KAS_STUB'; +#!/bin/sh +printf '%s\n' "$*" >> "$XCAT_TEST_KAS_LOG" +KAS_STUB +close($kas_stub_file) or die "Unable to close $kas_stub: $!"; +chmod(0755, $kas_stub) or die "Unable to make $kas_stub executable: $!"; +{ + local $ENV{KAS} = $kas_stub; + local $ENV{XCAT_TEST_KAS_LOG} = $kas_log; + local $ENV{XCAT_GENESIS_WORK_DIR} = + File::Spec->catdir($build_test_dir, 'work'); + is(system($build_path, 's390x') >> 8, 0, + 'build accepts s390x'); + is(system($build_path, 'not-an-architecture') >> 8, 2, + 'build rejects an unsupported architecture'); +} +open(my $kas_log_file, '<', $kas_log) or die "Unable to read $kas_log: $!"; +my @kas_invocations = <$kas_log_file>; +close($kas_log_file) or die "Unable to close $kas_log: $!"; +is_deeply( + \@kas_invocations, + ["build $repo_root/xCAT-genesis-builder/oe/kas/s390x.yml\n"], + 'build invokes the s390x kas configuration once', +); my $distro = read_file( 'xCAT-genesis-builder/oe/meta-xcat-genesis/conf/distro/xcat-genesis.conf' @@ -877,6 +906,9 @@ my $smoke_extension = read_file( ); like( $smoke_extension, qr/^XCAT_GENESIS_EXTENSION_NAME = "xcat-smoke"$/m, 'open smoke extension exercises the build path' ); +like( $smoke_extension, + qr/^XCAT_GENESIS_EXTENSION_ARCHITECTURE = "\$\{XCAT_GENESIS_ARCHITECTURE\}"$/m, + 'smoke extension uses the target architecture identity' ); my $preset = read_file( 'xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-init/files/00-xcat-genesis.preset' diff --git a/xCAT-test/unit/genesis_openembedded_activation.t b/xCAT-test/unit/genesis_openembedded_activation.t index 774f73049..da2c7c572 100644 --- a/xCAT-test/unit/genesis_openembedded_activation.t +++ b/xCAT-test/unit/genesis_openembedded_activation.t @@ -112,11 +112,13 @@ like( qr{/opt/xcat/share/xcat/netboot/genesis-openembedded/ARCH}, 'the mknb man page documents the OpenEmbedded install namespace', ); -like( - $mknb_pod, - qr/x86.*x86_64.*ppc64.*ppc64le.*armv7hf.*aarch64.*riscv64.*s390x/s, - 'the mknb man page lists every exact OpenEmbedded architecture', -); +for my $architecture (qw(x86 x86_64 ppc64 ppc64le armv7hf aarch64 riscv64 s390x)) { + like( + $mknb_pod, + qr/\b\Q$architecture\E\b/, + "the mknb man page lists $architecture", + ); +} unlike( $mknb_pod, qr/For ppc64le, use the ppc64 architecture/, diff --git a/xCAT-test/unit/mknb_xcatd_address.t b/xCAT-test/unit/mknb_xcatd_address.t index d2c0ecdc5..699daf3f6 100644 --- a/xCAT-test/unit/mknb_xcatd_address.t +++ b/xCAT-test/unit/mknb_xcatd_address.t @@ -537,17 +537,6 @@ unlike( 's390x configurations do not use the later floating address', ); write_text($s390x_qemu_path, "admin network configuration\n"); -%xCAT::TableUtils::site_extra = ( dhcpinterfaces => 'eth0,eth1:noboot' ); -$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.148.10' }; -$responses = run_mknb('s390x'); -generation_succeeded($responses, 's390x configuration generation accepts a :noboot interface'); -is( - read_config($s390x_qemu_path), - "admin network configuration\n", - 'a :noboot interface preserves an administrator-owned s390x configuration', -); -%xCAT::TableUtils::site_extra = (); -$xCAT::NetworkUtils::nic_ips = undef; $responses = run_mknb('s390x'); ok( scalar(grep { ref($_) eq 'HASH' && $_->{error} && "@{$_->{error}}" =~ /Refusing to replace unmanaged/ } @{$responses}), @@ -559,6 +548,25 @@ unlink($s390x_qemu_path); $responses = run_mknb('s390x'); generation_succeeded($responses, 's390x configuration is restored after removing the unmanaged file'); +my $s390x_legacy_root = "$tmpdir/tftpboot-s390x-legacy"; +make_path("$s390x_legacy_root/pxelinux.cfg/s390x"); +my ($s390x_legacy_path, $s390x_legacy_error) = + xCAT_plugin::mknb::_write_s390x_discovery_config( + tftpdir => $s390x_legacy_root, + network => '192.168.144.0_20', + xcatd_address => '192.168.148.10', + xcatdport => 3001, + consolecmdline => 'console=ttysclp0', + kernel => 'xcat/nbk.s390x', + initrd => "$s390x_legacy_root/xcat/nbfs.s390x.gz", + ); +is($s390x_legacy_error, undef, 'legacy s390x configuration is written'); +like( + read_config($s390x_legacy_path), + qr/^ KERNEL xcat\/nbk\.s390x$/m, + 'legacy s390x configuration selects its published kernel', +); + my $s390x_failure_root = "$tmpdir/tftpboot-s390x-failure"; make_path("$s390x_failure_root/pxelinux.cfg/s390x/192.168.144.0_20"); my (undef, $s390x_write_error) = @@ -568,6 +576,7 @@ my (undef, $s390x_write_error) = xcatd_address => '192.168.148.10', xcatdport => 3001, consolecmdline => 'console=ttysclp0', + kernel => 'xcat/genesis.kernel.s390x', initrd => "$s390x_failure_root/xcat/genesis.fs.s390x.gz", ); like( @@ -591,7 +600,7 @@ like( ); %xCAT::TableUtils::site_extra = ( dhcpinterfaces => 'eth0,eth1:noboot' ); -$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.148.10' }; +$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.149.100' }; $responses = run_mknb('s390x'); generation_succeeded($responses, 's390x configuration generation honors :noboot'); ok(!-e $s390x_qemu_path, 'a :noboot network gets no QEMU s390x configuration');