[PATCH] testbot/LogUtils: Return the log errors as a single object.
Francois Gouget
fgouget at codeweavers.com
Thu Jan 16 08:43:21 CST 2020
The $LogInfo structure is more extensible and can carry additional
information such as the total number of errors (ErrCount) and the total
number of new errors (NewCount).
Adjust _AddErrorGroup(), TagNewErrors() and _DumpErrors() to take the
new $LogInfo structure returned by GetLogErrors() instead of the
($Groups, $Errors) tuple.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
testbot/bin/WineSendLog.pl | 26 +++---
testbot/lib/WineTestBot/LogUtils.pm | 129 +++++++++++++++++-----------
testbot/web/JobDetails.pl | 21 +++--
3 files changed, 103 insertions(+), 73 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 6704f9828..fdf7e2409 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -208,18 +208,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}});
}
}
}
@@ -288,14 +288,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.
@@ -304,7 +304,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;
@@ -312,9 +312,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 e1a8176ac..815e0d8db 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -658,33 +658,35 @@ sub GetLogLabel($)
}
-sub _DumpErrors($$$)
+sub _DumpErrors($$)
{
- my ($Label, $Groups, $Errors) = @_;
+ my ($Label, $LogInfo) = @_;
- print STDERR "$Label:\n";
- print STDERR " Groups=", scalar(@$Groups), " [", join(",", @$Groups), "]\n";
- my @ErrorKeys = sort keys %$Errors;
+ print STDERR "$Label: ", join(" ", keys %$LogInfo), "\n";
+ my $GroupNames = $LogInfo->{ErrGroupNames};
+ print STDERR " Groups=", scalar(@$GroupNames), " [", join(",", @$GroupNames), "]\n";
+ my @ErrorKeys = sort keys %{$LogInfo->{Groups}};
print STDERR " Errors=", scalar(@ErrorKeys), " [", join(",", @ErrorKeys), "]\n";
- foreach my $GroupName (@$Groups)
+ foreach my $GroupName (@$GroupNames)
{
print STDERR " [$GroupName]\n";
- print STDERR " [$_]\n" for (@{$Errors->{$GroupName}->{Errors}});
+ my $Group = $LogInfo->{Groups}->{$GroupName};
+ print STDERR " [$_]\n" for (@{$Group->{Errors}});
}
}
-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 +698,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 +734,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 +763,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 +790,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,42 +871,52 @@ sub _GetLineKey($)
Compares the specified errors to the reference report to identify new errors.
-Adds two fields to each error group:
+The $LogInfo structure is augmented with the following fields:
=over
=item NewCount
-A count of the new errors.
+The total number of new errors or undef if the reference log could not be read.
+
+=item ErrGroups
+=over
+
+=item NewCount
+A count of the group's new errors.
=item IsNew
-An array where entries are set to true to identify new errors.
+An array indicating which entries in the group's Errors array are new
+or undef if there are no new errors in this group.
=back
-Returns a global count of the new errors. Returns undef if there is no
-reference log to identify the new errors.
-
+=back
=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 +941,7 @@ sub TagNewErrors($$$)
}
else
{
+ # All errors in this group are new
$Group->{NewCount} = @{$Group->{Errors}};
if ($Group->{NewCount})
{
@@ -918,10 +951,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 ee4013a1b..76de1bb23 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 "<div class='HrTitle'>$Label<div class='HrLine'></div></div>\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 "<div class='LogDllName'>$GroupName</div>\n" if ($GroupName);
print "<pre><code>";
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
More information about the wine-devel
mailing list