diff --git a/xCAT-test/unit/template_install_device.t b/xCAT-test/unit/template_install_device.t index 440a28b44..4a5f2e518 100644 --- a/xCAT-test/unit/template_install_device.t +++ b/xCAT-test/unit/template_install_device.t @@ -6,7 +6,6 @@ use File::Spec; use FindBin; use Test::More; -my $root = File::Spec->catdir( $FindBin::Bin, '..', '..' ); BEGIN { push @INC, File::Spec->catdir( $FindBin::Bin, '..', '..', 'perl-xCAT' ), @@ -52,75 +51,106 @@ is( $p->{mac}, $MAC1, 'the tagged entry for the node is selected' ); # Ubuntu keeps its own return shape over the same resolution. my ( $setname, $macaddress ) = xCAT::Template::subiquity_install_netcfg( 'eth1', '', $MAC1, $NODE ); -is( $setname, 'eth1', 'netplan is given the interface to rename to' ); -is( $macaddress, lc($MAC1), 'netplan is given the address, lower cased' ); +is( $setname, 'eth1', 'netplan is given the interface to rename to' ); +is( $macaddress, lc($MAC1), 'netplan is given the address, lower cased' ); ( $setname, $macaddress ) = xCAT::Template::subiquity_install_netcfg( '', '', $MAC1, $NODE ); is( $setname, '', 'netplan renames nothing when no interface is named' ); is( $macaddress, lc($MAC1), 'netplan still matches on the address' ); -# The kickstart names one device. It takes the interface when one is named and -# the address otherwise, and it lower cases either. -sub ks_device { - my ( $installnic, $primarynic, $macentry, $nodename ) = @_; - my $params = - xCAT::Template::install_device_params( $installnic, $primarynic, $macentry, $nodename ); - my $macaddr = defined( $params->{mac} ) ? lc( $params->{mac} ) : ''; - return defined( $params->{nicname} ) ? $params->{nicname} : $macaddr; +{ + package Local::TemplateInstallTable; + + sub getNodeAttribs { + my ($self) = @_; + return $self->{row}; + } + + sub setNodeAttribs { + my ( $self, undef, $attrs ) = @_; + $self->{written} = { %{$attrs} }; + return 1; + } } -is( ks_device( '', '', $MAC1, $NODE ), lc($MAC1), +# Exercise kickstartnetwork itself with in-memory table objects. This verifies +# the generated kickstart line rather than the text of Template.pm. +sub kickstart_network { + my ( $installnic, $primarynic, $macentry, $mode ) = @_; + + my $mactab = bless { row => { mac => $macentry } }, 'Local::TemplateInstallTable'; + my $nrtab = bless { + row => { + installnic => $installnic, + primarynic => $primarynic, + } + }, + 'Local::TemplateInstallTable'; + my $hoststab = bless {}, 'Local::TemplateInstallTable'; + my $autoula_mac; + + no warnings qw(redefine once); + local *xCAT::Table::new = sub { + my ( undef, $table ) = @_; + return $mactab if $table eq 'mac'; + return $nrtab if $table eq 'noderes'; + return $hoststab if $table eq 'hosts'; + die "Unexpected table $table"; + }; + local *xCAT::Template::autoulaaddress = sub { + ($autoula_mac) = @_; + return 'fd00::1'; + }; + local $::XCATSITEVALS{managedaddressmode} = $mode || 'dhcp'; + + my $line = xCAT::Template::kickstartnetwork(); + return ( $line, $autoula_mac, $hoststab->{written} ); +} + +sub ks_device { + my ($line) = kickstart_network(@_); + return $line =~ /--device=(\S+)/ ? $1 : undef; +} + +is( ks_device( '', '', $MAC1 ), lc($MAC1), 'a node setting neither attribute keeps the address it has today' ); -is( ks_device( 'eth1', '', $MAC1, $NODE ), 'eth1', +is( ks_device( 'eth1', '', $MAC1 ), 'eth1', 'a node setting installnic names that interface' ); -is( ks_device( $MAC2, '', $MAC1, $NODE ), lc($MAC2), +is( ks_device( $MAC2, '', $MAC1 ), lc($MAC2), 'a node whose installnic carries an address names that address' ); # The defect this closes: a bare multi address entry resolves to the LAST # address, which need not be the adapter that deploys the node. Setting # installnic must override that. my $BARE = "$MAC1|$MAC2"; -is( ks_device( '', '', $BARE, $NODE ), lc($MAC2), +is( ks_device( '', '', $BARE ), lc($MAC2), 'a bare multi address entry alone still resolves to the last address' ); -is( ks_device( 'eth0', '', $BARE, $NODE ), 'eth0', +is( ks_device( 'eth0', '', $BARE ), 'eth0', 'installnic overrides a bare multi address entry' ); # An interface name is case sensitive. A node on POWER carries names such as # enP1p12s0f0, which no longer name a device once they are lower cased. Only # an address may be lower cased. my $MIXED = 'enP1p12s0f0'; -is( ks_device( $MIXED, '', $MAC1, $NODE ), $MIXED, +is( ks_device( $MIXED, '', $MAC1 ), $MIXED, 'the kickstart keeps the case of the interface name' ); -is( ks_device( '', $MIXED, $MAC1, $NODE ), $MIXED, +is( ks_device( '', $MIXED, $MAC1 ), $MIXED, 'the kickstart keeps the case of a primarynic interface name' ); my ($mixedset) = xCAT::Template::subiquity_install_netcfg( $MIXED, '', $MAC1, $NODE ); is( $mixedset, $MIXED, 'Ubuntu keeps the case of the interface name too' ); -is( ks_device( '', '', uc($MAC1), $NODE ), lc($MAC1), +is( ks_device( '', '', uc($MAC1) ), lc($MAC1), 'an address is still lower cased' ); -# The source has to keep the unique local address built from the hardware -# address, not from the device name. -my $src = File::Spec->catfile( $root, 'xCAT-server', 'lib', 'perl', 'xCAT', 'Template.pm' ); -open( my $fh, '<', $src ) or die "Unable to read $src: $!"; -my $source = do { local $/; <$fh> }; -close($fh); - -my ($ksbody) = $source =~ /\nsub kickstartnetwork \{(.*?)\n\}\n/s; -ok( defined($ksbody), 'the kickstartnetwork body was located' ); - -like( $ksbody, qr/install_device_params\(/, - 'the kickstart resolves the device through the shared helper' ); -unlike( $ksbody, qr/parseMacTabEntry/, - 'the kickstart no longer names the device from mac.mac alone' ); -like( $ksbody, qr/my \$ulaaddr = autoulaaddress\(\$macaddr\)/, - 'the unique local address is built from the address, not the device name' ); -unlike( $ksbody, qr/lc\(\$params->\{nicname\}\)/, - 'the kickstart never lower cases the interface name' ); -my ($ubbody) = $source =~ /\nsub subiquity_install_netcfg \{(.*?)\n\}\n/s; -ok( defined($ubbody), 'the subiquity_install_netcfg body was located' ); -like( $ubbody, qr/install_device_params\(/, 'Ubuntu shares the same helper' ); -unlike( $ubbody, qr/gen_net_boot_params|parseMacTabEntry/, - 'Ubuntu no longer re-derives the resolution itself' ); +# autoula must derive the address from the hardware address even when the +# kickstart selects an interface by name. +my ( $autoula_line, $autoula_mac, $hostattrs ) = + kickstart_network( $MIXED, '', $MAC1, 'autoula' ); +is( $autoula_line, + "network --onboot=yes --bootproto=static --device=$MIXED --noipv4 --ipv6=fd00::1", + 'autoula keeps the selected interface in the kickstart line' ); +is( $autoula_mac, lc($MAC1), + 'autoula derives the address from the MAC, not the interface name' ); +is( $hostattrs->{ip}, 'fd00::1', 'the generated ULA is saved in the hosts table' ); done_testing();