mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-04 20:17:55 +00:00
test(dhcp): exercise ISC client boot policy
This commit is contained in:
@@ -3,62 +3,57 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use Test::More;
|
||||
|
||||
use XCAT::Test::File qw(repo_path slurp_repo_file);
|
||||
use xCAT::DHCP::BootPolicy;
|
||||
|
||||
# The ISC dhcpd subnet block in dhcp.pm maps DHCP option 93 (client system
|
||||
# architecture) to a boot file. The block is rendered inside a large
|
||||
# database-backed subroutine, so this pins the shipped source text: every
|
||||
# architecture branch must appear before the catch-all that hands unknown
|
||||
# clients /yaboot, otherwise the branch is unreachable.
|
||||
my $rendered = join '', @{ xCAT::DHCP::BootPolicy->isc_client_architecture_lines(
|
||||
next_server => '192.0.2.10',
|
||||
portsuffix => ':8080',
|
||||
tftpdir => '/srv/tftp',
|
||||
net => '192.0.2.0',
|
||||
prefix => 24,
|
||||
) };
|
||||
|
||||
my $plugin = repo_path('xCAT-server/lib/xcat/plugins/dhcp.pm');
|
||||
|
||||
plan skip_all => "$plugin not found" unless -r $plugin;
|
||||
|
||||
my $source = slurp_repo_file('xCAT-server/lib/xcat/plugins/dhcp.pm');
|
||||
|
||||
my %branch = (
|
||||
aarch64 => qr/client-architecture = 00:0b \{[^\n]*\n\s*push \@netent, "\s*filename \\"boot\/grub2\/grub2\.aarch64\\";/,
|
||||
riscv64 => qr/client-architecture = 00:1b \{[^\n]*\n\s*push \@netent, "\s*filename \\"boot\/grub2\/grub2\.riscv64\\";/,
|
||||
opal => qr/client-architecture = 00:0e \{/,
|
||||
yaboot => qr/substring\(filename,0,1\) = null \{[^\n]*\n\s*push \@netent, "\s*filename \\"\/yaboot\\";/,
|
||||
like(
|
||||
$rendered,
|
||||
qr/client-architecture = 00:0b \{ #aaarch64\n\s+filename "boot\/grub2\/grub2\.aarch64";/,
|
||||
'the ISC policy renders the aarch64 boot branch',
|
||||
);
|
||||
like(
|
||||
$rendered,
|
||||
qr/client-architecture = 00:1b \{ #riscv64 uefi\n\s+filename "boot\/grub2\/grub2\.riscv64";/,
|
||||
'the ISC policy renders the riscv64 TFTP boot branch',
|
||||
);
|
||||
like(
|
||||
$rendered,
|
||||
qr/client-architecture = 00:1c \{ #riscv64 uefi http boot\n\s+option vendor-class-identifier "HTTPClient";\n\s+filename "http:\/\/192\.0\.2\.10:8080\/srv\/tftp\/boot\/grub2\/grub2\.riscv64";/,
|
||||
'the ISC policy renders the riscv64 HTTP boot branch with the subnet URL',
|
||||
);
|
||||
like(
|
||||
$rendered,
|
||||
qr/option conf-file = "http:\/\/192\.0\.2\.10:8080\/tftpboot\/pxelinux\.cfg\/p\/192\.0\.2\.0_24";/,
|
||||
'the existing OPAL branch keeps its subnet URL',
|
||||
);
|
||||
|
||||
my %pos;
|
||||
for my $name ( sort keys %branch ) {
|
||||
ok( $source =~ $branch{$name}, "the ISC subnet block renders the $name branch" )
|
||||
or next;
|
||||
$pos{$name} = $-[0];
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'not every branch was found', 3 unless 4 == scalar keys %pos;
|
||||
cmp_ok( $pos{aarch64}, '<', $pos{riscv64}, 'riscv64 follows the aarch64 branch' );
|
||||
cmp_ok( $pos{riscv64}, '<', $pos{opal}, 'riscv64 is rendered before the POWER OPAL branch' );
|
||||
cmp_ok( $pos{riscv64}, '<', $pos{yaboot}, 'riscv64 is rendered before the /yaboot fallback, so it is reachable' );
|
||||
}
|
||||
|
||||
# HTTP boot firmware (architecture id 28) needs the boot file as a URL and only
|
||||
# accepts an offer that is tagged HTTPClient
|
||||
ok(
|
||||
$source =~ /client-architecture = 00:1c \{[^\n]*\n\s*push \@netent, "\s*option vendor-class-identifier \\"HTTPClient\\";[^\n]*\n\s*push \@netent, "\s*filename \\"http:\/\/\$tftp\$portsuffix\$tftpdir\/boot\/grub2\/grub2\.riscv64\\";/,
|
||||
'the ISC subnet block hands RISC-V HTTP boot clients the boot loader as a URL',
|
||||
);
|
||||
my $httpboot_pos = $-[0];
|
||||
SKIP: {
|
||||
skip 'the riscv64 branches were not both found', 2 unless defined $pos{riscv64} && defined $httpboot_pos;
|
||||
cmp_ok( $pos{riscv64}, '<', $httpboot_pos, 'the PXE branch keeps its place before the HTTP boot branch' );
|
||||
cmp_ok( $httpboot_pos, '<', $pos{yaboot}, 'the HTTP boot branch is rendered before the /yaboot fallback' );
|
||||
}
|
||||
|
||||
my @riscv_ids = $source =~ /client-architecture = (00:1[9a-e])/g;
|
||||
my @riscv_ids = $rendered =~ /client-architecture = (00:1[9a-e])/g;
|
||||
is_deeply(
|
||||
[ sort @riscv_ids ],
|
||||
\@riscv_ids,
|
||||
[ '00:1b', '00:1c' ],
|
||||
'only the RISC-V 64-bit UEFI architecture ids (27 and 28) are mapped',
|
||||
'only the RISC-V 64-bit UEFI architecture ids are mapped',
|
||||
);
|
||||
|
||||
my $aarch64_pos = index($rendered, 'client-architecture = 00:0b');
|
||||
my $tftp_pos = index($rendered, 'client-architecture = 00:1b');
|
||||
my $http_pos = index($rendered, 'client-architecture = 00:1c');
|
||||
my $opal_pos = index($rendered, 'client-architecture = 00:0e');
|
||||
my $fallback_pos = index($rendered, 'substring(filename,0,1) = null');
|
||||
|
||||
cmp_ok($aarch64_pos, '<', $tftp_pos, 'riscv64 follows the aarch64 branch');
|
||||
cmp_ok($tftp_pos, '<', $http_pos, 'the TFTP branch precedes the HTTP branch');
|
||||
cmp_ok($http_pos, '<', $opal_pos, 'the HTTP branch precedes the OPAL branch');
|
||||
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');
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user