mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-05 12:37:54 +00:00
113 lines
4.4 KiB
Perl
Executable File
113 lines
4.4 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
use strict;
|
|
use warnings;
|
|
|
|
use File::Spec;
|
|
use FindBin;
|
|
use Test::More;
|
|
|
|
my $repo_root = $ENV{XCAT_REPO_ROOT}
|
|
|| File::Spec->catdir( $FindBin::Bin, '..', '..' );
|
|
unshift @INC, File::Spec->catdir( $repo_root, 'perl-xCAT' );
|
|
require xCAT::NetworkUtils;
|
|
|
|
subtest 'isIpv4addr accepts host addresses' => sub {
|
|
my @accepted = qw(10.0.0.1 192.168.0.1 172.16.254.10 255.255.255.255);
|
|
foreach my $address (@accepted) {
|
|
ok( xCAT::NetworkUtils->isIpv4addr($address), "$address is accepted" );
|
|
}
|
|
ok( xCAT::NetworkUtils::isIpv4addr('10.0.0.1'),
|
|
'the function form works without a class argument' );
|
|
ok( xCAT::NetworkUtils->isIpaddr('10.0.0.1'),
|
|
'the deprecated isIpaddr alias still answers' );
|
|
ok( !xCAT::NetworkUtils->isIpaddr('fe80::1'),
|
|
'the alias keeps the strict IPv4 contract' );
|
|
};
|
|
|
|
subtest 'isIpv4addr rejects invalid or ambiguous forms' => sub {
|
|
my @rejected = (
|
|
[ '192.168.001.010', 'leading-zero octets are octal to some resolvers' ],
|
|
[ '0.1.2.3', 'a host address cannot start with zero' ],
|
|
[ '0.0.0.0', 'all-zero is a call-site policy, not a host address' ],
|
|
[ '256.1.1.1', 'octet above 255' ],
|
|
[ '1.2.3', 'three-part form' ],
|
|
[ '1.2.3.4.5', 'five-part form' ],
|
|
[ 'fe80::1', 'IPv6 is outside the IPv4 contract' ],
|
|
[ 'bmc.example.test', 'hostnames are not addresses' ],
|
|
[ '', 'empty value' ],
|
|
);
|
|
foreach my $case (@rejected) {
|
|
my ( $value, $reason ) = @{$case};
|
|
ok( !xCAT::NetworkUtils->isIpv4addr($value), "'$value' is rejected: $reason" );
|
|
}
|
|
ok( !xCAT::NetworkUtils->isIpv4addr(undef), 'undef is rejected' );
|
|
};
|
|
|
|
subtest 'isIpv6addr validates IPv6 syntax' => sub {
|
|
my @accepted = ( 'fe80::1', '::1', '::', '2001:db8::1', '::ffff:10.1.1.1' );
|
|
foreach my $address (@accepted) {
|
|
ok( xCAT::NetworkUtils->isIpv6addr($address), "$address is accepted" );
|
|
}
|
|
my @rejected = (
|
|
[ 'not:an:ip', 'colon text is not an address' ],
|
|
[ ':::::', 'malformed compression' ],
|
|
[ 'fe80::zzzz', 'invalid hex digits' ],
|
|
[ 'fe80::1%eth0', 'zone identifiers are platform-dependent and rejected' ],
|
|
[ '10.0.0.1', 'IPv4 is outside the IPv6 contract' ],
|
|
[ '', 'empty value' ],
|
|
);
|
|
foreach my $case (@rejected) {
|
|
my ( $value, $reason ) = @{$case};
|
|
ok( !xCAT::NetworkUtils->isIpv6addr($value), "'$value' is rejected: $reason" );
|
|
}
|
|
ok( !xCAT::NetworkUtils->isIpv6addr(undef), 'undef is rejected' );
|
|
ok( xCAT::NetworkUtils::isIpv6addr('::1'),
|
|
'the function form works without a class argument' );
|
|
};
|
|
|
|
sub socket6_fallback_ok {
|
|
ok( !defined &Socket::inet_pton, 'core inet_pton is absent' );
|
|
ok( xCAT::NetworkUtils->isIpv6addr('2001:db8::1'),
|
|
'a valid IPv6 address is accepted through Socket6' );
|
|
ok( !xCAT::NetworkUtils->isIpv6addr('fe80::zzzz'),
|
|
'an invalid IPv6 address is still rejected through Socket6' );
|
|
return;
|
|
}
|
|
|
|
subtest 'isIpv6addr falls back to Socket6 without core inet_pton' => sub {
|
|
no warnings qw(once redefine);
|
|
if ( defined &Socket6::inet_pton ) {
|
|
local *Socket::inet_pton;
|
|
socket6_fallback_ok();
|
|
return;
|
|
}
|
|
plan skip_all => 'neither core inet_pton nor Socket6 is available'
|
|
unless defined &Socket::inet_pton;
|
|
|
|
# lend the core implementation to Socket6 so the fallback path runs
|
|
# where Socket6 is not installed
|
|
my $core_pton = \&Socket::inet_pton;
|
|
my $af6 = Socket::AF_INET6();
|
|
local *Socket6::inet_pton = sub { return $core_pton->(@_) };
|
|
local *Socket6::AF_INET6 = sub { return $af6 };
|
|
local *Socket::inet_pton;
|
|
socket6_fallback_ok();
|
|
};
|
|
|
|
subtest 'isValidIp accepts both families and nothing else' => sub {
|
|
ok( xCAT::NetworkUtils->isValidIp('10.0.0.1'), 'IPv4 delegates to isIpv4addr' );
|
|
ok( xCAT::NetworkUtils->isValidIp('fe80::1'), 'IPv6 delegates to isIpv6addr' );
|
|
my @rejected = (
|
|
'not:an:ip', 'fe80::1%eth0', '192.168.001.010', '0.0.0.0',
|
|
'bmc.example.test', '',
|
|
);
|
|
foreach my $value (@rejected) {
|
|
ok( !xCAT::NetworkUtils->isValidIp($value), "'$value' is rejected" );
|
|
}
|
|
ok( !xCAT::NetworkUtils->isValidIp(undef), 'undef is rejected' );
|
|
ok( xCAT::NetworkUtils::isValidIp('10.0.0.1'),
|
|
'the function form works without a class argument' );
|
|
};
|
|
|
|
done_testing();
|