Francois Gouget : testbot/web: Highlight new errors on the JobDetails page.
Alexandre Julliard
julliard at winehq.org
Thu Aug 30 13:54:09 CDT 2018
Module: tools
Branch: master
Commit: afe56cb39e47f6337c8eba808a17f5710a4bcfd4
URL: https://source.winehq.org/git/tools.git/?a=commit;h=afe56cb39e47f6337c8eba808a17f5710a4bcfd4
Author: Francois Gouget <fgouget at codeweavers.com>
Date: Thu Aug 30 02:00:22 2018 +0200
testbot/web: Highlight new errors on the JobDetails page.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
testbot/bin/WineRunBuild.pl | 31 +++++++++++++++++++++++++++++++
testbot/bin/WineSendLog.pl | 2 +-
testbot/lib/WineTestBot/LogUtils.pm | 21 +++++++++++++--------
testbot/lib/WineTestBot/Steps.pm | 16 +++++++++++-----
testbot/lib/WineTestBot/StepsTasks.pm | 16 +++++++++++-----
testbot/web/JobDetails.pl | 24 +++++++++++++++++++++++-
testbot/web/WineTestBot.css | 1 +
7 files changed, 91 insertions(+), 20 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 117b065..11b41c6 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -472,6 +472,37 @@ $TA->Disconnect();
#
+# Grab a copy of the reference logs
+#
+
+# Note that this may be a bit inaccurate right after a Wine commit.
+# See WineSendLog.pl for more details.
+my $LatestDir = "$DataDir/latest";
+foreach my $TestStep (@{$Job->Steps->GetItems()})
+{
+ if (($TestStep->PreviousNo || 0) == $Step->No and
+ $TestStep->FileType =~ /^exe/)
+ {
+ foreach my $TestTask (@{$TestStep->Tasks->GetItems()})
+ {
+ my $RefReport = $TestTask->VM->Name ."_". $TestStep->FileType .".report";
+ for my $Suffix ("", ".err")
+ {
+ if (-f "$LatestDir/$RefReport$Suffix")
+ {
+ unlink "$StepDir/$RefReport$Suffix";
+ if (!link "$LatestDir/$RefReport$Suffix", "$StepDir/$RefReport$Suffix")
+ {
+ Error "Could not link '$RefReport$Suffix': $!\n";
+ }
+ }
+ }
+ }
+ }
+}
+
+
+#
# Wrap up
#
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index a4b1c82..36d47c3 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -288,7 +288,7 @@ EOF
{
my $LogErrors = $JobErrors->{$Key}->{$LogName};
my $RefFileName = "$DataDir/latest". $StepTask->VM->Name ."_$LogName";
- my ($NewGroups, $NewErrors) = GetNewLogErrors($RefFileName, $LogErrors->{Groups}, $LogErrors->{Errors});
+ my ($NewGroups, $NewErrors, $_NewIndices) = GetNewLogErrors($RefFileName, $LogErrors->{Groups}, $LogErrors->{Errors});
if (!$NewGroups)
{
# There was no reference log (typical of build logs)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 17b9093..5120217 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -781,8 +781,9 @@ sub _GetLineKey($)
Compares the specified errors to the reference log and returns only the ones
that are new.
-Returns a list of error groups containing new errors and a hashtable containing
-the list of new errors for each group.
+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.
=back
=cut
@@ -791,10 +792,10 @@ sub GetNewLogErrors($$$)
{
my ($RefFileName, $Groups, $Errors) = @_;
- my ($_Dummy, $RefErrors, $NoLog) = GetLogErrors($RefFileName);
- return (undef, undef) if ($NoLog);
+ my ($RefGroups, $RefErrors) = GetLogErrors($RefFileName);
+ return (undef, undef) if (!$RefGroups);
- my (@NewGroups, %NewErrors);
+ my (@NewGroups, %NewErrors, %NewIndices);
foreach my $GroupName (@$Groups)
{
if ($RefErrors->{$GroupName})
@@ -802,7 +803,7 @@ sub GetNewLogErrors($$$)
my $Diff = Algorithm::Diff->new($RefErrors->{$GroupName},
$Errors->{$GroupName},
{ keyGen => \&_GetLineKey });
- my $CurrentGroup;
+ my ($CurrentGroup, $CurrentIndices);
while ($Diff->Next())
{
# Skip if there are no new lines
@@ -812,20 +813,24 @@ sub GetNewLogErrors($$$)
{
push @NewGroups, $GroupName;
$CurrentGroup = $NewErrors{$GroupName} = [];
+ $CurrentIndices = $NewIndices{$GroupName} = {};
}
push @$CurrentGroup, $Diff->Items(2);
+ $CurrentIndices->{$_} = 1 for ($Diff->Range(2));
}
}
else
{
- # This module did not have errors before, so every error is new
+ # 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);
}
}
- return (\@NewGroups, \%NewErrors);
+ return (\@NewGroups, \%NewErrors, \%NewIndices);
}
1;
diff --git a/testbot/lib/WineTestBot/Steps.pm b/testbot/lib/WineTestBot/Steps.pm
index 2f5bdb0..ae1180c 100644
--- a/testbot/lib/WineTestBot/Steps.pm
+++ b/testbot/lib/WineTestBot/Steps.pm
@@ -146,16 +146,22 @@ sub RmTree($)
rmtree($Dir);
}
-sub GetFullFileName($)
+sub GetFullFileName($;$)
{
- my ($self) = @_;
+ my ($self, $FileName) = @_;
- return undef if (!defined $self->FileName);
+ $FileName = $self->FileName if (!defined $FileName);
+ return undef if (!defined $FileName);
my ($JobId, $StepNo) = @{$self->GetMasterKey()};
my $Path = "$DataDir/jobs/$JobId/";
- $Path .= $self->PreviousNo ."/" if ($self->PreviousNo);
- return $Path . $self->FileName;
+ foreach my $StepNo ($StepNo, $self->PreviousNo)
+ {
+ next if (!$StepNo);
+ my $Full = "$Path$StepNo/$FileName";
+ return $Full if (-f $Full);
+ }
+ return $Path . $FileName;
}
sub UpdateStatus($$)
diff --git a/testbot/lib/WineTestBot/StepsTasks.pm b/testbot/lib/WineTestBot/StepsTasks.pm
index 4675194..a50f61a 100644
--- a/testbot/lib/WineTestBot/StepsTasks.pm
+++ b/testbot/lib/WineTestBot/StepsTasks.pm
@@ -40,16 +40,22 @@ sub GetStepDir($)
}
# See WineTestBot::Step::GetFullFileName()
-sub GetFullFileName($)
+sub GetFullFileName($;$)
{
- my ($self) = @_;
+ my ($self, $FileName) = @_;
- return undef if (!defined $self->FileName);
+ $FileName = $self->FileName if (!defined $FileName);
+ return undef if (!defined $FileName);
my ($JobId, $_StepTaskId) = @{$self->GetMasterKey()};
my $Path = "$DataDir/jobs/$JobId/";
- $Path .= $self->PreviousNo ."/" if ($self->PreviousNo);
- return $Path . $self->FileName;
+ foreach my $StepNo ($self->StepNo, $self->PreviousNo)
+ {
+ next if (!$StepNo);
+ my $Full = "$Path$StepNo/$FileName";
+ return $Full if (-f $Full);
+ }
+ return $Path . $FileName;
}
sub GetTaskDir($)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 51fb2e9..bcf3231 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -25,6 +25,7 @@ package JobDetailsPage;
use ObjectModel::CGI::CollectionPage;
our @ISA = qw(ObjectModel::CGI::CollectionPage);
+use File::Basename;
use URI::Escape;
use WineTestBot::Config;
@@ -484,11 +485,32 @@ EOF
}
my $Summary = $LogSummaries->{$LogName};
+ my $New;
+ if ($LogName =~ /\.report$/)
+ {
+ # Identify new errors in test reports
+ my $RefFileName = $StepTask->GetFullFileName($VM->Name ."_$LogName");
+ (my $_NewGroups, my $_NewErrors, $New) = GetNewLogErrors($RefFileName, $Summary->{Groups}, $Summary->{Errors});
+ }
+
foreach my $GroupName (@{$Summary->{Groups}})
{
print "<div class='LogDllName'>$GroupName:</div>\n" if ($GroupName);
+
print "<pre><code>";
- print $self->escapeHTML($_), "\n" for (@{$Summary->{Errors}->{$GroupName}});
+ my $ErrIndex = 0;
+ foreach my $Line (@{$Summary->{Errors}->{$GroupName}})
+ {
+ if ($New and $New->{$GroupName}->{$ErrIndex})
+ {
+ print "<span class='log-new'>", $self->escapeHTML($Line), "</span>\n";
+ }
+ else
+ {
+ print $self->escapeHTML($Line), "\n";
+ }
+ $ErrIndex++;
+ }
print "</code></pre>\n";
}
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 9656254..88badfe 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -379,6 +379,7 @@ pre
.log-error { color: red; }
.log-boterror { color: #cc0052; }
.log-diag { color: #e56300; }
+.log-new { color: #e56e00; font-weight: bold; }
a.title { color:inherit; text-decoration: none; }
More information about the wine-cvs
mailing list