X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/363ae066badd453c806244ee48a0f18da4643261..74d338023be703e83a3515bc3c97e698567620d9:/buildtools/Cmake/tesh.pl diff --git a/buildtools/Cmake/tesh.pl b/buildtools/Cmake/tesh.pl index 87e6adc2e0..bb2db788ef 100755 --- a/buildtools/Cmake/tesh.pl +++ b/buildtools/Cmake/tesh.pl @@ -1,105 +1,235 @@ #! /usr/bin/perl -w +=encoding UTF-8 + +=head1 NAME + +tesh -- testing shell + +=head1 SYNOPSIS + +B [I] I + +=cut + +use Pod::Usage qw(pod2usage); +use Getopt::Long qw(GetOptions); use strict; +use Term::ANSIColor; +use IPC::Open3; -if($#ARGV<0){die "Usage: tesh.pl \n";} -my($line1); -my($line2); -my($execline); -my($ok)=0; -my($ok1)=0; + +my($line1,$line2,$execline,$command,$command_tesh); +my($command_executed)=0; +my($expected_result_line)=0; my($sort)=0; my($nb_arg)=0; -my($result); -my(@list1)=(); -my(@list2)=(); -my(@list3)=(); +my(@list1,@list2,@list3,@list_of_commands)=(); my(@buffer)=(); -my($timeout)=-1; -my($parallel)=0; -my($verbose)=0; +my($timeout)=0; my($encore)=0; my($old_buffer); +my($linebis); +my($SIGABRT)=0; +my($no_output_ignore)=1; +my($verbose)=0; +my($return)=-1; +my($pid); +my($result); +my($result_err); +my($fich_name); +my($forked); +my($config)=""; -#options -do{ - if($ARGV[$nb_arg] =~ /^--cd$/) - { - $nb_arg++; - if(!$ARGV[$nb_arg] or $ARGV[$nb_arg] =~ /^--/){die "Usage: tesh.pl --cd \n";} - my($directory)=$ARGV[$nb_arg]; - if( -e $directory) - { - chdir("$directory"); - print "[Tesh/INFO] Change directory to \"$directory\"\n"; - } - else - { - die "[Tesh/CRITICAL] Directory not found : \"$directory\"\n"; - } - $nb_arg++; - } - elsif($ARGV[$nb_arg] =~ /^--setenv$/) - { - $nb_arg++; - if(!$ARGV[$nb_arg] or $ARGV[$nb_arg] =~ /^--/){die "Usage: tesh.pl --setenv environment_variable\n";} - if(!$ARGV[$nb_arg+1] or $ARGV[$nb_arg+1] =~ /^--/){die "Usage: tesh.pl --setenv environment_variable\n";} - $ENV{$ARGV[$nb_arg]} = "$ENV{$ARGV[$nb_arg]}:$ARGV[$nb_arg+1]"; - print "[Tesh/INFO] export $ARGV[$nb_arg]=\"$ENV{$ARGV[$nb_arg]}\"\n"; - $nb_arg++; - $nb_arg++; - } - elsif($ARGV[$nb_arg] =~ /^--verbose$/) - { - $verbose=1; - } - else - { - print "[Tesh/CRITICAL] Unrecognized option : $ARGV[$nb_arg]\n"; - $nb_arg++; - } -}while(($nb_arg) < $#ARGV); +my($tesh_command)=0; +my(@buffer_tesh)=(); + +# make sure we received a tesh file +scalar @ARGV > 0 || pod2usage(-exitval => 1); #Add current directory to path $ENV{PATH} = "$ENV{PATH}:."; -#tesh file -if(!$ARGV[$nb_arg]){die "tesh.pl \n";} -print "[Tesh/INFO] load file : $ARGV[$nb_arg]\n"; -my($file)=$ARGV[$nb_arg]; -open SH_LIGNE, $file or die "[Tesh/CRITICAL] Unable to open $file. $!\n"; + +#options +sub cd_cmd { + my $directory=$_[1]; + if (-e $directory) { + chdir("$directory"); + print "[Tesh/INFO] change directory to $directory\n"; + } else { + die "[Tesh/CRITICAL] Directory not found : \"$directory\"\n"; + } +} + +sub setenv_cmd { + if ($_[1] =~ /^(.*)=(.*)$/) { + my($var,$ctn)=($1,$2); + $ENV{$var} = $ctn; + print "[Tesh/INFO] setenv $var=$ctn\n"; + } else { + die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n"; + } +} + +my $tesh_file; +sub get_options { + # remove the tesh file from the ARGV used + my @ARGV = @_; + $tesh_file = pop @ARGV; + + # temporary arrays for GetOption + my @verbose = (); + my @cfg; + + my %opt = ( + "help" => 0, + "debug" => 0, + "verbose" => 0 + ); + + Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); + + GetOptions( + 'help|h' => \$opt{'help'}, + + 'verbose|v' => \@verbose, + 'debug|d' => \$opt{"debug"}, + + 'cd=s' => \&cd_cmd, + 'setenv=s' => \&setenv_cmd, + 'cfg=s' => \@cfg, + ); + + $opt{'verbose'} = scalar @verbose; + foreach (@cfg) { + $opt{'cfg'} .= " --cfg=$_"; + } + return %opt; +} + +my %opts = get_options(@ARGV); + +# parse tesh file +open SH_LIGNE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file: $!\n"; while(defined($line1=)) { - if($line1 =~ /^\$ /){ #command line - $line1 =~ s/\$\{srcdir\:\=\.\}/./g; + if($line1 =~ /^\< \$ /){ # arg command line + $line1 =~ s/\${EXEEXT:=}//g; + $line1 =~ s/^\< \$\ *//g; + $line1 =~ s/^.\/lua/lua/g; + $line1 =~ s/^.\/ruby/ruby/g; + $line1 =~ s/^.\///g; + $line1 =~ s/^tesh/.\/tesh/g; + $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g; + chomp $line1; + $command_tesh = $line1; + print "[Tesh/INFO] arg_exec_line : $command_tesh\n"; + } + elsif($line1 =~ /^\< \< /){ # arg buffer line + $line1 =~ s/^\< \<\ *//g; + chomp $line1; + print "[Tesh/INFO] arg_buffer_line : $line1\n"; + push @buffer_tesh, "$line1\n"; + } + elsif($line1 =~ /^\< \> /){ # arg output line + $line1 =~ s/^\< \>\ *//g; + $line1 =~ s/\r//g; + chomp $line1; + push @list2, $line1; + print "[Tesh/INFO] arg_output_line : $line1\n"; + $expected_result_line = 1; + } + elsif($line1 =~ /^\$ mkfile/){ # "mkfile" command line + $line1 =~ s/\$ //g; + $line1 =~ s/mkfile//g; + chomp $line1; + $fich_name = $line1; + $line1 =(); + print "[Tesh/INFO] exec_line : mkfile $fich_name\n"; + `rm -f $fich_name`; + open(FILE,">$fich_name") or die "[Tesh/CRITICAL] Unable to make file : $fich_name. $!\n"; + print FILE @buffer; + close(FILE); + @buffer = (); + } + elsif($line1 =~ /^\$ cd/){ # "cd" command line + $line1 =~ s/\$ //g; + chomp $line1; + print "[Tesh/INFO] exec_line : $line1\n"; + $line1 =~ s/cd //g; + chdir("$line1") or die "[Tesh/CRITICAL] Unable to open $line1. $!\n"; + } + elsif($line1 =~ /^\$ /){ #command line + if($line1 =~ /^\$ .\/tesh/){ # tesh command line + $tesh_command = 1; + @buffer = @buffer_tesh; + @buffer_tesh=(); + } $line1 =~ s/\${EXEEXT:=}//g; $line1 =~ s/^\$\ *//g; $line1 =~ s/^.\/lua/lua/g; $line1 =~ s/^.\/ruby/ruby/g; $line1 =~ s/^.\///g; + $line1 =~ s/^tesh/.\/tesh/g; $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g; chomp $line1; + $line1 = "$line1 $config"; + if(@list1){ - print "[Tesh/CRITICAL] Old result : @list1"; - print "[Tesh/CRITICAL] Previous result not check!"; - die;} - if($parallel == 1) - { - $execline = "$execline \& $line1 2>&1"; - print "[Tesh/INFO] exec_line // : $execline\n"; + print color("red"); + print "[Tesh/CRITICAL] -\n"; + print "[Tesh/CRITICAL] + @list1"; + print color("reset"), "\n"; + die;} + if(@list_of_commands){ # need parallel execution + push @list_of_commands, $line1; + print "[Tesh/INFO] exec_line : $line1\n"; } - else - { - $ok = 1; - $execline = "$line1 2>&1"; - print "[Tesh/INFO] exec_line : $execline\n"; - $result=`$execline`; - @list1 = split(/\n/,$result); + else{ + print "[Tesh/INFO] exec_line : $line1\n"; + if($tesh_command) + { $execline = $command_tesh; + $tesh_command=0;} + else + { $execline = $line1;} + $pid = open3(\*IN, \*OUT, \*OUT, $execline ); + if( $timeout){ + $forked = fork();die "fork() failed: $!" unless defined $forked; + if ( $forked == 0 ) + { + sleep $timeout; + kill(9, $pid); + exit; + } + } + + while(@buffer) + { + $line1 = shift (@buffer); + print IN $line1; + } + close IN ; + + waitpid( $pid, 0 ); + if($timeout){kill(9, $forked);$timeout=0;} + $timeout = 0; + + while(defined($linebis=)) + { + $linebis =~ s/\r//g; + $linebis =~ s/^( )*//g; + chomp $linebis; + push @list1,"$linebis"; + } + close OUT; + $command_executed = 1; } } elsif($line1 =~ /^\& /){ # parallel command line - $line1 =~ s/\$\{srcdir\:\=\.\}/./g; + $command_executed = 0; + $expected_result_line = 0; $line1 =~ s/\${EXEEXT:=}//g; $line1 =~ s/^\& //g; $line1 =~ s/^.\/lua/lua/g; @@ -107,32 +237,21 @@ while(defined($line1=)) $line1 =~ s/^.\///g; $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g; chomp $line1; - if(@list1){ - print "Old result : @list1"; - die "Previous result not check!";} - if($parallel == 1) - { - $execline = "$execline \& $line1 2>&1"; - print "[Tesh/INFO] exec_line // : $execline\n"; - } - else - { - $parallel = 1; - $execline = "$line1 2>&1"; - print "[Tesh/INFO] exec_line // : $execline\n"; - } + $line1 = "$line1 $config"; + $execline = "$line1"; + print "[Tesh/INFO] exec_line : $execline\n"; + push @list_of_commands, $execline; } elsif($line1 =~ /^\>/){ #expected result line - if($ok == 0 and $parallel== 0){die "No command line\n";} - $ok1 = 1; - $line1 =~ s/^\> //g; + $line1 =~ s/^\>( )*//g; $line1 =~ s/\r//g; chomp $line1; push @list2, $line1; + $expected_result_line = 1; } elsif($line1 =~ /^\)) } else { - if($encore == 1) - { - push @buffer, "$old_buffer$line1"; - $old_buffer = (); - $encore = 0; - } - else - { - push @buffer, "$line1\n"; - $old_buffer = (); - $encore = 0; - } + if($encore == 1){push @buffer, "$old_buffer$line1";} + else{push @buffer, "$line1\n";} + $old_buffer = (); + $encore = 0; } } elsif($line1 =~ /^p/){ #comment @@ -164,11 +275,22 @@ while(defined($line1=)) print "[Tesh/INFO] comment_line :$line1\n"; } elsif($line1 =~ /^! output sort/){ #output sort - print "[Tesh/INFO] output sort\n"; $sort=1; } - elsif($line1 =~ /^! expect return/){ #expect sort - print "[Tesh/CRITICAL] expect return\n"; + elsif($line1 =~ /^! output ignore/){ #output ignore + $no_output_ignore=0; + } + elsif($line1 =~ /^! expect signal SIGABRT$/) #expect signal SIGABRT + { + $SIGABRT=1; + } + elsif($line1 =~ /^! expect return/){ #expect return + $line1 =~ s/^! expect return //g; + $line1 =~ s/\r//g; + chomp $line1; + $return = $line1; + print color("red"), "[Tesh/INFO] expect return $return"; + print color("reset"), "\n"; die; } elsif($line1 =~ /^! setenv/){ #setenv @@ -180,17 +302,62 @@ while(defined($line1=)) print "[Tesh/INFO] setenv: $1=$2\n"; } elsif($line1 =~ /^! include/){ #output sort - die "[Tesh/CRITICAL] need include\n"; + print color("red"), "[Tesh/CRITICAL] need include"; + print color("reset"), "\n"; + die; } elsif($line1 =~ /^! timeout/){ #timeout $line1 =~ s/^! timeout //g; $line1 =~ s/\r//g; chomp $line1; + if($timeout != $line1){ $timeout = $line1; - print "[Tesh/INFO] timeout : $timeout\n"; + print "[Tesh/INFO] timeout : $timeout\n";} + } + elsif($line1 =~ /^! need execute/){ #need execute // commands + $execline = (); + $sort = 1; # need sort output + while(@list_of_commands) + { + $command = shift (@list_of_commands); + if($execline){$execline = "$command & $execline";} + else{$execline = "$command";} + } + $pid = open3(\*IN, \*OUT, \*OUT, $execline); + if( $timeout){ + $forked = fork();die "fork() failed: $!" unless defined $forked; + if ( $forked == 0 ) + { + sleep $timeout; + kill(9, $pid); + exit; + } + } + + while(@buffer) + { + $line1 = shift (@buffer); + print IN $line1; + } + close IN ; + waitpid( $pid, 0 ); + if($timeout){kill(9, $forked);$timeout=0;} + $timeout = 0; + + @list1=(); + while(defined($linebis=)) + { + $linebis =~ s/\r//g; + $linebis =~ s/^( )*//g; + chomp $linebis; + push @list1,"$linebis"; + } + close OUT; + $command_executed = 1; } - elsif($ok == 1 and $ok1 == 1) + elsif($command_executed and $expected_result_line) { + if($no_output_ignore){ @buffer = (); if($sort == 1) { @@ -206,48 +373,96 @@ while(defined($line1=)) $sort=0; } + if($SIGABRT) + { + push @list2,"Aborted"; + $SIGABRT = 0; + } + while(@list1 or @list2) { - $line1 = shift (@list1); - $line2 = shift (@list2); - if($line2 and $line1) + if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";} + if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";} + if($command_executed and $expected_result_line) { + if($line1 eq $line2){ - if($verbose == 1){print "$line1\n";} - else{push @buffer, "$line1\n";} + if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");} + else{push @buffer, "[Tesh/CRITICAL] $line1\n";} } else - { if($verbose == 0){print @buffer}; - if($line2) {print "- $line2\n"}; - if($line1) {print "+ $line1\n"}; + { if($verbose == 0){print color("green"),@buffer,color("reset");} + if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";} + if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";} die; } } else - { if($verbose == 0){print @buffer}; - if($line2) {print "- $line2\n"}; - if($line1) {print "+ $line1\n"}; + { if($verbose == 0){print color("green"),@buffer,color("reset");} + if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";} + if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";} die; } } - $ok = 0; - $ok1= 0; + }else{$no_output_ignore = 1;} + $command_executed = 0; + $expected_result_line = 0; @list1=(); @list2=(); @buffer = (); - $result = (); + $tesh_command=0; + @buffer_tesh=(); } -} -if($parallel == 1) -{ - $ok = 1; - $result=`$execline`; - @list1 = split(/\n/,$result); } -elsif($ok == 1 and $ok1 == 1) + +if(@list_of_commands){ # need parallel execution + $execline = (); + $sort = 1; # need sort output + while(@list_of_commands) + { + $command = shift (@list_of_commands); + if($execline){$execline = "$command & $execline";} + else{$execline = "$command";} + } + print "[Tesh/INFO] exec_line : $execline\n"; + $pid = open3(\*IN, \*OUT, \*OUT,"$execline"); + + if( $timeout){ + $forked = fork();die "fork() failed: $!" unless defined $forked; + if ( $forked == 0 ) { + sleep $timeout; + kill(9, $pid); + exit; + } + } + + while(@buffer) + { + $line1 = shift (@buffer); + print IN $line1; + } + close IN ; + waitpid( $pid, 0 ); + if($timeout){kill(9, $forked);$timeout=0;} + $timeout = 0; + + @list1=(); + while(defined($linebis=)) + { + $linebis =~ s/\r//g; + $linebis =~ s/^( )*//g; + chomp $linebis; + push @list1,"$linebis"; + } + close OUT; + $command_executed = 1; +} + +if($command_executed and $expected_result_line ){ + if($no_output_ignore){ @buffer = (); if($sort == 1) { @@ -263,34 +478,41 @@ elsif($ok == 1 and $ok1 == 1) $sort=0; } + if($SIGABRT) + { + push @list2,"Aborted"; + $SIGABRT = 0; + } + while(@list1 or @list2) { - $line1 = shift (@list1); - $line2 = shift (@list2); - if($line2 and $line1) + if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";} + if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";} + if($command_executed and $expected_result_line) { if($line1 eq $line2){ - if($verbose == 1){print "$line1\n";} - else{push @buffer, "$line1\n";} + if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");} + else{push @buffer, "[Tesh/CRITICAL] $line1\n";} } else - { if($verbose == 0){print @buffer}; - if($line2) {print "- $line2\n"}; - if($line1) {print "+ $line1\n"}; + { if($verbose == 0){print color("green"),@buffer,color("reset");} + if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";} + if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";} die; } } else - { if($verbose == 0){print @buffer}; - if($line2) {print "- $line2\n"}; - if($line1) {print "+ $line1\n"}; + { if($verbose == 0){print color("green"),@buffer,color("reset");} + if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2",color("reset"),"\n";} + if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1",color("reset"),"\n";} die; } } - $ok = 0; - $ok1= 0; + }else{$no_output_ignore = 1;} + $command_executed = 0; + $expected_result_line= 0; @list1=(); @list2=(); @buffer = (); -} \ No newline at end of file +}