diff --git a/xCAT-test/unit/dhcp_boot_policy.t b/xCAT-test/unit/dhcp_boot_policy.t index 8b0f823ae..b5369b066 100644 --- a/xCAT-test/unit/dhcp_boot_policy.t +++ b/xCAT-test/unit/dhcp_boot_policy.t @@ -81,4 +81,64 @@ my $combined_classes = xCAT::DHCP::BootPolicy->kea_client_classes( ); is( $combined_classes->[0]{name}, 'xcat-xnba-cn01-52544b100011-bios', 'node-specific xNBA classes have priority over generic boot classes' ); +my $network_classes = xCAT::DHCP::BootPolicy->kea_xnba_network_classes( + net => '192.0.2.0', + prefix => 24, + next_server => '192.0.2.10', + httpport => '8080', + xnba_kpxe => 1, + xnba_efi => 1, +); +is( scalar @$network_classes, 2, 'xNBA network policy renders BIOS and UEFI fallback classes' ); +my %network_by_name = map { $_->{name} => $_ } @$network_classes; +my $network_bios = $network_by_name{'xcat-xnba-net-192.0.2.0_24-bios'}; +ok( $network_bios, 'xNBA network BIOS class is named by subnet' ); +is( + $network_bios->{'boot-file-name'}, + 'http://192.0.2.10:8080/tftpboot/xcat/xnba/nets/192.0.2.0_24', + 'xNBA network BIOS class returns the subnet script URL' +); +like( $network_bios->{test}, qr/option\[77\]\.text == 'xNBA'/, 'xNBA network class matches the xNBA user class' ); +like( $network_bios->{test}, qr/option\[93\]\.hex == 0x0000/, 'xNBA network BIOS class matches BIOS clients' ); +unlike( $network_bios->{test}, qr/pkt4\.mac/, 'xNBA network fallback does not require a known MAC' ); +ok( $network_bios->{additional_only}, 'xNBA network fallback is limited to its owning subnet' ); +is( + $network_by_name{'xcat-xnba-net-192.0.2.0_24-uefi'}{'boot-file-name'}, + 'http://192.0.2.10:8080/tftpboot/xcat/xnba/nets/192.0.2.0_24.uefi', + 'xNBA network UEFI class returns the subnet UEFI script URL' +); +like( + $network_by_name{'xcat-xnba-net-192.0.2.0_24-uefi'}{test}, + qr/0x0010/, + 'xNBA network UEFI class matches HTTP boot clients' +); + +is_deeply( + xCAT::DHCP::BootPolicy->kea_xnba_network_classes( + net => '192.0.2.0', + prefix => 24, + next_server => '192.0.2.10', + xnba_kpxe => 1, + ), + [ + { + name => 'xcat-xnba-net-192.0.2.0_24-bios', + test => xCAT::DHCP::BootPolicy::xnba_user_class_test() + . ' and option[93].hex == 0x0000', + 'boot-file-name' => 'http://192.0.2.10/tftpboot/xcat/xnba/nets/192.0.2.0_24', + additional_only => 1, + }, + ], + 'xNBA network policy omits unavailable loaders and the default HTTP port' +); +is_deeply( + xCAT::DHCP::BootPolicy->kea_xnba_network_classes( + net => '192.0.2.0', + prefix => 24, + xnba_kpxe => 1, + ), + [], + 'xNBA network policy requires a next server' +); + done_testing(); diff --git a/xCAT-test/unit/dhcp_kea_renderer.t b/xCAT-test/unit/dhcp_kea_renderer.t index 89ae04cfb..af20211d5 100644 --- a/xCAT-test/unit/dhcp_kea_renderer.t +++ b/xCAT-test/unit/dhcp_kea_renderer.t @@ -194,6 +194,37 @@ ok( !exists $modern_subnet->{'require-client-classes'}, 'Kea 3.x output omits de is( $modern_class->{'only-in-additional-list'}, JSON::true, 'Kea 3.x renders modern class additional-evaluation flag' ); ok( !exists $modern_class->{'only-if-required'}, 'Kea 3.x output omits deprecated class additional-evaluation flag' ); +my $numeric_additional_json = $backend->render_dhcp4_config( + { + subnets => [ + { + id => 4, + subnet => '192.0.2.0/24', + pools => [], + additional_client_classes => ['xcat-xnba-net-192.0.2.0_24-bios'], + }, + ], + 'client-classes' => [ + { + name => 'xcat-xnba-net-192.0.2.0_24-bios', + test => "option[77].text == 'xNBA'", + additional_only => 1, + }, + ], + } +); +my $numeric_additional_config = decode_json($numeric_additional_json); +is_deeply( + $numeric_additional_config->{Dhcp4}{subnet4}[0]{'require-client-classes'}, + ['xcat-xnba-net-192.0.2.0_24-bios'], + 'legacy Kea limits the xNBA fallback class to its owning subnet' +); +is( + $numeric_additional_config->{Dhcp4}{'client-classes'}[0]{'only-if-required'}, + JSON::true, + 'numeric additional-only intent is rendered as a JSON boolean' +); + my $empty_boot_json = $backend->render_dhcp4_config( { subnets => [