From: Francois Gouget Subject: [04/25] testbot/LogUtils: Tag new errors instead of filtering them. Message-Id: <862d43611a54dcfa654b985a0efed7963fffefef.1579000229.git.fgouget@codeweavers.com> Date: Tue, 14 Jan 2020 16:41:05 +0100 (CET) In-Reply-To: References: 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 +=item C -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 "
";
           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 "", $self->escapeHTML($Line), "\n";
             }

-- 
2.20.1