Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
have perl comply a little bit more to what existed before
[simgrid.git] / buildtools / Cmake / Scripts / tesh.pl
index a5b53c4..db079a4 100755 (executable)
@@ -13,9 +13,11 @@ tesh -- testing shell
 B<tesh> [I<options>] I<tesh_file>
 
 =cut
-my($bindir);
-my($srcdir);
+my($bindir)=".";
+my($srcdir)=".";
+my($timeout)=0;
 my $path = $0;
+my $OS;
 $path =~ s|[^/]*$||;
 push @INC,$path;
 
@@ -24,22 +26,28 @@ use strict;
 use Term::ANSIColor;
 use IPC::Open3;
 
-my($OS)=`echo %OS%`;
-if($OS eq "%OS%"){
+if($^O eq "linux"){
        $OS = "UNIX";
 }
 else{
        $OS = "WIN";
 }
 
-print "OS: ".$OS."\n";
+
+sub trim($)
+{
+       my $string = shift;
+       $string =~ s/^\s+//;
+       $string =~ s/\s+$//;
+       return $string;
+}
 
 # make sure we received a tesh file
 scalar @ARGV > 0 || die "Usage:\n    tesh [*options*] *tesh_file*\n";
 
 #Add current directory to path
 $ENV{PATH} = "$ENV{PATH}:.";
-
+my $tesh_file;
 
 ##
 ## Command line option handling
@@ -48,19 +56,35 @@ $ENV{PATH} = "$ENV{PATH}:.";
 # option handling helper subs
 sub cd_cmd {
     my $directory=$_[1];
+    my $failure=1;
     if (-e $directory && -d $directory) {
        chdir("$directory");
        print "[Tesh/INFO] change directory to $directory\n";
+    $failure=0;
     } elsif (-e $directory) {
-       die "[Tesh/CRITICAL] Cannot change directory to '$directory': it is not a directory\n";
+       print "Cannot change directory to '$directory': it is not a directory\n";
     } else {
-       die "[Tesh/CRITICAL] Cannot change directory to '$directory': no such directory\n";
+       print "Chdir to $directory failed: No such file or directory\n";
+    }
+    if($failure==1){
+    print "Test suite `$tesh_file': NOK (system error)\n";
+    exit 4;
     }
 }
 
+sub timeout_cmd{
+    $timeout=$_[1];
+}
+
 sub setenv_cmd {
-    if ($_[1] =~ /^(.*)=(.*)$/) {
-       my($var,$ctn)=($1,$2);
+    my($var,$ctn);
+    if ($_[0] =~ /^(.*)=(.*)$/) {
+        ($var,$ctn)=($1,$2);
+    }elsif ($_[1] =~ /^(.*)=(.*)$/) {
+        ($var,$ctn)=($1,$2);
+    } else { 
+           die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n";
+    }
        
        if($var =~ /bindir/){
                print "[Tesh/INFO] setenv $var=$ctn\n";
@@ -76,13 +100,10 @@ sub setenv_cmd {
                        print "[Tesh/INFO] setenv $var=$ctn\n";
                }
        }       
-       } else { 
-       die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n";
-    }
 }
 
 # Main option parsing sub
-my $tesh_file;
+
 sub get_options {
     # remove the tesh file from the ARGV used
     my @ARGV = @_;
@@ -92,6 +113,7 @@ sub get_options {
     my @verbose = ();
     my @cfg;
     my $log; # ignored
+    my $enable_coverage;
 
     my %opt = (
        "help"    => 0,
@@ -108,11 +130,22 @@ sub get_options {
         'debug|d'    => \$opt{"debug"},
 
        'cd=s'       => \&cd_cmd,
+       'timeout=s'  => \&timeout_cmd,  
        'setenv=s'   => \&setenv_cmd,
        'cfg=s'      => \@cfg,
        'log=s'      => \$log,
+    'enable-coverage+'  => \$enable_coverage,  
        );
 
+    if($enable_coverage){
+        print "Enable coverage\n";
+    }
+
+    unless($tesh_file=~/\.tesh/){
+        $tesh_file="(stdin)";
+        print "Test suite from stdin\n";
+    }
+
     $opt{'verbose'} = scalar @verbose;
     foreach (@cfg) {
        $opt{'cfg'} .= " --cfg=$_";
@@ -127,7 +160,6 @@ my %opts = get_options(@ARGV);
 ##
 my($sort)=0;
 my($nb_arg)=0;
-my($timeout)=0;
 my($old_buffer);
 my($linebis);
 my($SIGABRT)=0;
@@ -199,7 +231,11 @@ sub exec_cmd {
     ###
     # exec the command line
     ###
-    $pid = open3(\*IN, \*OUT, \*OUT, $cmd{'cmd'} );
+    $pid = open3(\*CHILD_IN, \*OUT, \*OUT, $cmd{'cmd'} );
+
+    # push all provided input to executing child
+    map { print CHILD_IN "$_\n" }  @{$cmd{'in'}};
+    close CHILD_IN;
 
     # if timeout specified, fork and kill executing child at the end of timeout
     if ($timeout){
@@ -212,20 +248,30 @@ sub exec_cmd {
        }
     }
 
-    # push all provided input to executing child
-    map { print IN "$_\n" } $cmd{'in'};
-    close IN;
 
     # pop all output from executing child
     my @got;
     while(defined(my $got=<OUT>)) {
        $got =~ s/\r//g;
-       #$got =~ s/^( )*//g;
+       $got =~ s/^( )*//g;
        chomp $got;
-       push @got, "$got";
+    $got=trim($got);
+       if( $got ne ""){
+        push @got, "$got";
+    }
     }  
     close OUT;
-    
+   
+    if ($sort){   
+      sub mysort{
+        $a cmp $b
+        }
+      use sort qw(defaults _quicksort); # force quicksort
+      @got = sort mysort @got;
+      #also resort the other one, as perl sort is not the same as the C one used to generate teshes
+      @{$cmd{'out'}}=sort mysort @{$cmd{'out'}};
+    }
+  
     # Cleanup the executing child, and kill the timeouter brother on need
     $cmd{'return'} = 0 unless defined($cmd{'return'});
     my $wantret = "returned code ".(defined($cmd{'return'})? $cmd{'return'} : 0);
@@ -267,13 +313,16 @@ sub mkfile_cmd {
 }
 
 # parse tesh file
-print "Test suite $tesh_file\n";
-open TESH_FILE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file $!\n";
-
+#my $teshfile=$tesh_file;
+#$teshfile=~ s{\.[^.]+$}{};
+#print "Test suite `$teshfile'\n";
+unless($tesh_file eq "(stdin)"){
+    open TESH_FILE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file $!\n";
+}
 
 my %cmd; # everything about the next command to run
 my $line_num=0;
-LINE: while (defined(my $line=<TESH_FILE>)) {
+LINE: while (defined(my $line=<TESH_FILE>) or defined(my $line=<>)) {
     $line_num++;
     chomp $line;
     print "[TESH/debug] $line_num: $line\n" if $opts{'debug'};
@@ -304,7 +353,10 @@ LINE: while (defined(my $line=<TESH_FILE>)) {
     if ($cmd =~ /^#/) {        #comment
     } elsif ($cmd eq '> '){    #expected result line
        print "[TESH/debug] push expected result\n" if $opts{'debug'};
-       push @{$cmd{'out'}}, $arg;
+    $arg=trim($arg);
+       if($arg ne ""){
+        push @{$cmd{'out'}}, $arg;
+    }
 
     } elsif ($cmd eq '< ') {   # provided input
        print "[TESH/debug] push provided input\n" if $opts{'debug'};
@@ -346,6 +398,7 @@ LINE: while (defined(my $line=<TESH_FILE>)) {
        $cmd{'cmd'} = $arg;
     }  
     elsif($line =~ /^! output sort/){  #output sort
+    $sort=1;
        $cmd{'sort'} = 1;
     }
     elsif($line =~ /^! output ignore/){        #output ignore
@@ -378,12 +431,18 @@ LINE: while (defined(my $line=<TESH_FILE>)) {
     }
 }
 
+
+
 # Deal with last command
 if (defined($cmd{'cmd'})) {
     exec_cmd(\%cmd);
     %cmd = ();
 }
 
+if($tesh_file eq "(stdin)"){
+        print "Test suite from stdin OK\n";
+}
+
 #my (@a,@b);
 #push @a,"bl1";   push @b,"bl1";
 #push @a,"bl2";   push @b,"bl2";
@@ -406,6 +465,8 @@ if (defined($cmd{'cmd'})) {
 #push @a,"AZE"; push @b,"EZA";
 #print "Different:\n".build_diff(\@a,\@b);
 
+use lib "@CMAKE_BINARY_DIR@/bin" ;
+
 use Diff qw(diff); # postpone a bit to have time to change INC
 
 sub build_diff {