[04/25] testbot/LogUtils: Tag new errors instead of filtering them.

Francois Gouget fgouget at codeweavers.com
Tue Jan 14 09:41:05 CST 2020


TagNewErrors() replaces GetNewLogErrors() and tags new errors in the
provided error list instead of returning a new list containing only the
new errors.
---
 testbot/bin/WineSendLog.pl          |  27 +++++---
 testbot/lib/WineTestBot/LogUtils.pm | 103 +++++++++++++++++-----------
 testbot/web/JobDetails.pl           |  10 +--
 3 files changed, 85 insertions(+), 55 deletions(-)

diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 1ec7db1bd..d61b403b9 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -218,7 +218,7 @@ EOF
       foreach my $GroupName (@$Groups)
       {
         print $Sendmail ($GroupName ? "\n$GroupName:\n" : "\n");
-        print $Sendmail "$_\n" for (@{$Errors->{$GroupName}});
+        print $Sendmail "$_\n" for (@{$Errors->{$GroupName}->{Errors}});
       }
     }
   }
@@ -251,7 +251,7 @@ EOF
       }
     }
   }
-  
+
   print $Sendmail "\n--$PART_BOUNDARY--\n";
   close($Sendmail);
 
@@ -291,19 +291,19 @@ EOF
       # Skip if there are no errors
       next if (!$LogErrors->{Groups});
 
+      my $AllNew;
       my $RefReportPath = $StepTask->GetFullFileName($StepTask->GetRefReportName($LogName));
-      my ($NewGroups, $NewErrors, $_NewIndices) = GetNewLogErrors($RefReportPath, $LogErrors->{Groups}, $LogErrors->{Errors});
-      if (!$NewGroups)
+      my $NewCount = TagNewErrors($RefReportPath, $LogErrors->{Groups}, $LogErrors->{Errors});
+      if (!defined $NewCount)
       {
         # Test reports should have reference WineTest results and if not
         # reporting the errors as new would cause false positives.
         next if ($LogName =~ /\.report$/);
 
         # Build logs don't have reference logs so for them every error is new.
-        $NewGroups = $LogErrors->{Groups};
-        $NewErrors = $LogErrors->{Errors};
+        $AllNew = 1;
       }
-      if (!$NewGroups or !@$NewGroups)
+      elsif (!$NewCount)
       {
         # There is no new error
         next;
@@ -311,10 +311,19 @@ EOF
 
       push @Messages, "\n=== ". GetTitle($StepTask, $LogName) ." ===\n";
 
-      foreach my $GroupName (@$NewGroups)
+      foreach my $GroupName (@{$LogErrors->{Groups}})
       {
+        my $Group = $LogErrors->{Errors}->{$GroupName};
+        next if (!$AllNew and !$Group->{NewCount});
+
         push @Messages, ($GroupName ? "\n$GroupName:\n" : "\n");
-        push @Messages, "$_\n" for (@{$NewErrors->{$GroupName}});
+        foreach my $ErrIndex (0..@{$Group->{Errors}} - 1)
+        {
+          if ($AllNew or $Group->{IsNew}->[$ErrIndex])
+          {
+            push @Messages, "$Group->{Errors}->[$ErrIndex]\n";
+          }
+        }
       }
     }
   }
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index f52af6704..3141cb286 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -1,5 +1,5 @@
 # -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
-# Copyright 2018 Francois Gouget
+# Copyright 2018-2019 Francois Gouget
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@ WineTestBot::LogUtils - Provides functions to parse task logs
 
 
 use Exporter 'import';
-our @EXPORT = qw(GetLogFileNames GetLogLabel GetLogErrors GetNewLogErrors
+our @EXPORT = qw(GetLogFileNames GetLogLabel GetLogErrors TagNewErrors
                  GetLogLineCategory GetReportLineCategory
                  ParseTaskLog ParseWineTestReport);
 
@@ -669,7 +669,7 @@ sub _DumpErrors($$$)
   foreach my $GroupName (@$Groups)
   {
     print STDERR "  [$GroupName]\n";
-    print STDERR "    [$_]\n" for (@{$Errors->{$GroupName}});
+    print STDERR "    [$_]\n" for (@{$Errors->{$GroupName}->{Errors}});
   }
 }
 
@@ -682,7 +682,7 @@ sub _AddErrorGroup($$$)
   if (!$Errors->{$GroupName})
   {
     push @$Groups, $GroupName;
-    $Errors->{$GroupName} = [];
+    $Errors->{$GroupName} = {Errors => []};
   }
   return $Errors->{$GroupName};
 }
@@ -745,7 +745,7 @@ sub GetLogErrors($)
       {
         $CurrentGroup = _AddErrorGroup($Groups, $Errors, $CurrentModule);
       }
-      push @$CurrentGroup, $Line;
+      push @{$CurrentGroup->{Errors}},  $Line;
     }
     close($LogFile);
   }
@@ -753,7 +753,7 @@ sub GetLogErrors($)
   {
     $NoLog = 0;
     my $Group = _AddErrorGroup($Groups, $Errors, "TestBot errors");
-    push @$Group, "Could not open '". basename($LogFileName) ."' for reading: $!";
+    $Group->{Errors} = ["Could not open '". basename($LogFileName) ."' for reading: $!"];
   }
 
   if (open(my $LogFile, "<", "$LogFileName.err"))
@@ -771,7 +771,7 @@ sub GetLogErrors($)
         my $GroupName = $IsReport ? "Report errors" : "Task errors";
         $CurrentGroup = _AddErrorGroup($Groups, $Errors, $GroupName);
       }
-      push @$CurrentGroup, $Line;
+      push @{$CurrentGroup->{Errors}}, $Line;
     }
     close($LogFile);
   }
@@ -779,7 +779,7 @@ sub GetLogErrors($)
   {
     $NoLog = 0;
     my $Group = _AddErrorGroup($Groups, $Errors, "TestBot errors");
-    push @$Group, "Could not open '". basename($LogFileName) .".err' for reading: $!";
+    $Group->{Errors} = ["Could not open '". basename($LogFileName) .".err' for reading: $!"];
   }
 
   return $NoLog ? (undef, undef) : ($Groups, $Errors);
@@ -812,8 +812,9 @@ sub _DumpDiff($$)
 
 =item C<_GetLineKey()>
 
-This is a helper for GetNewLogErrors(). It reformats the log lines so they can
-meaningfully be compared to the reference log even if line numbers change, etc.
+This is a helper for TagNewErrors(). It reformats the log lines so they
+can meaningfully be compared to the reference log even if line numbers change,
+etc.
 
 =back
 =cut
@@ -844,63 +845,83 @@ sub _GetLineKey($)
 =pod
 =over 12
 
-=item C<GetNewLogErrors()>
+=item C<TagNewErrors()>
 
-Compares the specified errors to the reference log and returns only the ones
-that are new.
+Compares the specified errors to the reference report to identify new errors.
 
-Returns a list of error groups containing new errors, a hashtable containing
-the list of new errors for each group, and a hashtable containing the indices
-of the new errors in the input errors list for each group.
+Adds two fields to each error group:
+=over
+
+=item NewCount
+A count of the new errors.
+
+=item IsNew
+An array where entries are set to true to identify new errors.
+
+=back
+
+Returns a global count of the new errors. Returns undef if there is no
+reference log to identify the new errors.
 
 =back
 =cut
 
-sub GetNewLogErrors($$$)
+sub TagNewErrors($$$)
 {
-  my ($RefFileName, $Groups, $Errors) = @_;
+  my ($RefLogPath, $Groups, $Errors) = @_;
 
-  my (@NewGroups, %NewErrors, %NewIndices);
-  return (\@NewGroups, \%NewErrors, \%NewIndices) if (!$Groups or !@$Groups);
+  return 0 if (!$Groups or !@$Groups);
 
-  my ($RefGroups, $RefErrors) = GetLogErrors($RefFileName);
-  return (undef, undef) if (!$RefGroups);
+  my ($RefGroups, $RefErrors) = GetLogErrors($RefLogPath);
+  return undef if (!$RefGroups);
 
+  my $NewCount = 0;
   foreach my $GroupName (@$Groups)
   {
+    my $Group = $Errors->{$GroupName};
+    $Group->{NewCount} = 0;
+
     if ($RefErrors->{$GroupName})
     {
-      my $Diff = Algorithm::Diff->new($RefErrors->{$GroupName},
-                                      $Errors->{$GroupName},
+      my $Diff = Algorithm::Diff->new($RefErrors->{$GroupName}->{Errors},
+                                      $Group->{Errors},
                                       { keyGen => \&_GetLineKey });
-      my ($CurrentGroup, $CurrentIndices);
+      my $ErrIndex = 0;
       while ($Diff->Next())
       {
-        # Skip if there are no new lines
-        next if ($Diff->Same() or !$Diff->Items(2));
-
-        if (!$CurrentGroup)
+        my $SameCount = $Diff->Same();
+        if ($SameCount)
+        {
+          $ErrIndex += $SameCount;
+        }
+        else
         {
-          push @NewGroups, $GroupName;
-          $CurrentGroup = $NewErrors{$GroupName} = [];
-          $CurrentIndices = $NewIndices{$GroupName} = {};
+          # Added lines are the new errors
+          my $AddedCount = $Diff->Items(2);
+          $Group->{NewCount} += $AddedCount;
+          foreach (1..$AddedCount)
+          {
+            $Group->{IsNew}->[$ErrIndex] = 1;
+            $ErrIndex++;
+          }
         }
-        push @$CurrentGroup, $Diff->Items(2);
-        $CurrentIndices->{$_} = 1 for ($Diff->Range(2));
       }
     }
     else
     {
-      # This group did not have errors before, so every error is new
-      push @NewGroups, $GroupName;
-      $NewErrors{$GroupName} = $Errors->{$GroupName};
-      $NewIndices{$GroupName} = {};
-      my $Last = @{$Errors->{$GroupName}} - 1;
-      $NewIndices{$GroupName}->{$_} = 1 for (0..$Last);
+      $Group->{NewCount} = @{$Group->{Errors}};
+      if ($Group->{NewCount})
+      {
+        foreach my $ErrIndex (0..$Group->{NewCount} - 1)
+        {
+          $Group->{IsNew}->[$ErrIndex] = 1;
+        }
+      }
     }
+    $NewCount += $Group->{NewCount};
   }
 
-  return (\@NewGroups, \%NewErrors, \%NewIndices);
+  return $NewCount;
 }
 
 1;
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 4d08a862c..f3105d019 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -525,12 +525,11 @@ EOF
         }
 
         my $Summary = $LogSummaries->{$LogName};
-        my $New;
         if ($LogName =~ /\.report$/)
         {
-          # Identify new errors in test reports
+          # For test reports try to identify the new errors
           my $RefReportPath = $StepTask->GetFullFileName($StepTask->GetRefReportName($LogName));
-          (my $_NewGroups, my $_NewErrors, $New) = GetNewLogErrors($RefReportPath, $Summary->{Groups}, $Summary->{Errors});
+          TagNewErrors($RefReportPath, $Summary->{Groups}, $Summary->{Errors});
         }
 
         foreach my $GroupName (@{$Summary->{Groups}})
@@ -539,9 +538,10 @@ EOF
 
           print "<pre><code>";
           my $ErrIndex = 0;
-          foreach my $Line (@{$Summary->{Errors}->{$GroupName}})
+          my $Group = $Summary->{Errors}->{$GroupName};
+          foreach my $Line (@{$Group->{Errors}})
           {
-            if ($New and $New->{$GroupName}->{$ErrIndex})
+            if ($Group->{IsNew}->[$ErrIndex])
             {
               print "<span class='log-new'>", $self->escapeHTML($Line), "</span>\n";
             }
-- 
2.20.1




More information about the wine-devel mailing list