From: Francois Gouget Subject: [05/25] testbot/LogUtils: Return the log errors as a single object. Message-Id: Date: Tue, 14 Jan 2020 16:41:17 +0100 (CET) In-Reply-To: References: --- testbot/bin/WineSendLog.pl | 26 +++---- testbot/lib/WineTestBot/LogUtils.pm | 103 +++++++++++++++++----------- testbot/web/JobDetails.pl | 21 +++--- 3 files changed, 86 insertions(+), 64 deletions(-) diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl index d61b403b9..89e90c40f 100755 --- a/testbot/bin/WineSendLog.pl +++ b/testbot/bin/WineSendLog.pl @@ -207,18 +207,18 @@ EOF $JobErrors->{$Key}->{LogNames} = $LogNames; foreach my $LogName (@$LogNames) { - my ($Groups, $Errors) = GetLogErrors("$TaskDir/$LogName"); - next if (!$Groups or !@$Groups); + my $LogInfo = GetLogErrors("$TaskDir/$LogName"); + next if (!$LogInfo->{ErrCount}); $JobErrors->{$Key}->{HasErrors} = 1; - $JobErrors->{$Key}->{$LogName}->{Groups} = $Groups; - $JobErrors->{$Key}->{$LogName}->{Errors} = $Errors; + $JobErrors->{$Key}->{$LogName} = $LogInfo; print $Sendmail "\n=== ", GetTitle($StepTask, $LogName), " ===\n"; - foreach my $GroupName (@$Groups) + foreach my $GroupName (@{$LogInfo->{ErrGroupNames}}) { print $Sendmail ($GroupName ? "\n$GroupName:\n" : "\n"); - print $Sendmail "$_\n" for (@{$Errors->{$GroupName}->{Errors}}); + my $Group = $LogInfo->{ErrGroups}->{$GroupName}; + print $Sendmail "$_\n" for (@{$Group->{Errors}}); } } } @@ -287,14 +287,14 @@ EOF foreach my $LogName (@{$JobErrors->{$Key}->{LogNames}}) { - my $LogErrors = $JobErrors->{$Key}->{$LogName}; + my $LogInfo = $JobErrors->{$Key}->{$LogName}; # Skip if there are no errors - next if (!$LogErrors->{Groups}); + next if (!$LogInfo->{ErrCount}); my $AllNew; my $RefReportPath = $StepTask->GetFullFileName($StepTask->GetRefReportName($LogName)); - my $NewCount = TagNewErrors($RefReportPath, $LogErrors->{Groups}, $LogErrors->{Errors}); - if (!defined $NewCount) + TagNewErrors($RefReportPath, $LogInfo); + if (!defined $LogInfo->{NewCount}) { # Test reports should have reference WineTest results and if not # reporting the errors as new would cause false positives. @@ -303,7 +303,7 @@ EOF # Build logs don't have reference logs so for them every error is new. $AllNew = 1; } - elsif (!$NewCount) + elsif (!$LogInfo->{NewCount}) { # There is no new error next; @@ -311,9 +311,9 @@ EOF push @Messages, "\n=== ". GetTitle($StepTask, $LogName) ." ===\n"; - foreach my $GroupName (@{$LogErrors->{Groups}}) + foreach my $GroupName (@{$LogInfo->{ErrGroupNames}}) { - my $Group = $LogErrors->{Errors}->{$GroupName}; + my $Group = $LogInfo->{ErrGroups}->{$GroupName}; next if (!$AllNew and !$Group->{NewCount}); push @Messages, ($GroupName ? "\n$GroupName:\n" : "\n"); diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm index 3141cb286..d3aa82c2e 100644 --- a/testbot/lib/WineTestBot/LogUtils.pm +++ b/testbot/lib/WineTestBot/LogUtils.pm @@ -673,18 +673,18 @@ sub _DumpErrors($$$) } } -sub _AddErrorGroup($$$) +sub _AddErrorGroup($$) { - my ($Groups, $Errors, $GroupName) = @_; + my ($LogInfo, $GroupName) = @_; # In theory the error group names are all unique. But, just in case, make - # sure we don't overwrite $Errors->{$GroupName}. - if (!$Errors->{$GroupName}) + # sure we don't overwrite $LogInfo->{ErrGroups}->{$GroupName}. + if (!$LogInfo->{ErrGroups}->{$GroupName}) { - push @$Groups, $GroupName; - $Errors->{$GroupName} = {Errors => []}; + push @{$LogInfo->{ErrGroupNames}}, $GroupName; + $LogInfo->{ErrGroups}->{$GroupName} = { Errors => [] }; } - return $Errors->{$GroupName}; + return $LogInfo->{ErrGroups}->{$GroupName}; } =pod @@ -696,8 +696,24 @@ Analyzes the specified log and associated error file to filter out unimportant messages and only return the errors, split by module (for Wine reports that's per dll / program being tested). -Returns a list of modules containing errors, and a hashtable containing the list of errors for each module. +Returns a hashtable containing: +=over + +=item ErrCount +The number of errors. This is undefined if no log file was found. + +=item ErrGroupNames +An array containing the names of all the error groups. + +=item ErrGroups +A hashtable indexed by the error group name. Each entry contains: +=over +=item Errors +An array containing the error messages. +=back + +=back =back =cut @@ -716,12 +732,14 @@ sub GetLogErrors($) $GetCategory = \&GetLogLineCategory; } - my $NoLog = 1; - my $Groups = []; - my $Errors = {}; + my $LogInfo = { + ErrCount => undef, # until we open a log + ErrGroupNames => [], + ErrGroups => {}, + }; if (open(my $LogFile, "<", $LogFileName)) { - $NoLog = 0; + $LogInfo->{ErrCount} ||= 0; my $CurrentModule = ""; my $CurrentGroup; foreach my $Line (<$LogFile>) @@ -743,22 +761,23 @@ sub GetLogErrors($) } if (!$CurrentGroup) { - $CurrentGroup = _AddErrorGroup($Groups, $Errors, $CurrentModule); + $CurrentGroup = _AddErrorGroup($LogInfo, $CurrentModule); } push @{$CurrentGroup->{Errors}}, $Line; + $LogInfo->{ErrCount}++; } close($LogFile); } elsif (-f $LogFileName) { - $NoLog = 0; - my $Group = _AddErrorGroup($Groups, $Errors, "TestBot errors"); - $Group->{Errors} = ["Could not open '". basename($LogFileName) ."' for reading: $!"]; + my $Group = _AddErrorGroup($LogInfo, "TestBot errors"); + push @{$Group->{Errors}}, "Could not open '". basename($LogFileName) ."' for reading: $!"; + $LogInfo->{ErrCount}++; } if (open(my $LogFile, "<", "$LogFileName.err")) { - $NoLog = 0; + $LogInfo->{ErrCount} ||= 0; # Add the related extra errors my $CurrentGroup; foreach my $Line (<$LogFile>) @@ -769,20 +788,21 @@ sub GetLogErrors($) # Note: $GroupName must not depend on the previous content as this # would break diffs. my $GroupName = $IsReport ? "Report errors" : "Task errors"; - $CurrentGroup = _AddErrorGroup($Groups, $Errors, $GroupName); + $CurrentGroup = _AddErrorGroup($LogInfo, $GroupName); } push @{$CurrentGroup->{Errors}}, $Line; + $LogInfo->{ErrCount}++; } close($LogFile); } elsif (-f "$LogFileName.err") { - $NoLog = 0; - my $Group = _AddErrorGroup($Groups, $Errors, "TestBot errors"); - $Group->{Errors} = ["Could not open '". basename($LogFileName) .".err' for reading: $!"]; + my $Group = _AddErrorGroup($LogInfo, "TestBot errors"); + push @{$Group->{Errors}}, "Could not open '". basename($LogFileName) .".err' for reading: $!"; + $LogInfo->{ErrCount}++; } - return $NoLog ? (undef, undef) : ($Groups, $Errors); + return $LogInfo; } sub _DumpDiff($$) @@ -849,6 +869,9 @@ sub _GetLineKey($) Compares the specified errors to the reference report to identify new errors. +Sets $LogInfo->{NewCount} to the total number of new errors. If there is no +reference log to identify the new errors this field is left undefined. + Adds two fields to each error group: =over @@ -859,32 +882,33 @@ A count of the new errors. 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 TagNewErrors($$$) +sub TagNewErrors($$) { - my ($RefLogPath, $Groups, $Errors) = @_; + my ($RefLogPath, $LogInfo) = @_; - return 0 if (!$Groups or !@$Groups); + if (!$LogInfo->{ErrCount}) + { + $LogInfo->{NewCount} = 0; + return; + } - my ($RefGroups, $RefErrors) = GetLogErrors($RefLogPath); - return undef if (!$RefGroups); + my $RefInfo = GetLogErrors($RefLogPath); + # Don't tag the errors as new if there is no reference log + return if (!defined $RefInfo->{ErrCount}); - my $NewCount = 0; - foreach my $GroupName (@$Groups) + $LogInfo->{NewCount} = 0; + foreach my $GroupName (@{$LogInfo->{ErrGroupNames}}) { - my $Group = $Errors->{$GroupName}; + my $Group = $LogInfo->{ErrGroups}->{$GroupName}; $Group->{NewCount} = 0; - if ($RefErrors->{$GroupName}) + my $RefGroup = $RefInfo->{ErrGroups}->{$GroupName}; + if ($RefGroup) { - my $Diff = Algorithm::Diff->new($RefErrors->{$GroupName}->{Errors}, - $Group->{Errors}, + my $Diff = Algorithm::Diff->new($RefGroup->{Errors}, $Group->{Errors}, { keyGen => \&_GetLineKey }); my $ErrIndex = 0; while ($Diff->Next()) @@ -909,6 +933,7 @@ sub TagNewErrors($$$) } else { + # All errors in this group are new $Group->{NewCount} = @{$Group->{Errors}}; if ($Group->{NewCount}) { @@ -918,10 +943,8 @@ sub TagNewErrors($$$) } } } - $NewCount += $Group->{NewCount}; + $LogInfo->{NewCount} += $Group->{NewCount}; } - - return $NewCount; } 1; diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl index f3105d019..48d511ccb 100644 --- a/testbot/web/JobDetails.pl +++ b/testbot/web/JobDetails.pl @@ -500,21 +500,20 @@ EOF # # Figure out which logs / reports actually have errors - my $LogSummaries; + my $LogInfos; foreach my $LogName (@{$MoreInfo->{Logs}}) { next if ($LogName =~ /^old_/); - my ($Groups, $Errors) = GetLogErrors("$TaskDir/$LogName"); - next if (!$Groups or !@$Groups); - $LogSummaries->{$LogName}->{Groups} = $Groups; - $LogSummaries->{$LogName}->{Errors} = $Errors; + my $LogInfo = GetLogErrors("$TaskDir/$LogName"); + next if (!$LogInfo->{ErrCount}); + $LogInfos->{$LogName} = $LogInfo; } - my $ShowLogName = ($ReportCount > 1 or scalar(keys %$LogSummaries) > 1); + my $ShowLogName = ($ReportCount > 1 or scalar(keys %$LogInfos) > 1); my $LogIsEmpty = 1; foreach my $LogName (@{$MoreInfo->{Logs}}) { - next if (!$LogSummaries->{$LogName}); + next if (!$LogInfos->{$LogName}); $LogIsEmpty = 0; if ($ShowLogName) @@ -524,21 +523,21 @@ EOF print "
$Label
\n"; } - my $Summary = $LogSummaries->{$LogName}; + my $LogInfo = $LogInfos->{$LogName}; if ($LogName =~ /\.report$/) { # For test reports try to identify the new errors my $RefReportPath = $StepTask->GetFullFileName($StepTask->GetRefReportName($LogName)); - TagNewErrors($RefReportPath, $Summary->{Groups}, $Summary->{Errors}); + TagNewErrors($RefReportPath, $LogInfo); } - foreach my $GroupName (@{$Summary->{Groups}}) + foreach my $GroupName (@{$LogInfo->{ErrGroupNames}}) { print "
$GroupName
\n" if ($GroupName); print "
";
           my $ErrIndex = 0;
-          my $Group = $Summary->{Errors}->{$GroupName};
+          my $Group = $LogInfo->{ErrGroups}->{$GroupName};
           foreach my $Line (@{$Group->{Errors}})
           {
             if ($Group->{IsNew}->[$ErrIndex])

-- 
2.20.1