1#!/usr/bin/perl
2
3#LTP results gathering script: ltp_check
4#       3/12/02 William Jay Huie (creation)
5#       3/28/02 William Jay Huie minor fixes, increased results parsing
6#       5/01/02 William Jay Huie parsing changes
7#       5/17/02 Casey Abell added sar results
8#This will log into the LTP_HOST machine, which may be different then the
9#machine used to run the ltp_master script
10#This script will check for *ltpoutput.tgz files created by the ltprun script
11#and download them each to their own directory and do a bit of processing
12#the results gathering probably needs to be extended but hopefully this is a good
13#first go at it
14
15use Net::FTP ();
16
17#CHANGEME:
18#For some reason doesn't work if you do ~/ltp/results, so you need to code the
19#explicit path for LTP_RES_DIR unless someone can tell me why
20$LTP_RES_DIR="/home/wjhuie/ltp/results";
21#CHANGEME:
22$LTP_HOST="ltp_host.somewhere.org";
23
24#This is who has the *ltpoutput.tgz files, where the results are uploaded
25#     not necessarially the user id that ran the test
26$LTP_USER="ltp";
27$LTP_PASS="ltp";
28$LTP_LOGFILE="ltp-logfile";
29$LTP_RUN_OUTPUT="ltprun.out";
30$LTP_RUNALL_OUT="runall.output";
31$RESULTS_OUT="results.out";
32$FAILS_OUT="failures.list";
33$SAR_OUTFILE="sar.data";
34
35@res_dirs;
36$count = 0;
37$RES = 0;
38$FAILS = 0;
39%hash;
40
41sub download_results()
42{
43   print "Attempting to download the LTP results\n";
44
45   $dir = system("ls $LTP_RES_DIR &> /dev/null") / 256;
46   if ($dir)
47   {
48     print "Making a results directory in $LTP_RES_DIR\n";
49     `mkdir -p $LTP_RES_DIR`;
50     chdir "$LTP_RES_DIR" or die "Can't change to $LTP_RES_DIR\n";
51   }
52   else
53   { chdir "$LTP_RES_DIR" or die "Can't change to $LTP_RES_DIR\n"; }
54
55   $ftp = Net::FTP->new($LTP_HOST, Debug => 0) or die "Can't connect to ftp: $LTP_HOST";
56   $ftp->login($LTP_USER, $LTP_PASS) or die "Unable to login";
57   $ftp->type('I') or die "Unable to set type to Binary";
58   @files = $ftp->ls("*ltpoutput.tgz");
59   $num_files = $#files + 1;
60   print "New results files found $num_files:\n";
61   for ($i = 0; $i < $num_files; $i++) { print "\t$files[$i]\n"; }
62
63   for ($i = 0; $i < $num_files; $i++)
64   {
65      print "Downloading: $files[$i]\t";
66      if ($ftp->get($files[$i]))
67      {
68         print "Successful\n";
69         $ftp->delete($files[$i]);
70      }
71      else
72      { print "FAILED\n"; }
73
74   }
75   $ftp->quit;
76
77   @res = `ls $LTP_RES_DIR/*.tgz 2> /dev/null`;
78
79   if (@res)
80   {
81      $num = $#res + 1;
82      print "             download of LTP results finished\n";
83      print "$num unprocessed results files found\n";
84      chomp(@res);
85      return 1;
86   }
87   else
88   {  print "             no apparent results to process\n"; return 0; }
89
90}
91
92sub untar_results()
93{
94   for ($i = 0; $i < $num; $i++)
95   {
96      if ( $res[$i] =~ m/\s*(\w+)-((\w+)-)*ltpoutput.tgz/ )
97      {
98         $hostname = $1;
99         $epoch_time = $3;
100         $english_time = localtime($epoch_time);
101         $dir = "$LTP_RES_DIR/$hostname/$english_time";
102
103         if ($english_time)
104         {
105            $new_dir = $dir;
106            $new_dir =~ s/ /_/g;
107            print "New results: $hostname @ $english_time\n";
108            `mkdir -p '$new_dir'`;
109            chdir "$new_dir" or die "Can't change to $new_dir\n";
110            `tar -zxf $res[$i]`;
111            `mv $res[$i] $new_dir`;
112            $res_dirs[$count] = $new_dir; $count++;
113         }
114         else
115         {
116            print "No timestamp on results file, skipping for now\n";
117#Should come up with a soultion for this, check/create $hostname
118#     then some unique identifier but for now we'll complain and ignore
119         }
120      }
121   }
122   return 1;
123}
124
125sub gather_results()
126{
127   print "Gathering $count result(s):\n";
128
129   for ($i = 0; $i < $count; $i++)
130   {
131      print "\nResults for: $res_dirs[$i]\n";
132      chdir "$res_dirs[$i]" or die "Can't change to $res_dirs[$i]\n";
133
134      if ( !( -f $LTP_RUNALL_OUT && -f $LTP_LOGFILE ) )
135      {
136           print "$LTP_RUNALL_OUT or $LTP_LOGFILE seems to be missing\n";
137           print "     check the tarfile and perhaps $LTP_RUN_OUTPUT\n";
138           print "Skipping\n";
139           next;
140      }
141
142      chomp($stat = `tail -n 1 $LTP_RUNALL_OUT`);
143      print "\t\t$stat\n";
144
145      $num_success = `grep "stat=0" $LTP_LOGFILE | wc -l`;
146      if ( $num_success =~ /\s*(\d+)\s*/ ) { $num_success = $1; }
147
148      @fails = `grep "stat=" $LTP_LOGFILE | grep -v "stat=0"`;
149      $num_fail = $#fails + 1;
150
151      # gather the same fail cases together and have a counter for each different fail case.
152
153        foreach $each (@fails) {
154                if ($each =~ /(.)*tag=(\w+)\sstime=(.+)/){
155                        $case = $2;
156                        # print "$case\n";
157                        if (exists $hash{$case}) {
158                        #       print "$hash{$case} before\n";
159                                $counter = $hash{$case}+1;
160                                $hash{$case} = $counter;
161                        #       print "$hash{$case} later\n";
162
163                        }
164                        else {
165                                $hash{$case}=1;
166                        }
167                }
168        }
169
170      $pass_percent = sprintf("%.2f",
171                         ($num_success / ($num_success + $num_fail)) * 100);
172
173      $ltp_ver = `grep "version" $LTP_RUN_OUTPUT`;
174      if ( $ltp_ver =~ m/.*version: (.*)/ ) { $ltp_ver = $1; }
175
176      $line = "Pass $pass_percent % : $num_success succeeded : $num_fail failed";
177      print "$line\n";
178
179      $line1 = `sar -f $SAR_OUTFILE |tail -n 1`;
180      if ($line1 =~ /(.+)/) {
181        @sarstats1 = split(/\s+/, $line1);
182        print "Cpu user = $sarstats1[2]%\n";
183        print "Cpu nice = $sarstats1[3]%\n";
184        print "Cpu system = $sarstats1[4]%\n";
185
186        $line2 = `sar -r -f $SAR_OUTFILE |tail -n 1`;
187        @sarstats2 = split(/\s+/, $line2);
188        print "Memory used = $sarstats2[3]%\n";
189        print "Swap used = $sarstats2[9]%\n";
190
191        $line3 = `sar -c -f $SAR_OUTFILE |tail -n 1`;
192        @sarstats3 = split(/\s+/, $line3);
193        print "Processes created per second = $sarstats3[1]%\n";
194      }
195
196      if (open RES, ">$RESULTS_OUT")
197      {
198         print ". -> Results stored in $RESULTS_OUT\n";
199         if (!open FAILS, ">$FAILS_OUT") { print "Error opening $FAILS_OUT\n"; }
200         $num =
201#The <<<test_start>>> doesn't always get into the runalltest.sh output capture
202#because some output will appear before its corresponding block
203#So for now relying on last thing from ver_linux to know when to stop copying
204#          system("awk '/<<<test_start>>>/ { exit NR-1; }' $LTP_RUNALL_OUT") / 256;
205           system("awk '/bogomips/ { exit NR; }' $LTP_RUNALL_OUT") / 256;
206
207         @system_info = `head -n $num $LTP_RUNALL_OUT`;
208
209         if ($ltp_ver) { print RES "$ltp_ver : "; }
210         print RES "$line\n\n";
211         if ($line1 =~ /(.+)/) {
212           print RES "Cpu user = $sarstats1[2]%\n";
213           print RES "Cpu nice = $sarstats1[3]%\n";
214           print RES "Cpu system = $sarstats1[4]%\n";
215           print RES "Memory used = $sarstats2[3]%\n";
216           print RES "Swap used = $sarstats2[9]%\n";
217           print RES "processes created per second = $sarstats3[1]%\n\n";
218        }
219         print RES "@system_info\n";
220         print RES "$stat:\n";
221
222         #print out each failed case information.
223         foreach $case(keys %hash){
224                print RES "failed case=$case\tnumber of failures=$hash{$case}\n";
225         }
226#end of new ouput section
227
228         $runall = `cat $LTP_RUNALL_OUT`;
229
230	 # reset hash table values to 0
231	 foreach $case(keys %hash){
232		$hash{$case}=0;
233	 }
234
235         for ($j = 0; $j < $num_fail; $j++)
236         {
237            if ( $fails[$j] =~ m/^tag=(\w+?) / )
238            {
239               	$test_case = $1;
240		# each failure case will be printed out only once
241	       	if ((exists $hash{$test_case})&&( $hash{$test_case}==0 )) {
242			$hash{$test_case}=1;
243
244                        if (FAILS) { print FAILS "$test_case\n"; }
245               		print RES "\nTrying to find $test_case output";
246               		if ( $runall =~
247			#modified because some output is appearing before tagline
248                    		m/((^$test_case.*?)*<<<test_start>>>.tag=$test_case.*?<<<test_end>>>)/ms )
249               		{
250               		   	print RES "\n-------------------------\n";
251                 		print RES "$1";
252                 		print RES "\n-------------------------\n";
253               		}
254              		else
255               		{
256                  		print RES "\n-------------------------\n";
257                  		print RES "Unable to locate output for $test_case!";
258                  		print RES "\n-------------------------\n";
259               		}
260		}
261            }
262         }
263         close(RES); close(FAILS);
264      }
265      else
266      { print "Can't open $RESULTS_OUT, test failures are:\n @fails\n"; }
267   }
268   return 1;
269}
270
271if (!download_results)
272{ exit 0; }
273
274if (!untar_results)
275{ exit 0; }
276
277if (!gather_results)
278{ exit 0; }
279