Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
It is not Experimental test but nightly.
[simgrid.git] / buildtools / Cmake / tesh.pl
1 #! /usr/bin/perl -w
2
3 use strict;
4 use Term::ANSIColor;
5 use IPC::Open3;
6
7 if($#ARGV < 0)
8 {
9         die "Usage: tesh.pl <options> <teshfile.tesh>\n";
10 }
11
12 my($line1);
13 my($line2);
14 my($execline);
15 my($command);
16 my($command_tesh);
17 my($command_executed)=0;
18 my($expected_result_line)=0;
19 my($sort)=0;
20 my($nb_arg)=0;
21 my(@list1)=();
22 my(@list2)=();
23 my(@list3)=();
24 my(@list_of_commands)=();
25 my(@buffer)=();
26 my($timeout)=0;
27 my($encore)=0;
28 my($old_buffer);
29 my($linebis);
30 my($SIGABRT)=0;
31 my($no_output_ignore)=1;
32 my($verbose)=0;
33 my($return)=-1;
34 my($pid);
35 my($result);
36 my($result_err);
37 my($fich_name);
38 my($forked);
39
40 my($tesh_command)=0;
41 my(@buffer_tesh)=();
42
43 #options
44 do{
45         if($ARGV[$nb_arg] =~ /^--cd$/)
46         {
47                 $nb_arg++;
48                 if(!$ARGV[$nb_arg] or $ARGV[$nb_arg] =~ /^--/){die "Usage: tesh.pl --cd <directory>\n";}
49                 my($directory)=$ARGV[$nb_arg];
50                 if( -e $directory) 
51                 {
52                         chdir("$directory");
53                         print "[Tesh/INFO] Change directory to \"$directory\"\n";
54                 }
55                 else
56                 {
57                         die "[Tesh/CRITICAL] Directory not found : \"$directory\"\n";
58                 }
59                 $nb_arg++;      
60         }
61         elsif($ARGV[$nb_arg] =~ /^--setenv$/)
62         {
63                 $nb_arg++;
64                 if(!$ARGV[$nb_arg] or $ARGV[$nb_arg] =~ /^--/){die "Usage: tesh.pl --setenv environment_variable\n";}
65                 if(!$ARGV[$nb_arg+1] or $ARGV[$nb_arg+1] =~ /^--/){die "Usage: tesh.pl --setenv environment_variable\n";}
66                 $ENV{$ARGV[$nb_arg]} = "$ENV{$ARGV[$nb_arg]}:$ARGV[$nb_arg+1]";
67                 print "[Tesh/INFO] export $ARGV[$nb_arg]=\"$ENV{$ARGV[$nb_arg]}\"\n";
68                 $nb_arg++;
69                 $nb_arg++;
70         }
71         elsif($ARGV[$nb_arg] =~ /^--verbose$/)
72         {
73                 $verbose=1;$nb_arg++;
74         }
75         else
76         {
77                 print "[Tesh/CRITICAL] Unrecognized option : $ARGV[$nb_arg]\n";
78                 $nb_arg++;
79         }
80 }while(($nb_arg) < $#ARGV);
81
82 #Add current directory to path
83 $ENV{PATH} = "$ENV{PATH}:.";
84
85 #tesh file
86 if(!$ARGV[$nb_arg]){die "tesh.pl <options> <teshfile.tesh>\n";}
87 print "[Tesh/INFO] load file : $ARGV[$nb_arg]\n";
88 my($file)=$ARGV[$nb_arg];
89 open SH_LIGNE, $file or die "[Tesh/CRITICAL] Unable to open $file. $!\n";
90
91 while(defined($line1=<SH_LIGNE>))
92 {
93         if($line1 =~ /^\< \$ /){        # arg command line
94                 $line1 =~ s/\$\{srcdir\:\=\.\}/./g;
95                 $line1 =~ s/\${EXEEXT:=}//g;
96                 $line1 =~ s/^\< \$\ *//g;
97                 $line1 =~ s/^.\/lua/lua/g;
98                 $line1 =~ s/^.\/ruby/ruby/g;
99                 $line1 =~ s/^.\///g;
100                 $line1 =~ s/^tesh/.\/tesh/g;
101                 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
102                 chomp $line1;
103                 $command_tesh = $line1;
104                 print "[Tesh/INFO] arg_exec_line   : $command_tesh\n";
105         }
106         elsif($line1 =~ /^\< \< /){  # arg buffer line
107                 $line1 =~ s/^\< \<\ *//g;
108                 chomp $line1;
109                 print "[Tesh/INFO] arg_buffer_line : $line1\n";
110                 push @buffer_tesh, "$line1\n";
111         }
112         elsif($line1 =~ /^\< \> /){  # arg output line
113                 $line1 =~ s/^\< \>\ *//g;
114                 $line1 =~ s/\r//g;
115                 chomp $line1;
116                 push @list2, $line1;
117                 print "[Tesh/INFO] arg_output_line : $line1\n";
118                 $expected_result_line = 1;
119         }
120         elsif($line1 =~ /^\$ mkfile/){          # "mkfile" command line
121                 $line1 =~ s/\$ //g;
122                 $line1 =~ s/mkfile//g;
123                 chomp $line1;
124                 $fich_name = $line1;
125                 $line1 =();
126                 print "[Tesh/INFO] exec_line : mkfile $fich_name\n";
127                 `rm -f $fich_name`;
128                 open(FILE,">$fich_name") or die "[Tesh/CRITICAL] Unable to make file : $fich_name. $!\n";
129                 print FILE @buffer;
130                 close(FILE);
131                 @buffer = ();   
132         }
133         elsif($line1 =~ /^\$ cd/){      # "cd" command line
134                 $line1 =~ s/\$ //g;
135                 chomp $line1;
136                 print "[Tesh/INFO] exec_line : $line1\n";
137                 $line1 =~ s/cd //g;
138                 chdir("$line1") or die "[Tesh/CRITICAL] Unable to open $line1. $!\n";   
139         }
140         elsif($line1 =~ /^\$ /){        #command line
141                 if($line1 =~ /^\$ .\/tesh/){    # tesh command line
142                         $tesh_command = 1;
143                         @buffer = @buffer_tesh;
144                         @buffer_tesh=();
145                 }
146                 $line1 =~ s/\$\{srcdir\:\=\.\}/./g;
147                 $line1 =~ s/\${EXEEXT:=}//g;
148                 $line1 =~ s/^\$\ *//g;
149                 $line1 =~ s/^.\/lua/lua/g;
150                 $line1 =~ s/^.\/ruby/ruby/g;
151                 $line1 =~ s/^.\///g;
152                 $line1 =~ s/^tesh/.\/tesh/g;
153                 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
154                 chomp $line1;
155                 if(@list1){
156                         print color("red");
157                         print "[Tesh/CRITICAL] -\n";
158                         print "[Tesh/CRITICAL] + @list1\n";
159                         print color("reset");
160                         die;}           
161                 if(@list_of_commands){ # need parallel execution
162                         push @list_of_commands, $line1;
163                         print "[Tesh/INFO] exec_line : $line1\n";
164                 }
165                 else{
166                         print "[Tesh/INFO] exec_line : $line1\n";
167                         if($tesh_command)
168                         {       $execline = $command_tesh;
169                                 $tesh_command=0;}
170                         else
171                         {       $execline = $line1;}
172                         $pid = open3(\*IN, \*OUT, \*OUT, $execline );
173                         if( $timeout){
174                                 $forked = fork();die "fork() failed: $!" unless defined $forked;
175                                 if ( $forked == 0 )
176                                 {
177                                 sleep $timeout;
178                                 kill(9, $pid);
179                                 exit;
180                                 }
181                         }
182                         
183                         while(@buffer)
184                         {
185                                 $line1 = shift (@buffer);
186                                 print IN $line1;
187                         }
188                         close IN ;
189                         
190                         waitpid( $pid, 0 );
191                         if($timeout){kill(9, $forked);$timeout=0;}
192                         $timeout = 0;
193                         
194                         while(defined($linebis=<OUT>))
195                         {
196                                 $linebis =~ s/\r//g;
197                                 $linebis =~ s/^( )*//g;
198                                 chomp $linebis;
199                                 push @list1,"$linebis";
200                         }       
201                         close OUT;
202                         $command_executed = 1;
203                 }
204         }
205         elsif($line1 =~ /^\& /){        # parallel command line
206                 $command_executed = 0;
207                 $expected_result_line = 0;
208                 $line1 =~ s/\$\{srcdir\:\=\.\}/./g;
209                 $line1 =~ s/\${EXEEXT:=}//g;
210                 $line1 =~ s/^\& //g;
211                 $line1 =~ s/^.\/lua/lua/g;
212                 $line1 =~ s/^.\/ruby/ruby/g;
213                 $line1 =~ s/^.\///g;
214                 $line1 =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
215                 chomp $line1;
216                 $execline = "$line1";
217                 print "[Tesh/INFO] exec_line : $execline\n";
218                 push @list_of_commands, $execline;      
219         }       
220         elsif($line1 =~ /^\>/){ #expected result line
221                 $line1 =~ s/^\>( )*//g;
222                 $line1 =~ s/\r//g;
223                 chomp $line1;
224                 push @list2, $line1;
225                 $expected_result_line = 1;
226         }
227         elsif($line1 =~ /^\</ or $encore==1){   #need to buffer
228                 $line1 =~ s/^\<( )*//g; #delete < with space or tab after
229                 $line1 =~ s/\r//g;
230                 chomp $line1;
231                 if($line1 =~ /\\$/) # need to store this line into old_buff
232                 {
233                         $encore=1;
234                         $line1 =~ s/\\$//g;
235                         $old_buffer = "$old_buffer$line1";
236                 }
237                 else
238                 {
239                         if($encore == 1){push @buffer, "$old_buffer$line1";}
240                         else{push @buffer, "$line1\n";}
241                         $old_buffer = ();
242                         $encore = 0;    
243                 }
244         }
245         elsif($line1 =~ /^p/){  #comment
246                 $line1 =~ s/^p //g;
247                 $line1 =~ s/\r//g;
248                 chomp $line1;
249                 print "[Tesh/INFO] comment_line :$line1\n";
250         }
251         elsif($line1 =~ /^! output sort/){      #output sort
252                 $sort=1;
253         }
254         elsif($line1 =~ /^! output ignore/){    #output ignore
255                 $no_output_ignore=0;
256         }
257         elsif($line1 =~ /^! expect signal SIGABRT$/) #expect signal SIGABRT
258         {
259                 $SIGABRT=1;
260         }
261         elsif($line1 =~ /^! expect return/){    #expect return
262                 $line1 =~ s/^! expect return //g;
263                 $line1 =~ s/\r//g;
264                 chomp $line1;
265                 $return = $line1;
266                 print color("red"), "[Tesh/INFO] expect return $return\n";
267                 die;
268         }
269         elsif($line1 =~ /^! setenv/){   #setenv
270                 $line1 =~ s/^! setenv //g;
271                 $line1 =~ s/\r//g;
272                 chomp $line1;
273                 $line1 =~ /^(.*)=(.*)$/;
274                 $ENV{$1} = $2;
275                 print "[Tesh/INFO] setenv: $1=$2\n";
276         }
277         elsif($line1 =~ /^! include/){  #output sort
278                 color("red");die "[Tesh/CRITICAL] need include\n";
279         }
280         elsif($line1 =~ /^! timeout/){  #timeout
281                 $line1 =~ s/^! timeout //g;
282                 $line1 =~ s/\r//g;
283                 chomp $line1;
284                 if($timeout != $line1){
285                 $timeout = $line1;
286                 print "[Tesh/INFO] timeout   : $timeout\n";}
287         }
288         elsif($line1 =~ /^! need execute/){     #need execute // commands
289                 $execline = ();
290                 $sort = 1; # need sort output
291                 while(@list_of_commands)
292                 {
293                         $command = shift (@list_of_commands);
294                         if($execline){$execline = "$command & $execline";}
295                         else{$execline = "$command";}
296                 }
297                 $pid = open3(\*IN, \*OUT, \*OUT, $execline);
298                 if( $timeout){
299                         $forked = fork();die "fork() failed: $!" unless defined $forked;
300                         if ( $forked == 0 )
301                         {
302                         sleep $timeout;
303                         kill(9, $pid);
304                         exit;
305                         }
306                 }
307                 
308                 while(@buffer)
309                 {
310                         $line1 = shift (@buffer);
311                         print IN $line1;
312                 }
313                 close IN ;
314                 waitpid( $pid, 0 );
315                 if($timeout){kill(9, $forked);$timeout=0;}
316                 $timeout = 0;
317
318                 @list1=();
319                 while(defined($linebis=<OUT>))
320                 {
321                         $linebis =~ s/\r//g;
322                         $linebis =~ s/^( )*//g;
323                         chomp $linebis;
324                         push @list1,"$linebis";
325                 }       
326                 close OUT;
327                 $command_executed = 1;
328         }
329         elsif($command_executed and $expected_result_line)
330         {
331                 if($no_output_ignore){
332                 @buffer = ();
333                 if($sort == 1)
334                 {
335                         @list3 = sort @list1;
336                         @list1=();
337                         @list1=@list3;
338                         @list3=();
339                         
340                         @list3 = sort @list2;
341                         @list2=();
342                         @list2=@list3;
343                         @list3=();
344                         
345                         $sort=0;
346                 }
347                 if($SIGABRT)
348                 {
349                         push @list2,"Aborted";
350                         $SIGABRT = 0;
351                 }
352                                 
353                 while(@list1 or @list2)
354                 {
355                         if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";}
356                         if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";}
357                         if($command_executed and $expected_result_line)
358                         {
359                                 
360                                 if($line1 eq $line2){
361                                         if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");}
362                                         else{push @buffer, "[Tesh/CRITICAL]   $line1\n";}
363                                         
364                                 }
365                                 else
366                                 {       if($verbose == 0){print color("green"),@buffer,color("reset");}
367                                         if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2\n",color("reset");}
368                                         if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1\n",color("reset");}
369                                         die;
370                                 }
371                         }
372                         else
373                         {       if($verbose == 0){print color("green"),@buffer,color("reset");}
374                                 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2\n",color("reset");}
375                                 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1\n",color("reset");}
376                                 die;
377                         }
378                 }
379                 }else{$no_output_ignore = 1;}
380                 $command_executed = 0;
381                 $expected_result_line = 0;
382                 @list1=();
383                 @list2=();
384                 @buffer = ();
385                 $tesh_command=0;
386                 @buffer_tesh=();
387         }
388
389 }
390
391 if(@list_of_commands){ # need parallel execution
392         $execline = ();
393         $sort = 1; # need sort output
394         while(@list_of_commands)
395         {
396                 $command = shift (@list_of_commands);
397                 if($execline){$execline = "$command & $execline";}
398                 else{$execline = "$command";}
399         }
400         print "[Tesh/INFO] exec_line : $execline\n";
401         $pid = open3(\*IN, \*OUT, \*OUT,"$execline");
402
403         if( $timeout){
404                 $forked = fork();die "fork() failed: $!" unless defined $forked;
405                 if ( $forked == 0 )
406                 {
407                 sleep $timeout;
408                 kill(9, $pid);
409                 exit;
410                 }
411         }
412         
413         while(@buffer)
414         {
415                 $line1 = shift (@buffer);
416                 print IN $line1;
417         }
418         close IN ;
419         waitpid( $pid, 0 );
420         if($timeout){kill(9, $forked);$timeout=0;}
421         $timeout = 0;
422
423         @list1=();
424         while(defined($linebis=<OUT>))
425         {
426                 $linebis =~ s/\r//g;
427                 $linebis =~ s/^( )*//g;
428                 chomp $linebis;
429                 push @list1,"$linebis";
430         }       
431         close OUT;
432         $command_executed = 1;
433 }
434
435 if($command_executed and $expected_result_line ){
436                         if($no_output_ignore){
437                         @buffer = ();
438                         if($sort == 1)
439                         {
440                                 @list3 = sort @list1;
441                                 @list1=();
442                                 @list1=@list3;
443                                 @list3=();
444                                 
445                                 @list3 = sort @list2;
446                                 @list2=();
447                                 @list2=@list3;
448                                 @list3=();
449                                 
450                                 $sort=0;
451                         }
452                         if($SIGABRT)
453                         {
454                                 push @list2,"Aborted";
455                                 $SIGABRT = 0;
456                         }
457                         
458                         while(@list1 or @list2)
459                         {
460                                 if(@list1){$line1 = shift (@list1);$expected_result_line = "x$line1";}
461                                 if(@list2){$line2 = shift (@list2);$command_executed = "x$line2";}
462                                 if($command_executed and $expected_result_line)
463                                 {
464                                         if($line1 eq $line2){
465                                                 if($verbose == 1){print color("green"),"[Tesh/VERB] $line1\n",color("reset");}
466                                                 else{push @buffer, "[Tesh/CRITICAL]   $line1\n";}
467                                                 
468                                         }
469                                         else
470                                         {       if($verbose == 0){print color("green"),@buffer,color("reset");}
471                                                 if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2\n",color("reset");}
472                                                 if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1\n",color("reset");}
473                                                 die;
474                                         }
475                                 }
476                                 else
477                                 {       if($verbose == 0){print color("green"),@buffer,color("reset");}
478                                         if($line2) {print color("red"), "[Tesh/CRITICAL] - $line2\n",color("reset");}
479                                         if($line1) {print color("red"), "[Tesh/CRITICAL] + $line1\n",color("reset");}
480                                         die;
481                                 }
482                         }
483                         }else{$no_output_ignore = 1;}
484                         $command_executed = 0;
485                         $expected_result_line= 0;
486                         @list1=();
487                         @list2=();
488                         @buffer = ();
489 }