mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-30 02:42:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			549 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			549 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| ###############################################################################
 | |
| # This script is used for rest-api automation test
 | |
| # Flags are used for test input:
 | |
| #     -m method. Should be GET, POST, PUT, DELETE
 | |
| #     -r resource
 | |
| #     -t
 | |
| #     -h host
 | |
| #     -u user
 | |
| #     -p passwd
 | |
| #     -P port (BC)
 | |
| #     -d data
 | |
| #     -c cert
 | |
| #     --debug
 | |
| # Flags are used for check output:
 | |
| #     -o expected output
 | |
| #     -O logical operator
 | |
| #
 | |
| # Expected result format is '{ANY:{ANY:content}}'
 | |
| # These steps are used to explain how to scan result
 | |
| #     step 1. go through to see if content can be found
 | |
| #     step 2. compare content if found
 | |
| # options are used as followed:
 | |
| #    == returns 0 if found and equal, returns 1 if not found or found but not equal
 | |
| #    != returns 0 if found, returns 1 if not found
 | |
| #    =~ returns 0 if match, returns 1 if not match
 | |
| #    !=~ returns 0 if not match, returns 1 if match
 | |
| ################################################################################
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| use Getopt::Long qw{:config  bundling no_ignore_case};
 | |
| use Data::Dumper;
 | |
| use strict;
 | |
| my $help;
 | |
| my $method;
 | |
| my $token;
 | |
| my $usetoken;
 | |
| my $resource;
 | |
| my $host;
 | |
| my $user;
 | |
| my $passwd;
 | |
| my $port;
 | |
| my $data;
 | |
| my $cert;
 | |
| my $output;
 | |
| my $loperator;
 | |
| my $debug;
 | |
| my $defaulthash;
 | |
| my $defaulthttpresult = 0;
 | |
| my $outputfile        = "/tmp/testrestapiresult";
 | |
| 
 | |
| if (
 | |
|     !GetOptions("h|?" => \$help,
 | |
|         "m=s"   => \$method,
 | |
|         "t"     => \$usetoken, # use generated token instead of the user/pw
 | |
|         "r=s"   => \$resource,
 | |
|         "h=s"   => \$host,
 | |
|         "u=s"   => \$user,
 | |
|         "p=s"   => \$passwd,
 | |
|         "P=s"   => \$port,
 | |
|         "d=s"   => \$data,
 | |
|         "c=s"   => \$cert,
 | |
|         "o=s"   => \$output,
 | |
|         "O=s"   => \$loperator,
 | |
|         "debug" => \$debug,
 | |
|     )
 | |
|   ) {
 | |
|     &usage;
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| ##############################################################
 | |
| # return help
 | |
| ##############################################################
 | |
| if ($help) {
 | |
|     &usage;
 | |
|     exit 0;
 | |
| }
 | |
| ##############################################################
 | |
| # flag check
 | |
| ##############################################################
 | |
| if ($method) {
 | |
|     unless ($resource) {
 | |
|         print "-m must be used with -r \n";
 | |
|         &usage;
 | |
|         exit 0;
 | |
|     }
 | |
| }
 | |
| if ($resource) {
 | |
|     unless ($method) {
 | |
|         print "-r must be used with -m \n";
 | |
|         &usage;
 | |
|         exit 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| ##############################################################
 | |
| # Give default values for optional vars.
 | |
| ###############################################################
 | |
| my $rootdir   = "$::XCATROOT/share/xcat/tools/autotest";
 | |
| my $resultdir = "$rootdir/result";
 | |
| my $logfile   = "$rootdir/result/restapitest.log";
 | |
| #logfile: /opt/xcat/share/xcat/tools/autotest/result/restapitest.log
 | |
| 
 | |
| unless (($user) && ($passwd)) {
 | |
| 
 | |
|     # No user or passwd passed in, read configuration file, they might be there
 | |
|     print "Userid and password must be supplied\n";
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| # get hostname or default to local host if not specified
 | |
| unless ($host) {
 | |
|     $host = "127.0.0.1";
 | |
| }
 | |
| 
 | |
| if ($usetoken) {
 | |
| # get token
 | |
|     my $gettoken = `curl -X POST -k 'https://$host/xcatws/tokens' -H Content-Type:application/json --data '{"userName":"$user","userPW":"$passwd"}' 2>/dev/null`;
 | |
|     my $reshash = parse_json($gettoken);
 | |
|     $token  = $$reshash{token}{id};
 | |
| }
 | |
| 
 | |
| # debug and log info
 | |
| log_debug(3, "User $user. \n");
 | |
| log_debug(3, "Password $passwd. \n");
 | |
| log_debug(3, "Host $host. \n");
 | |
| log_debug(3, "Got token $token. \n");
 | |
| 
 | |
| my $res = run_restapi($method, $resource, $data, "", $port, "$host", "$user", "$passwd", "$token");
 | |
| $defaulthttpresult = check_errcode();
 | |
| 
 | |
| print Dumper $res;
 | |
| exit $defaulthttpresult;
 | |
| 
 | |
| ################################################
 | |
| # begin subroutine
 | |
| ################################################
 | |
| 
 | |
| ##########
 | |
| # usage  #
 | |
| ##########
 | |
| sub usage
 | |
| {
 | |
|     print "Usage:testrestapi - Run xcat test cases.\n";
 | |
|     print "  testrestapi [-?|-h]\n";
 | |
|     print "  testrestapi [-m method] [-r resource] [-t tocken]\n";
 | |
|     print "  [-h host] [-P port][-u user] [-p passwd]\n";
 | |
|     print "  [-d data] [-c cert] \n";
 | |
|     print "  [-o expect_output] [-O logical_operator] \n";
 | |
|     print "  [--debug]\n";
 | |
|     print "\n";
 | |
|     return;
 | |
| }
 | |
| 
 | |
| 
 | |
| #######################
 | |
| # print debug infor   #
 | |
| # 1 for only log      #
 | |
| # 2 for only debug    #
 | |
| # 3 for log and debug #
 | |
| #######################
 | |
| sub log_debug
 | |
| {
 | |
|     my $flag = shift;
 | |
|     my $msg  = shift;
 | |
|     if ($flag & 0x2) {
 | |
|         if ($debug) {
 | |
|             if (ref($msg) eq 'HASH') {
 | |
|                 print Dumper($msg);
 | |
|             } elsif (ref($msg) eq 'ARRAY') {
 | |
|                 print Dumper($msg);
 | |
|             } else {
 | |
|                 print "$msg";
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     if ($flag & 0x1) {
 | |
|         open(LOG, ">>$logfile")
 | |
|           or return 1;
 | |
|         my $date = `date`;
 | |
|         print LOG "$date\: $msg\n";
 | |
|     }
 | |
| }
 | |
| #########################
 | |
| # run rest-api command  #
 | |
| #########################
 | |
| sub run_restapi
 | |
| {
 | |
|     my ($m, $r, $d, $c, $p, $h, $u, $a, $t) = @_;
 | |
|     my $cmd = "curl";
 | |
|     $cmd .= " -X $m";
 | |
|     unless ($c) {
 | |
|         $cmd .= " -k ";
 | |
|     } else {
 | |
|         $cmd .= " --cacert $c";
 | |
|     }
 | |
|     if ($t) {
 | |
|         $cmd .= " -H X-Auth-Token:$t ";
 | |
|     }
 | |
|     $cmd .= " 'https://$h";
 | |
|     if ($p) {
 | |
|         $cmd .= ":$p";
 | |
|     }
 | |
|     $cmd .= "/xcatws";
 | |
|     $cmd .= "$r?";
 | |
|     unless ($t) {
 | |
|         $cmd .= "userName=$u&userPW=$a";
 | |
|     }
 | |
|     $cmd .= "&pretty=1'";
 | |
|     if ($d) {
 | |
|         $cmd .= " -H Content-Type:application/json --data '$d'";
 | |
|     }
 | |
|     $cmd .= " -D /tmp/err.log";
 | |
|     log_debug(1, "Begin to run restapi test with $cmd");
 | |
|     my $res = `$cmd 2>/dev/null`;
 | |
|     log_debug(2, "run curl: $cmd\n");
 | |
|     log_debug(2, "result is $res\n");
 | |
|     if (!open(RESULT, ">$outputfile")) {
 | |
|         log_debug(1, "wirte outputfile error");
 | |
|     }
 | |
|     print RESULT $res;
 | |
|     close RESULT;
 | |
|     return $res;
 | |
| }
 | |
| 
 | |
| ############################
 | |
| # transfer json into hash  #
 | |
| ############################
 | |
| sub parse_json
 | |
| {
 | |
|     my $input = shift;
 | |
|     my %hash;
 | |
|     if ($input =~ /:/) {
 | |
| 
 | |
|         # for those who look like:
 | |
|         # {"networks":[{"mgtifname":"eth1","mask":"255.255.255.0"},{"mgtifname":"eth1","mask":"255.255.255.0"}]}
 | |
|         if ($input =~ /^\[(.*)\]$/s) {
 | |
|             my $content = $1;
 | |
|             # log_debug(2, "[:] content is $content \n");
 | |
|             parse_json($content);
 | |
|         }
 | |
| 
 | |
|         # for those who look like:
 | |
|         # {"Vc68m4hsp01":{"parent":"Server-9119-590-SN02C5F9E","pprofile":"Vc68m4hsp01"},"p5ih_c75vios":{"parent":"P5IH-SN02012EB-A","mgt":"hmc","id":"2"},"p5ih_lpar04":{"parent":"P5IH-SN02013EB-A","pprofile":"p5ih_lpar04"}}
 | |
|         elsif ($input =~ /^"(\S+?)\":{\S+},/) {
 | |
|             $input =~ s/},/}%/;
 | |
|             my @contents = split /%/, $input;
 | |
|             my @reval;
 | |
| 
 | |
|             # record result
 | |
|             foreach my $t (@contents) {
 | |
|                 #log_debug(2, ":{}, content is $t \n");
 | |
|                 my $re = parse_json($t);
 | |
|                 push @reval, $re;
 | |
|             }
 | |
| 
 | |
|             # merge hash
 | |
|             foreach my $t (@reval) {
 | |
|                 if (ref($t) =~ "HASH") {
 | |
|                     foreach my $k (keys %$t) {
 | |
|                         $hash{$k} = $$t{$k};
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return \%hash;
 | |
|         }
 | |
|         elsif ($input =~ /^{\S+},{\S+}/ and !($input =~ /]/)) {
 | |
|             $input =~ s/},{/}%{/;
 | |
|             my @contents = split /%/, $input;
 | |
|             my @reval;
 | |
| 
 | |
|             # record result
 | |
|             foreach my $t (@contents) {
 | |
|                 #log_debug(2, "{},{}, content is $t \n");
 | |
|                 my $re = parse_json($t);
 | |
|                 push @reval, $re;
 | |
|             }
 | |
| 
 | |
|             # merge hash
 | |
|             foreach my $t (@reval) {
 | |
|                 if (ref($t) =~ "HASH") {
 | |
|                     foreach my $k (keys %$t) {
 | |
|                         $hash{$k} = $$t{$k};
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return \%hash;
 | |
|         }
 | |
| 
 | |
|         # for those who look like
 | |
|         # {"clustersite":{"domain":"cluster.com","master":"192.168.1.15"}}
 | |
|         elsif ($input =~ /^\s*{(.*)}\s*$/s) {
 | |
|             my $content = $1;
 | |
|             #log_debug(2, "{} content is $content \n");
 | |
|             parse_json($content);
 | |
|         }
 | |
|         elsif ($input =~ /],\"\S+\":/) {
 | |
|             $input =~ s/],\"(\S+)\":/]%\"$1\":/;
 | |
|             my @contents = split /%/, $input;
 | |
|             my @reval;
 | |
| 
 | |
|             # record result
 | |
|             foreach my $t (@contents) {
 | |
|                 #log_debug(2, "],:, content is $t \n");
 | |
|                 my $re = parse_json($t);
 | |
|                 push @reval, $re;
 | |
|             }
 | |
| 
 | |
|             # merge hash
 | |
|             foreach my $t (@reval) {
 | |
|                 if (ref($t) =~ "HASH") {
 | |
|                     foreach my $k (keys %$t) {
 | |
|                         $hash{$k} = $$t{$k};
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return \%hash;
 | |
|         }
 | |
| 
 | |
|         # for those who look like
 | |
|         # "domain":"cluster.com","master":"192.168.1.15"
 | |
|         elsif ($input =~ /,/ and !($input =~ /}/)) {
 | |
|             my @contents = split /,/, $input;
 | |
|             my @reval;
 | |
| 
 | |
|             # record result
 | |
|             foreach my $t (@contents) {
 | |
|                 #log_debug(2, ", content is $t \n");
 | |
|                 my $re = parse_json($t);
 | |
|                 push @reval, $re;
 | |
|             }
 | |
| 
 | |
|             # merge hash
 | |
|             foreach my $t (@reval) {
 | |
|                 if (ref($t) =~ "HASH") {
 | |
|                     foreach my $k (keys %$t) {
 | |
|                         $hash{$k} = $$t{$k};
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return \%hash;
 | |
| 
 | |
|         }
 | |
| 
 | |
|         # for those who look like:
 | |
|         # "clustersite":{"domain":"cluster.com","master":"192.168.1.15"}
 | |
|         # "domain":"cluster.com"
 | |
|         elsif ($input =~ /\"(\S+?)\":(.+)/s) {
 | |
|             my $key   = $1;
 | |
|             my $value = $2;
 | |
|             if ($value =~ /{/) {
 | |
| 
 | |
|                 # "clustersite":{"domain":"cluster.com","master":"192.168.1.15"}
 | |
|                 #log_debug(2, "{ content is $value \n");
 | |
|                 $hash{$key} = parse_json($value, $key);
 | |
|                 return \%hash;
 | |
|             } else {
 | |
| 
 | |
|                 # "domain":"cluster.com"
 | |
|                 $value =~ /\"(\S+)\"/;
 | |
|                 $hash{$key} = $1;
 | |
|                 return \%hash;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # for those who look like
 | |
|     # ["10.1.255.250","192.168.200.16","192.168.200.19","192.168.200.22"]
 | |
|     else {
 | |
|         if ($input =~ /^\[(.*)\]/s) {
 | |
|             my $content = $1;
 | |
|             #log_debug(2, "[] content is $content \n");
 | |
|             my @all = split /,/, $content;
 | |
|             foreach my $n (@all) {
 | |
|                 $n =~ /\"(.*)\"/;
 | |
|                 $hash{$1} = "restapiarray";
 | |
|             }
 | |
|             return \%hash;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| ############################
 | |
| # check curl running code  #
 | |
| ############################
 | |
| sub check_errcode
 | |
| {
 | |
|     if (!open(ERRLOG, "</tmp/err.log")) {
 | |
|         log_debug(1, "can't open err.log in tmp");
 | |
|         return 1;
 | |
|     }
 | |
|     my $num;
 | |
|     while (<ERRLOG>) {
 | |
|         if (/HTTP\/\w*\.*\w* (\w+) (\w+)/) {
 | |
|             $num = $1;
 | |
|             last;
 | |
|         }
 | |
|     }
 | |
|     close ERRLOG;
 | |
|     log_debug(2, "can't get errorcode\n") unless ($num);
 | |
|     return $num;
 | |
| }
 | |
| 
 | |
| ############################
 | |
| # check curl return result #
 | |
| ############################
 | |
| sub check_result
 | |
| {
 | |
|     my $data      = shift;
 | |
|     my $opterator = shift;
 | |
|     my $output    = shift;
 | |
|     if (!open(OUTPUT, "<$output")) {
 | |
|         log_debug(1, "can't read output file");
 | |
|         return 1;
 | |
|     }
 | |
|     my $res;
 | |
|     while (<OUTPUT>) {
 | |
|         $res .= $_;
 | |
|     }
 | |
|     close OUTPUT;
 | |
| 
 | |
|     log_debug(2, "\nbegin to parse json for expected value: \n");
 | |
|     my $expects = transf_hash(parse_json($data));    # one entry
 | |
|     log_debug(2, "\nbegin to parse json for actual result: \n");
 | |
|     my $actuals = transf_hash(parse_json($res));     # serval entries
 | |
| 
 | |
|     log_debug(2, "expected result is:\n");
 | |
|     log_debug(2, $expects);
 | |
|     log_debug(2, "testcase run result is \n");
 | |
|     log_debug(2, $actuals);
 | |
| 
 | |
|     my $flag = 0;
 | |
|     my %flaghash;
 | |
|     my $expect = $$expects[0];                       # $expect = ANY:ANY:x86_64
 | |
| 
 | |
|     my @expectvalue = split /:/, $expect;    #@expectvalue = ANY, ANY, x86_64
 | |
|     $flag = 0;
 | |
|     foreach my $expval (@expectvalue) {      # $expval = ANY
 | |
|         foreach my $actual (@$actuals) {     # $actual = nodetype:arch:x86_64
 | |
|             if ($flaghash{$actual} eq "none") {
 | |
|                 next;
 | |
|             }
 | |
|             my @actualvalue = split /:/, $actual; # @actualvalue = nodetype, arch, x86_64
 | |
|             log_debug(2, "begin to compare $expval and $actualvalue[$flag]");
 | |
| 
 | |
|             if (($expval eq "restapiarray") and ($actualvalue[$flag] eq "restapiarray")) {
 | |
|                 next;
 | |
|             }
 | |
| 
 | |
|             if (($expval eq $actualvalue[$flag]) or ($expval eq "ANY")) { #ANY =~ nodetype
 | |
|                 $flaghash{$actual} = "eq";
 | |
|             } elsif (($actualvalue[$flag] =~ $expval) or ($expval eq "ANY")) {
 | |
|                 $flaghash{$actual} = "match";
 | |
|             } else {
 | |
|                 $flaghash{$actual} = "none";
 | |
|             }
 | |
|             log_debug(2, ", compare result is $flaghash{$actual}\n");
 | |
|         }
 | |
|         $flag++;
 | |
|     }
 | |
|     log_debug(2, "search result is \n");
 | |
|     log_debug(2, \%flaghash);
 | |
| 
 | |
|     if ($opterator eq "!=") {
 | |
|         foreach my $val (keys %flaghash) {
 | |
|             if ($flaghash{$val} eq "eq") {
 | |
|                 log_debug(2, "compare result: failed\n");
 | |
|                 return 1;    # fail
 | |
|             }
 | |
|         }
 | |
|         log_debug(2, "compare result: succeed\n");
 | |
|         return 0;            #succeed
 | |
|     }
 | |
|     if ($opterator eq "==") {
 | |
|         foreach my $val (keys %flaghash) {
 | |
|             if ($flaghash{$val} eq "eq") {
 | |
|                 log_debug(2, "compare result: succeed\n");
 | |
|                 return 0;    # succeed
 | |
|             }
 | |
|         }
 | |
|         log_debug(2, "compare result: failed\n");
 | |
|         return 1;            #fail
 | |
|     }
 | |
| 
 | |
|     if ($opterator eq "=~") {
 | |
|         foreach my $val (keys %flaghash) {
 | |
|             if ($flaghash{$val} eq "match") {
 | |
|                 log_debug(2, "compare result: succeed\n");
 | |
|                 return 0;    # succeed
 | |
|             }
 | |
|         }
 | |
|         log_debug(2, "compare result: failed\n");
 | |
|         return 1;            #fail
 | |
|     }
 | |
|     if ($opterator eq "!=~") {
 | |
|         foreach my $val (keys %flaghash) {
 | |
|             if ($flaghash{$val} eq "match") {
 | |
|                 log_debug(2, "compare result: failed\n");
 | |
|                 return 1;    # fail
 | |
|             }
 | |
|         }
 | |
|         log_debug(2, "compare result: succeed\n");
 | |
|         return 0;            #succeed
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| ####################################
 | |
| # help to transfer hash into array #
 | |
| ####################################
 | |
| sub find_key
 | |
| {
 | |
|     my $input = shift;
 | |
|     my $en    = shift;
 | |
|     my $ou    = shift;
 | |
|     if (ref($input) =~ "HASH") {
 | |
|         foreach my $val (keys %$input) {
 | |
|             my $tmp = $$en;    # keey head
 | |
|             $$en .= "$val:";
 | |
|             my $t1 = find_key($$input{$val}, $en, $ou);
 | |
|             if ($$en eq "") {
 | |
|                 $$en = $tmp;    #restore head
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         $$en .= $input;
 | |
|         push @$ou, $$en;
 | |
|         $$en = "";              # clear entry;
 | |
|     }
 | |
| }
 | |
| 
 | |
| ############################
 | |
| # transfer hash into array #
 | |
| ############################
 | |
| sub transf_hash
 | |
| {
 | |
|     my $input = shift;
 | |
|     my $entry;
 | |
|     my @array;
 | |
|     find_key($input, \$entry, \@array);
 | |
|     return \@array;
 | |
| }
 | |
| 
 | |
| 
 |