mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 17:46:38 +00:00
Merge pull request #4027 from hu-weihua/case_switch
test case for testing switch-based switch discovery key process
This commit is contained in:
commit
faff9c51e6
@ -0,0 +1,498 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use Data::Dumper;
|
||||
use Time::Local;
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
use integer;
|
||||
|
||||
#--------------command line attrbutes--------------
|
||||
my $needhelp = 0;
|
||||
my $discovery_mode = undef;
|
||||
my $discovery_target_switch = undef;
|
||||
my $dynamic_ip_range = undef;
|
||||
|
||||
#--------------global attributes----------------
|
||||
my $prpgram_path = dirname(File::Spec->rel2abs(__FILE__));
|
||||
my $program_name = basename($0);
|
||||
my $rst = 0;
|
||||
my @error = ();
|
||||
|
||||
my %node_error_info;
|
||||
my $original_target_switch_num = 0;
|
||||
my $failed_switch_num = 0;
|
||||
my @success_be_discovered_switches;
|
||||
|
||||
#The structure of %discovery_target_node_info
|
||||
# $discovery_target_switch_info{<switchname>}{<attribute>}
|
||||
my %discovery_target_switch_info;
|
||||
|
||||
my @expected_attrs_for_switch_based_switch_discovery = ("ip", "mac", "switch", "switchport");
|
||||
my $expected_attrs_for_switch_based_switch_discovery_str = join(",", @expected_attrs_for_switch_based_switch_discovery);
|
||||
|
||||
#$monitor_switch{<switchname>}{workingip}
|
||||
#$monitor_switch{<switchname>}{workinghostname}
|
||||
#$monitor_switch{<switchname>}{mac}
|
||||
#$monitor_switch{<switchname>}{discover_status}
|
||||
my %monitor_switch;
|
||||
|
||||
my %mac_nodename_map;
|
||||
my $pre_def_node_prefix = "xcattest_predef_";
|
||||
|
||||
#----------------------usage--------------------
|
||||
$::USAGE = "Usage:
|
||||
To test switch-based switch discovery key process: switch discovery, predefined node match and predefined node definition update.
|
||||
|
||||
To get help:
|
||||
$program_name -h
|
||||
To test switch-based switch discovery key process
|
||||
$program_name --discovery_target_switch <noderange> --dynamic_ip_range <iprange> --discovery_mode <mode>
|
||||
|
||||
Options:
|
||||
discovery_target_switch: Required. The target switches which are used to test switch-based switch discovery key process
|
||||
dynamic_ip_range: Required. A valid ip range which are working for target switches. They can be dynamic ip range offered by DHCP or static ip configurd by hand.
|
||||
discovery_mode: The protocol used by discovery process. If not set, using SNMP by default.
|
||||
";
|
||||
|
||||
|
||||
#==============================================================================================
|
||||
# main process
|
||||
#==============================================================================================
|
||||
if (
|
||||
!GetOptions("h" => \$needhelp,
|
||||
"discovery_mode=s" => \$discovery_mode,
|
||||
"discovery_target_switch=s" => \$discovery_target_switch,
|
||||
"dynamic_ip_range=s" => \$dynamic_ip_range)
|
||||
)
|
||||
{
|
||||
print "[ERROR] Invalid usage.\n\n$::USAGE";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($needhelp) {
|
||||
print "$::USAGE\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
unless (defined $discovery_target_switch and defined $dynamic_ip_range) {
|
||||
print "[ERROR] options 'discovery_target_switch' and 'dynamic_ip_range' are required.\n\n$::USAGE";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
if (!defined $discovery_mode) {
|
||||
$discovery_mode = "snmp";
|
||||
}
|
||||
|
||||
$SIG{TERM} = $SIG{INT} = sub {
|
||||
to_exit(1);
|
||||
};
|
||||
|
||||
print "----------------Check the configuration of test case itself----------------\n";
|
||||
$rst = check_test_case_self_conf(\@error);
|
||||
if ($failed_switch_num == $original_target_switch_num) {
|
||||
print "All node in noderange $discovery_target_switch have error, there is not a valid switch to do discovery\n";
|
||||
foreach my $node (sort keys %node_error_info) {
|
||||
print "$node : $node_error_info{$node}\n";
|
||||
}
|
||||
to_exit(1);
|
||||
} elsif ($failed_switch_num > 0) {
|
||||
print "There are $failed_switch_num nodes in noderange $discovery_target_switch have error\n";
|
||||
print "$_ : $node_error_info{$_}\n" foreach (sort keys %node_error_info);
|
||||
}
|
||||
|
||||
my $vaildnum = keys %monitor_switch;
|
||||
print "There are $vaildnum valid switch (" . join(",", (keys %monitor_switch)) . ") will do discvoery test\n";
|
||||
|
||||
#print Dumper \%monitor_switch;
|
||||
|
||||
print "----------------To clear up old environment and generate predefine node ----------------\n";
|
||||
$rst = backup_env(\@error);
|
||||
if ($rst) {
|
||||
print "To backup environment......Failed\n";
|
||||
to_exit(1);
|
||||
} else {
|
||||
print "To backup environment......pass\n";
|
||||
}
|
||||
|
||||
print "----------------To discover switches----------------\n";
|
||||
$rst = switch_discovery(\@error);
|
||||
if ($failed_switch_num) {
|
||||
my @tmp = keys %monitor_switch;
|
||||
my @discovery_err = deletearray(\@tmp, \@success_be_discovered_switches);
|
||||
if (@discovery_err) {
|
||||
print "There are some issue in discovery process\n";
|
||||
foreach my $switch (@discovery_err) {
|
||||
if ($node_error_info{$switch}) {
|
||||
print "$switch : $node_error_info{$switch}";
|
||||
}
|
||||
}
|
||||
}
|
||||
$rst = 1;
|
||||
} else {
|
||||
$rst = 0;
|
||||
}
|
||||
|
||||
foreach (@success_be_discovered_switches) {
|
||||
print "Below switch finished all switch_based switch discovery process\n";
|
||||
my $cmd = "lsdef $pre_def_node_prefix" . join(",$pre_def_node_prefix", @success_be_discovered_switches);
|
||||
my @output = runcmd("$cmd");
|
||||
dump_info(\@output);
|
||||
}
|
||||
to_exit($rst);
|
||||
|
||||
#=============================================================================================
|
||||
# sub functions
|
||||
#==============================================================================================
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: check_test_case_self_conf
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub check_test_case_self_conf {
|
||||
my $error_ref = shift;
|
||||
@$error_ref = ();
|
||||
|
||||
my $current_node;
|
||||
my @output = runcmd("lsdef $discovery_target_switch");
|
||||
foreach (@output) {
|
||||
if ($_ =~ /^Error: Could not find an object named '(.+)' of type .+/i) {
|
||||
$node_error_info{$1} = "without node definition in current mn";
|
||||
++$original_target_switch_num;
|
||||
++$failed_switch_num;
|
||||
} elsif ($_ =~ /^\s*Object name: (\w+)/i) {
|
||||
$current_node = $1;
|
||||
++$original_target_switch_num;
|
||||
} elsif ($_ =~ /^\s+(\w+)\s*=\s*(.*)/) {
|
||||
$discovery_target_switch_info{$current_node}{$1} = $2;
|
||||
if ($1 eq "mac") {
|
||||
my $tmp_mac = lc($2);
|
||||
$mac_nodename_map{$2} = $current_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1 if ($original_target_switch_num == $failed_switch_num);
|
||||
|
||||
# print "<mac_nodename_map>\n";
|
||||
# print Dumper \%mac_nodename_map;
|
||||
# print Dumper \%discovery_target_switch_info;
|
||||
# print "original_target_switch_num=$original_target_switch_num\n";
|
||||
# print "failed_switch_num = $failed_switch_num\n";
|
||||
|
||||
foreach my $switch (keys %discovery_target_switch_info) {
|
||||
my @miss_attr;
|
||||
foreach (@expected_attrs_for_switch_based_switch_discovery) {
|
||||
unless (defined($discovery_target_switch_info{$switch}{$_})) {
|
||||
push @miss_attr, $_;
|
||||
}
|
||||
}
|
||||
if (@miss_attr) {
|
||||
$node_error_info{$switch} = "miss attribute " . join(",", @miss_attr);
|
||||
++$failed_switch_num;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach my $switch (keys %node_error_info) {
|
||||
delete $discovery_target_switch_info{$switch} if ($discovery_target_switch_info{$switch});
|
||||
}
|
||||
return 1 if ($original_target_switch_num == $failed_switch_num);
|
||||
|
||||
# print "===========================\n";
|
||||
# print Dumper \%discovery_target_switch_info;
|
||||
# print "original_target_switch_num=$original_target_switch_num\n";
|
||||
# print "failed_switch_num = $failed_switch_num\n";
|
||||
# print Dumper \%node_error_info;
|
||||
# print "===========================\n";
|
||||
|
||||
my @ips = parse_dynamic_ip_range($dynamic_ip_range);
|
||||
|
||||
#print Dumper \@ips;
|
||||
my $without_working_ip = $original_target_switch_num - $failed_switch_num;
|
||||
my $trytime = 10;
|
||||
while ($trytime && $without_working_ip) {
|
||||
|
||||
#print "> try $trytime\n";
|
||||
#print Dumper \@ips;
|
||||
my @matchedip;
|
||||
foreach my $ip (@ips) {
|
||||
my $cmd = "ping -c 2 $ip >/dev/null 2>&1";
|
||||
|
||||
#print "[RUN: $cmd]\n";
|
||||
runcmd("$cmd");
|
||||
$cmd = "arp $ip";
|
||||
|
||||
#print "[RUN: $cmd]\n";
|
||||
my @output = runcmd("$cmd");
|
||||
|
||||
#print Dumper \@output;
|
||||
foreach (@output) {
|
||||
if ($_ =~ / (\w){2}:(\w){2}:(\w){2}:(\w){2}:(\w){2}:(\w){2} /) {
|
||||
|
||||
#print "-->$_\n";
|
||||
my @value = split(" ", $_);
|
||||
my $arp_mc = lc($value[2]);
|
||||
if (grep(/$arp_mc/, (keys %mac_nodename_map))) {
|
||||
$monitor_switch{ $mac_nodename_map{$arp_mc} }{workingip} = $ip;
|
||||
$monitor_switch{ $mac_nodename_map{$arp_mc} }{mac} = $arp_mc;
|
||||
$monitor_switch{ $mac_nodename_map{$arp_mc} }{discover_status} = 0b000;
|
||||
--$without_working_ip;
|
||||
push @matchedip, $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#print "matchedip dumper\n";
|
||||
#print Dumper \@matchedip;
|
||||
@ips = deletearray(\@ips, \@matchedip);
|
||||
|
||||
#print Dumper \@ips;
|
||||
--$trytime;
|
||||
}
|
||||
|
||||
if ($without_working_ip) {
|
||||
$failed_switch_num += $without_working_ip;
|
||||
}
|
||||
|
||||
my @left_nodes = keys %discovery_target_switch_info;
|
||||
my @tmp_monitor_switch = keys %monitor_switch;
|
||||
my @without_workingip_nodes = deletearray(\@left_nodes, \@tmp_monitor_switch);
|
||||
|
||||
foreach (@without_workingip_nodes) {
|
||||
$node_error_info{$_} = "has not gotten a working ip from DHCP or configuration manually";
|
||||
delete $discovery_target_switch_info{$_};
|
||||
}
|
||||
|
||||
if ($failed_switch_num) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: to_exit
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub to_exit {
|
||||
my $exit_code = shift;
|
||||
|
||||
print "-----------To restore original environment--------------\n";
|
||||
my $cmd;
|
||||
|
||||
#delete predefine node used by test
|
||||
my @output = runcmd("lsdef");
|
||||
my @predefnodes;
|
||||
foreach (@output) {
|
||||
if ($_ =~ /^($pre_def_node_prefix.+) \(node\)/) {
|
||||
push @predefnodes, $1;
|
||||
}
|
||||
}
|
||||
if (@predefnodes) {
|
||||
$cmd = "rmdef " . join(",", @predefnodes);
|
||||
print "To run <$cmd>\n";
|
||||
runcmd("$cmd");
|
||||
}
|
||||
|
||||
#to restore original node definition
|
||||
foreach my $switch (keys %discovery_target_switch_info) {
|
||||
$cmd = "chdef $switch ";
|
||||
foreach my $attr (keys %{ $discovery_target_switch_info{$switch} }) {
|
||||
if ($attr ne "postscripts" and $attr ne "postbootscripts") {
|
||||
$cmd .= "$attr='$discovery_target_switch_info{$switch}{$attr}' ";
|
||||
}
|
||||
}
|
||||
print "To run <$cmd>\n";
|
||||
runcmd("$cmd");
|
||||
}
|
||||
|
||||
exit $exit_code;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: runcmd
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub runcmd {
|
||||
my ($cmd) = @_;
|
||||
my $rc = 0;
|
||||
$::RUNCMD_RC = 0;
|
||||
my $outref = [];
|
||||
|
||||
@$outref = `$cmd 2>&1`;
|
||||
if ($?)
|
||||
{
|
||||
$rc = $?;
|
||||
$::RUNCMD_RC = $rc;
|
||||
}
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: dump_info
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub dump_info {
|
||||
my $error_ref = shift;
|
||||
foreach (@$error_ref) {
|
||||
print "$_\n";
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: switch_discovery
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub switch_discovery {
|
||||
my $error_ref = shift;
|
||||
|
||||
my $cmd;
|
||||
my @output;
|
||||
|
||||
print "To do switch_based switch discovery for below predefined switches:\n";
|
||||
foreach my $switch (keys %monitor_switch) {
|
||||
$cmd = "lsdef $pre_def_node_prefix$switch";
|
||||
@output = runcmd("$cmd");
|
||||
dump_info(\@output);
|
||||
}
|
||||
|
||||
$cmd = "switchdiscover --range $dynamic_ip_range -s $discovery_mode -w";
|
||||
print "To run <$cmd> ...";
|
||||
@output = runcmd("$cmd");
|
||||
if ($::RUNCMD_RC) {
|
||||
print "failed\n";
|
||||
dump_info(\@output);
|
||||
return 1;
|
||||
}
|
||||
print "ok\n";
|
||||
|
||||
dump_info(\@output);
|
||||
foreach my $line (@output) {
|
||||
if ($line =~ /^(\d)+\.(\d)+\.(\d)+\.(\d)+/) {
|
||||
my @values = split(" ", $line);
|
||||
if (grep(/$values[4]/, (keys %mac_nodename_map))) {
|
||||
if ($values[0] eq $monitor_switch{ $mac_nodename_map{ $values[4] } }{workingip}) {
|
||||
$monitor_switch{ $mac_nodename_map{ $values[4] } }{discover_status} |= 0b001;
|
||||
$monitor_switch{ $mac_nodename_map{ $values[4] } }{workinghostname} = $values[1];
|
||||
}
|
||||
}
|
||||
} elsif ($line =~ /switch discovered and matched:\s+(.+)\s+to\s+(.+)/) {
|
||||
my $opt_sw = $1;
|
||||
my $opt_pre = $2;
|
||||
if ($opt_pre =~ /$pre_def_node_prefix(.+)/) {
|
||||
my $sname = $1;
|
||||
if ($monitor_switch{$sname}{workinghostname} eq $opt_sw) {
|
||||
$monitor_switch{$sname}{discover_status} |= 0b010;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cmd = "lsdef $pre_def_node_prefix" . join(",$pre_def_node_prefix", (keys %monitor_switch)) . " -i mac -c";
|
||||
@output = runcmd("$cmd");
|
||||
foreach my $line (@output) {
|
||||
my @values = split("=", $line);
|
||||
my $mac = $values[1];
|
||||
my $sname;
|
||||
if ($values[0] =~ /$pre_def_node_prefix(.+):/) {
|
||||
$sname = $1;
|
||||
}
|
||||
if ($mac) {
|
||||
if ($monitor_switch{$sname}{mac} eq $mac) {
|
||||
$monitor_switch{$sname}{discover_status} |= 0b100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $switch (keys %monitor_switch) {
|
||||
if ($monitor_switch{$switch}{discover_status} == 0b001) {
|
||||
$node_error_info{$switch} = "be discovered, but failed to match pre-defined node $pre_def_node_prefix$switch";
|
||||
++$failed_switch_num;
|
||||
} elsif ($monitor_switch{$switch}{discover_status} == 0b011) {
|
||||
$node_error_info{$switch} = "be discovered and matched, but failed to update pre-defined node info in DB";
|
||||
++$failed_switch_num;
|
||||
} elsif ($monitor_switch{$switch}{discover_status} == 0b111) {
|
||||
push @success_be_discovered_switches, $switch;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: parse_dynamic_ip_range
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub parse_dynamic_ip_range {
|
||||
my $original_dynamic_ip_str = shift;
|
||||
my @sec = split(/\./, $original_dynamic_ip_str);
|
||||
for (my $i = 0 ; $i <= $#sec ; $i++) {
|
||||
$sec[$i] = "{$1..$2}" if ($sec[$i] =~ /(\d+)-(\d+)/);
|
||||
}
|
||||
my $str = join(".", @sec);
|
||||
my @output = runcmd("echo $str");
|
||||
return split(/ /, $output[0]);
|
||||
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: backup_env
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub backup_env {
|
||||
my $rst = 0;
|
||||
|
||||
foreach my $switch (keys %discovery_target_switch_info) {
|
||||
my @cmds = ("rmdef $switch",
|
||||
"mkdef -t node $pre_def_node_prefix$switch groups=switch mgt=switch nodetype=switch switch=$discovery_target_switch_info{$switch}{switch} switchport=$discovery_target_switch_info{$switch}{switchport}");
|
||||
foreach my $cmd (@cmds) {
|
||||
print "To run <$cmd>...";
|
||||
my @output = runcmd("$cmd");
|
||||
if ($::RUNCMD_RC) {
|
||||
print "failed\n";
|
||||
dump_info(\@output);
|
||||
return 1;
|
||||
} else {
|
||||
print "ok\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: deletearray
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
#--------------------------------------------------------
|
||||
sub deletearray {
|
||||
my $org_arr_ref = shift;
|
||||
my $del_arr_ref = shift;
|
||||
my @left_arr = ();
|
||||
|
||||
foreach my $i (@{$org_arr_ref}) {
|
||||
push @left_arr, $i unless (grep(/$i/, @{$del_arr_ref}));
|
||||
}
|
||||
return @left_arr;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user