[PATCH] testbot/web: Allow downloading the raw task reports and logs.

Francois Gouget fgouget at codeweavers.com
Wed Oct 2 00:02:08 CDT 2019


This can make analysis easier or allow processing through scripts to
derive statistics.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---

In particular, while the full test suite reports are normally available 
through test.winehq.org, that's not the case when they time out. In such 
a case being able to download and grep through the report can be useful.

 testbot/web/GetTaskFile.pl | 79 ++++++++++++++++++++++++++++++++++++++
 testbot/web/JobDetails.pl  | 14 +++++--
 2 files changed, 90 insertions(+), 3 deletions(-)
 create mode 100644 testbot/web/GetTaskFile.pl

diff --git a/testbot/web/GetTaskFile.pl b/testbot/web/GetTaskFile.pl
new file mode 100644
index 000000000..83e723e47
--- /dev/null
+++ b/testbot/web/GetTaskFile.pl
@@ -0,0 +1,79 @@
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# Sends a Task's report or log file
+#
+# Copyright 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+use warnings;
+use strict;
+
+use Apache2::Const -compile => qw(REDIRECT);
+use CGI;
+use Fcntl; # for O_READONLY
+use WineTestBot::Config;
+
+
+sub SendTaskFile($$$$$)
+{
+  my ($Request, $JobId, $StepNo, $TaskNo, $File) = @_;
+
+  # Validate and untaint
+  return undef if ($JobId !~ m/^(\d+)$/);
+  $JobId = $1;
+  return undef if ($StepNo !~ m/^(\d+)$/);
+  $StepNo = $1;
+  return undef if ($TaskNo !~ m/^(\d+)$/);
+  $TaskNo = $1;
+  return undef if ($File !~ m/^(log|[a-zA-Z0-9_-]+\.report)$/);
+  $File = $1;
+
+  my $FileName = "$DataDir/jobs/$JobId/$StepNo/$TaskNo/$File";
+  if (sysopen(my $fh, $FileName, O_RDONLY))
+  {
+    my ($FileSize, $MTime, $BlkSize) = (stat($fh))[7, 9, 11];
+
+    $Request->headers_out->add("Last-Modified", scalar(gmtime($MTime)) ." GMT");
+    $Request->content_type("text/plain");
+    $Request->headers_out->add("Content-length", $FileSize);
+    $Request->headers_out->add("Content-Disposition",
+                               "attachment; filename='$File'");
+
+    $BlkSize ||= 16384;
+    print $_ while (sysread($fh, $_, $BlkSize));
+    close($fh);
+
+    return 1;
+  }
+
+  return undef;
+}
+
+
+my $Request = shift;
+
+my $CGIObj = CGI->new($Request);
+my $JobId = $CGIObj->param("Job") || "";
+my $StepNo = $CGIObj->param("Step") || "";
+my $TaskNo = $CGIObj->param("Task") || "";
+my $File = $CGIObj->param("File") || "";
+
+if (!SendTaskFile($Request, $JobId, $StepNo, $TaskNo, $File))
+{
+  $Request->headers_out->set("Location", "/");
+  $Request->status(Apache2::Const::REDIRECT);
+}
+
+exit;
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 8d878805a..fc98e14b0 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -321,14 +321,22 @@ sub GetMoreInfoLink($$$$;$)
   return ($Action, $Url);
 }
 
-sub GenerateMoreInfoLink($$$$;$)
+sub GenerateMoreInfoLink($$$$;$$)
 {
-  my ($self, $LinkKey, $Label, $Set, $Value) = @_;
+  my ($self, $LinkKey, $Label, $Set, $Value, $StepTask) = @_;
 
   my ($Action, $Url) = $self->GetMoreInfoLink($LinkKey, $Label, $Set, $Value);
   my $Title = ($Value =~ /^(.*)\.report$/) ? " title='$1'" : "";
 
   my $Html = "<a href='". $self->CGI->escapeHTML($Url) ."'$Title>$Action $Label</a>";
+  if (defined $Value)
+  {
+    $Url = "/GetTaskFile.pl?Job=". uri_escape($self->{JobId})
+           ."&Step=". uri_escape($StepTask->StepNo)
+           ."&Task=". uri_escape($StepTask->TaskNo)
+           ."&File=". uri_escape($Value);
+    $Html = "<a href='$Url'>↓</a> $Html";
+  }
   if ($Action eq "Hide")
   {
     $Html = "<span class='TaskMoreInfoSelected'>$Html</span>";
@@ -442,7 +450,7 @@ EOF
     my $ReportCount;
     foreach my $LogName (@{$MoreInfo->{Logs}})
     {
-      $self->GenerateMoreInfoLink($Key, GetLogLabel($LogName), "Full", $LogName);
+      $self->GenerateMoreInfoLink($Key, GetLogLabel($LogName), "Full", $LogName, $StepTask);
       $ReportCount++ if ($LogName !~ /^old_/ and $LogName =~ /\.report$/);
     }
     print "</div>\n";
-- 
2.20.1



More information about the wine-devel mailing list