Francois Gouget : testbot/WineSendLog: Add proper command line handling and options.

Alexandre Julliard julliard at winehq.org
Tue Jun 26 09:45:37 CDT 2018


Module: tools
Branch: master
Commit: 3941605cb602151e668db028c6e41c784cfb4cc9
URL:    https://source.winehq.org/git/tools.git/?a=commit;h=3941605cb602151e668db028c6e41c784cfb4cc9

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Tue Jun 26 13:29:25 2018 +0200

testbot/WineSendLog: Add proper command line handling and options.

When run in --debug mode WineSendLog prints the emails it would normally
send instead of piping them to sendmail.
Also the script now prints the error messages to stderr by default to
make it easier to figure things out when running it on the command
line. The --log-only option can be used when that's not desired.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 testbot/bin/Engine.pl      |   2 +-
 testbot/bin/WineSendLog.pl | 193 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 164 insertions(+), 31 deletions(-)

diff --git a/testbot/bin/Engine.pl b/testbot/bin/Engine.pl
index ce35094..464b6db 100755
--- a/testbot/bin/Engine.pl
+++ b/testbot/bin/Engine.pl
@@ -320,7 +320,7 @@ sub HandleJobStatusChange($$$)
       CloseAllDBBackEnds();
       WineTestBot::Log::SetupRedirects();
 
-      exec("$BinDir/${ProjectName}SendLog.pl $JobKey") or
+      exec("$BinDir/${ProjectName}SendLog.pl --log-only $JobKey") or
       LogMsg "Unable to exec ${ProjectName}SendLog.pl: $!\n";
       exit(1);
     }
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index e03395a..ed3453b 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -36,14 +36,47 @@ sub BEGIN
     unshift @INC, "$::RootDir/lib";
   }
 }
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
 
 use Algorithm::Diff;
+
 use WineTestBot::Config;
 use WineTestBot::Jobs;
 use WineTestBot::Log;
 use WineTestBot::StepsTasks;
 
 
+#
+# Logging and error handling helpers
+#
+
+my $Debug;
+sub Debug(@)
+{
+  print STDERR @_ if ($Debug);
+}
+
+sub DebugTee($@)
+{
+  my ($File) = shift;
+  print $File @_;
+  Debug(@_);
+}
+
+my $LogOnly;
+sub Error(@)
+{
+  print STDERR "$Name0:error: ", @_ if (!$LogOnly);
+  LogMsg @_;
+}
+
+
+#
+# Log analysis
+#
+
 sub IsBotFailure($)
 {
   my ($ErrLine) = @_;
@@ -121,7 +154,7 @@ sub ReadLog($$$)
   }
   else
   {
-    LogMsg "Unable to open '$LogName' for reading: $!\n";
+    Error "Unable to open '$LogName' for reading: $!\n";
   }
 
   return \@Messages;
@@ -179,7 +212,19 @@ sub SendLog($)
   my $StepsTasks = CreateStepsTasks(undef, $Job);
   my @SortedKeys = sort @{$StepsTasks->GetKeys()};
 
-  open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+  #
+  # Send a job summary and all the logs as attachments to the developer
+  #
+
+  Debug("-------------------- Developer email --------------------\n");
+  if ($Debug)
+  {
+    open(SENDMAIL, ">>&=", 1);
+  }
+  else
+  {
+    open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+  }
   print SENDMAIL "From: $RobotEMail\n";
   print SENDMAIL "To: $To\n";
   my $Subject = "TestBot job " . $Job->Id . " results";
@@ -218,6 +263,7 @@ EOF
                     $TestFailures;
   }
 
+  # Print the job summary
   my @FailureKeys;
   foreach my $Key (@SortedKeys)
   {
@@ -322,6 +368,7 @@ EOF
     }
   }
 
+  # Print the log attachments
   foreach my $Key (@SortedKeys)
   {
     my $StepTask = $StepsTasks->GetItem($Key);
@@ -334,6 +381,7 @@ Content-Transfer-Encoding: 8bit
 EOF
     print SENDMAIL "Content-Disposition: attachment; filename=",
                    $StepTask->VM->Name, ".log\n\n";
+    print SENDMAIL "Not dumping logs in debug mode\n" if ($Debug);
 
     my $PrintSeparator = !1;
     my $TaskDir = $StepTask->GetTaskDir();
@@ -343,7 +391,7 @@ EOF
       while (defined($Line = <LOGFILE>))
       {
         $Line =~ s/\s*$//;
-        print SENDMAIL "$Line\n";
+        print SENDMAIL "$Line\n" if (!$Debug);
         $PrintSeparator = 1;
       }
       close LOGFILE;
@@ -356,11 +404,11 @@ EOF
       {
         if ($PrintSeparator)
         {
-          print SENDMAIL "\n";
+          print SENDMAIL "\n" if (!$Debug);
           $PrintSeparator = !1;
         }
         $Line =~ s/\s*$//;
-        print SENDMAIL "$Line\n";
+        print SENDMAIL "$Line\n" if (!$Debug);
       }
       close ERRFILE;
     }
@@ -369,10 +417,12 @@ EOF
   print SENDMAIL "--==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==--\n";
   close(SENDMAIL);
 
-  if (! defined($Job->Patch))
-  {
-    return;
-  }
+  # This is all for jobs submitted from the website
+  return if (!defined $Job->Patch);
+
+  #
+  # Build a job summary with only the new errors
+  #
 
   my $Messages = "";
   foreach my $Key (@FailureKeys)
@@ -401,7 +451,7 @@ EOF
       }
       else
       {
-        LogMsg "BotFailure found in ${LatestName}.err\n";
+        Error "BotFailure found in ${LatestName}.err\n";
       }
       if ($MessagesFromErr || $MessagesFromLog)
       {
@@ -411,15 +461,28 @@ EOF
     }
     elsif ($BotFailure)
     {
-      LogMsg "BotFailure found in $TaskDir/err\n";
+      Error "BotFailure found in $TaskDir/err\n";
     }
   }
 
+  #
+  # Send a summary of the new errors to the mailing list
+  #
+
+  Debug("\n-------------------- Mailing list email --------------------\n");
+
   my $WebSite = ($UseSSL ? "https://" : "http://") . $WebHostName;
 
   if ($Messages)
   {
-    open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+    if ($Debug)
+    {
+      open(SENDMAIL, ">>&=", 1);
+    }
+    else
+    {
+      open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+    }
     print SENDMAIL "From: $RobotEMail\n";
     print SENDMAIL "To: $To\n";
     print SENDMAIL "Cc: $WinePatchCc\n";
@@ -445,6 +508,14 @@ EOF
     print SENDMAIL $Messages;
     close SENDMAIL;
   }
+  else
+  {
+    Debug("Found no error to report to the mailing list\n");
+  }
+
+  #
+  # Create a .testbot file for the patches website
+  #
 
   my $Patch = $Job->Patch;
   if (defined $Patch->WebPatchId and -d "$DataDir/webpatches")
@@ -452,9 +523,12 @@ EOF
     my $BaseName = "$DataDir/webpatches/" . $Patch->WebPatchId;
     if (open (my $result, ">", "$BaseName.testbot"))
     {
-      print $result "Status: " . ($Messages ? "Failed" : "OK") . "\n";
-      print $result "Job-ID: " . $Job->Id . "\n";
-      print $result "URL: $WebSite/JobDetails.pl?Key=" . $Job->GetKey() . "\n";
+      Debug("\n-------------------- WebPatches report --------------------\n");
+      # Only take into account new errors to decide whether the job was
+      # successful or not.
+      DebugTee($result, "Status: ". ($Messages ? "Failed" : "OK") ."\n");
+      DebugTee($result, "Job-ID: ". $Job->Id ."\n");
+      DebugTee($result, "URL: $WebSite/JobDetails.pl?Key=". $Job->GetKey() ."\n");
 
       foreach my $Key (@SortedKeys)
       {
@@ -496,7 +570,7 @@ EOF
     }
     else
     {
-      LogMsg "Job " . $Job->Id . ": Unable to open '$BaseName.testbot' for writing: $!";
+      Error "Job ". $Job->Id .": Unable to open '$BaseName.testbot' for writing: $!";
     }
   }
 }
@@ -509,37 +583,96 @@ EOF
 $ENV{PATH} = "/usr/bin:/bin";
 delete $ENV{ENV};
 
-my $JobId = $ARGV[0];
-if (! $JobId)
+my $Usage;
+sub ValidateNumber($$)
+{
+  my ($Name, $Value) = @_;
+
+  # Validate and untaint the value
+  return $1 if ($Value =~ /^(\d+)$/);
+  Error "$Value is not a valid $Name\n";
+  $Usage = 2;
+  return undef;
+}
+
+my ($JobId);
+while (@ARGV)
 {
-  die "Usage: WineSendLog.pl JobId";
+  my $Arg = shift @ARGV;
+  if ($Arg eq "--debug")
+  {
+    $Debug = 1;
+  }
+  elsif ($Arg eq "--log-only")
+  {
+    $LogOnly = 1;
+  }
+  elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+  {
+    $Usage = 0;
+    last;
+  }
+  elsif ($Arg =~ /^-/)
+  {
+    Error "unknown option '$Arg'\n";
+    $Usage = 2;
+    last;
+  }
+  elsif (!defined $JobId)
+  {
+    $JobId = ValidateNumber('job id', $Arg);
+  }
+  else
+  {
+    Error "unexpected argument '$Arg'\n";
+    $Usage = 2;
+    last;
+  }
 }
 
-# Untaint parameters
-if ($JobId =~ /^(\d+)$/)
+# Check parameters
+if (!defined $Usage)
 {
-  $JobId = $1;
+  if (!defined $JobId)
+  {
+    Error "you must specify the job id\n";
+    $Usage = 2;
+  }
 }
-else
+if (defined $Usage)
 {
-  LogMsg "Invalid JobId $JobId\n";
-  exit(1);
+  if ($Usage)
+  {
+    Error "try '$Name0 --help' for more information\n";
+    exit $Usage;
+  }
+  print "Usage: $Name0 [--debug] [--help] JOBID\n";
+  print "\n";
+  print "Analyze the job's logs and notifies the developer and the patches website.\n";
+  print "\n";
+  print "Where:\n";
+  print "  JOBID      Id of the job to report on.\n";
+  print "  --debug    More verbose messages for debugging.\n";
+  print "  --log-only Only send error messages to the log instead of also printing them\n";
+  print "             on stderr.\n";
+  print "  --help     Shows this usage message.\n";
+  exit 0;
 }
 
 my $Job = CreateJobs()->GetItem($JobId);
-if (! defined($Job))
+if (!defined $Job)
 {
-  LogMsg "Job $JobId doesn't exist\n";
-  exit(1);
+  Error "Job $JobId doesn't exist\n";
+  exit 1;
 }
 
 
 #
-# Analyze the log and notify the developer
+# Analyze the log, notify the developer and the Patches website
 #
 
 SendLog($Job);
 
 LogMsg "Log for job $JobId sent\n";
 
-exit(0);
+exit 0;




More information about the wine-cvs mailing list