1# -*- cperl -*- 2 3package My::Exec; 4 5use strict; 6use warnings; 7use Carp; 8use File::Basename; 9use IO::File; 10 11use base qw(Exporter); 12our @EXPORT= qw(exec_print_on_error); 13 14# Generate a logfile name from a command 15sub get_logfile_name { 16 my $cmd = shift; 17 18 # Get logfile name 19 my @cmd_parts = split(' ', $cmd); 20 my $logfile_base = fileparse($cmd_parts[0]); 21 my $logfile_name = ""; 22 my $log_dir = $ENV{MYSQLTEST_VARDIR}; 23 for my $i (1..100) 24 { 25 my $proposed_logfile_name = "$log_dir/$logfile_base" . '_' . $i . ".log"; 26 if (! -f $proposed_logfile_name) 27 { 28 # We can use this file name 29 $logfile_name = $proposed_logfile_name; 30 last; 31 } 32 } 33 34 return $logfile_name; 35} 36 37# Save a set of lines to a file 38sub save_file { 39 my $filename = shift; 40 my $lines = shift; 41 42 my $F = IO::File->new($filename, "w") or die "Can't write to '$filename': $!"; 43 foreach my $line (@$lines) { 44 print $F $line 45 } 46 $F->close(); 47} 48 49# 50# exec_print_on_error - executes command, and prints n last lines of output 51# from the command only if the command fails. If the command runs 52# successfully, no output is written. 53# 54# Parameters: 55# cmd - the command to run 56# max_lines - the maximum number of lines of output to show on error (default 200) 57# Returns: 58# 1 on success, 0 on error. 59# Example: 60# use My::Exec; 61# my $res = exec_print_on_error("./mtr --suite=ndb ndb_dd_varsize"); 62# 63sub exec_print_on_error { 64 my $cmd = shift; 65 my $max_lines = shift || 200; 66 67 my $logfile_name = get_logfile_name($cmd); 68 69 $cmd .= " 2>&1"; 70 my @output = `$cmd`; 71 print "Result of '$cmd': $?, logfile: '$logfile_name'\n"; 72 save_file($logfile_name, \@output); 73 if ($? == 0) 74 { 75 # Test program suceeded 76 return 1; 77 } 78 79 # Test program failed 80 if ($? == -1) 81 { 82 # Failed to execute program 83 print "Failed to execute '$cmd': $!\n"; 84 } 85 elsif ($?) 86 { 87 # Test program failed 88 my $sig = $? & 127; 89 my $return = $? >> 8; 90 print "Command that failed: '$cmd'\n"; 91 print "Test program killed by signal $sig\n" if $sig; 92 print "Test program failed with error $return\n" if $return; 93 94 # Show the last lines of the output 95 my $lines = scalar(@output); 96 $lines = $max_lines if $lines > $max_lines; 97 print "Last '$lines' lines of output from command:\n"; 98 foreach my $line (splice(@output, -$lines)) 99 { 100 print $line; 101 } 102 } 103 return 0; 104} 105