[PATCH] testbot: Allow running Windows executables on the Wine VMs.

Francois Gouget fgouget at codeweavers.com
Tue Nov 27 17:27:29 CST 2018


Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 testbot/bin/WineRunWineTest.pl    | 17 +++---
 testbot/bin/build/WineReconfig.pl | 19 +++++--
 testbot/bin/build/WineTest.pl     | 59 ++++++++++++++++++---
 testbot/web/Submit.pl             | 87 ++++++++++++++++---------------
 4 files changed, 124 insertions(+), 58 deletions(-)

diff --git a/testbot/bin/WineRunWineTest.pl b/testbot/bin/WineRunWineTest.pl
index 592162ad7b..19e3e8f3eb 100755
--- a/testbot/bin/WineRunWineTest.pl
+++ b/testbot/bin/WineRunWineTest.pl
@@ -388,7 +388,7 @@ if ($Step->Type ne "suite" and $Step->Type ne "single")
   FatalError("Unexpected step type '". $Step->Type ."' found\n");
 }
 if (($Step->Type eq "suite" and $Step->FileType ne "none") or
-    ($Step->Type ne "suite" and $Step->FileType ne "patch"))
+    ($Step->Type ne "suite" and $Step->FileType !~ /^(?:exe32|exe64|patch)$/))
 {
   FatalError("Unexpected file type '". $Step->FileType ."' found for ". $Step->Type ." step\n");
 }
@@ -417,13 +417,14 @@ if (!$TA->SetTime())
   }
 }
 
-my $FileName = $Step->GetFullFileName();
+my $FileName = $Step->FileName;
 if (defined $FileName)
 {
   Debug(Elapsed($Start), " Sending '$FileName'\n");
-  if (!$TA->SendFile($FileName, "staging/patch.diff", 0))
+  my $Dst = $Step->FileType eq "patch" ? "patch.diff" : $FileName;
+  if (!$TA->SendFile($Step->GetFullFileName(), "staging/$Dst", 0))
   {
-    FatalTAError($TA, "Could not copy the patch to the VM");
+    FatalTAError($TA, "Could send '$FileName' to the VM");
   }
 }
 
@@ -452,10 +453,14 @@ if ($Step->Type eq "suite")
   }
   $Script .= join(" ", "-m", ShQuote($AdminEMail), "-i", ShQuote($Info));
 }
-else
+elsif ($Step->FileType eq "patch")
 {
   $Script .= "--testpatch ". $Task->Missions ." patch.diff";
 }
+else
+{
+  $Script .= join(" ", "--testexe", $Task->Missions, $FileName, $Task->CmdLineArg);
+}
 $Script .= "\n) >Task.log 2>&1\n";
 Debug(Elapsed($Start), " Sending the script: [$Script]\n");
 if (!$TA->SendFileFromString($Script, "task", $TestAgent::SENDFILE_EXE))
@@ -557,7 +562,7 @@ foreach my $Mission (@{$TaskMissions->{Missions}})
   {
     chmod 0664, "$TaskDir/$RptFileName";
 
-    my ($TestUnitCount, $TimeoutCount, $LogFailures, $LogErrors) = ParseWineTestReport("$TaskDir/$RptFileName", 1, $TaskTimedOut);
+    my ($TestUnitCount, $TimeoutCount, $LogFailures, $LogErrors) = ParseWineTestReport("$TaskDir/$RptFileName", $Step->FileType eq "patch", $TaskTimedOut);
     $TaskTimedOut = 1 if ($TestUnitCount == $TimeoutCount);
     if (!defined $LogFailures and @$LogErrors == 1)
     {
diff --git a/testbot/bin/build/WineReconfig.pl b/testbot/bin/build/WineReconfig.pl
index cc25da0cc8..77810958ab 100755
--- a/testbot/bin/build/WineReconfig.pl
+++ b/testbot/bin/build/WineReconfig.pl
@@ -49,9 +49,9 @@ use WineTestBot::Missions;
 # Build helpers
 #
 
-sub BuildWine($$$$)
+sub BuildWine($$$$;$)
 {
-  my ($TaskMissions, $NoRm, $Build, $Extras) = @_;
+  my ($TaskMissions, $NoRm, $Build, $Extras, $WithWine) = @_;
 
   return 1 if (!$TaskMissions->{Builds}->{$Build});
   mkdir "$DataDir/wine-$Build" if (!-d "$DataDir/wine-$Build");
@@ -60,6 +60,7 @@ sub BuildWine($$$$)
   # accumulate
   InfoMsg "\nRebuilding the $Build Wine\n";
   my $CPUCount = GetCPUCount();
+  $Extras .= " --with-wine64='$WithWine'" if (defined $WithWine);
   system("cd '$DataDir/wine-$Build' && set -x && ".
          ($NoRm ? "" : "rm -rf * && ") .
          "time ../wine/configure $Extras && ".
@@ -70,6 +71,18 @@ sub BuildWine($$$$)
     return !1;
   }
 
+  # Compile TestLauncher
+  my $Bits = ($Build =~ /64/) ? "64" : "32";
+  $WithWine ||= ".";
+  system("cd '$DataDir/wine-$Build' && set -x && ".
+         "gcc -m$Bits -c -o TestLauncher.o ../../src/TestLauncher/TestLauncher.c -fPIC -Iinclude -I../wine/include && ".
+         "'$WithWine/tools/winegcc/winegcc' -B'$WithWine/tools/winebuild' --sysroot=. -m$Bits -o TestLauncher.exe.so TestLauncher.o");
+  if ($? != 0)
+  {
+    LogMsg "The $Build TestLauncher build failed\n";
+    return !1;
+  }
+
   return 1;
 }
 
@@ -79,7 +92,7 @@ sub UpdateWineBuilds($$)
 
   return BuildWine($TaskMissions, $NoRm, "win32", "") &&
          BuildWine($TaskMissions, $NoRm, "wow64", "--enable-win64") &&
-         BuildWine($TaskMissions, $NoRm, "wow32", "--with-wine64='$DataDir/wine-wow64'");
+         BuildWine($TaskMissions, $NoRm, "wow32", "", "$DataDir/wine-wow64");
 }
 
 
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
index 23da71832c..b7389ba25e 100755
--- a/testbot/bin/build/WineTest.pl
+++ b/testbot/bin/build/WineTest.pl
@@ -180,6 +180,28 @@ sub TestPatch($$)
   return 1;
 }
 
+sub TestExe($$$)
+{
+  my ($Mission, $FileName, $Args) = @_;
+
+  my $BaseName = SetupTest("the tests", $Mission);
+  if (!-d $ENV{WINEPREFIX})
+  {
+    # FIXME Wait for the wineserver as a workaround for bug 41713.
+    my $ErrMessage = CreateWinePrefix($Mission, "wait");
+    if (defined $ErrMessage)
+    {
+      LogMsg "Could not create the $BaseName wineprefix: $ErrMessage\n";
+      return 0;
+    }
+  }
+
+  # Run the test executable
+  RunWine($Mission, "./TestLauncher.exe.so", "-t 120 ". ShArgv2Cmd($FileName, @$Args) ." >'../$BaseName.report'");
+
+  return 1;
+}
+
 
 #
 # Setup and command line processing
@@ -193,7 +215,11 @@ my ($Usage, $OptNoSubmit, $MissionStatement, $FileName, $BaseTag);
 while (@ARGV)
 {
   my $Arg = shift @ARGV;
-  if ($Arg eq "--testpatch")
+  if ($Arg eq "--testexe")
+  {
+    $Action = "testexe";
+  }
+  elsif ($Arg eq "--testpatch")
   {
     $Action = "testpatch";
   }
@@ -243,6 +269,11 @@ while (@ARGV)
       $Usage = 2;
       last;
     }
+    if ($Action eq "testexe")
+    {
+      # The remainder are the executable's arguments
+      last;
+    }
   }
   else
   {
@@ -319,10 +350,18 @@ if (!defined $Usage)
     }
   }
 
-  if (!defined $FileName and $Action eq "testpatch")
+  if (!defined $FileName)
   {
-    Error "you must provide a patch to test\n";
-    $Usage = 2;
+    if ($Action eq "testexe")
+    {
+      Error "you must provide an executable to run\n";
+      $Usage = 2;
+    }
+    elsif ($Action eq "testpatch")
+    {
+      Error "you must provide a patch to test\n";
+      $Usage = 2;
+    }
   }
 }
 if (defined $Usage)
@@ -333,12 +372,14 @@ if (defined $Usage)
     Error "try '$Name0 --help' for more information\n";
     exit $Usage;
   }
-  print "Usage: $Name0 [--help] --testpatch MISSIONS PATCH\n";
+  print "Usage: $Name0 [--help] --testexe MISSIONS EXE ARGS...\n";
+  print "or     $Name0 [--help] --testpatch MISSIONS PATCH\n";
   print "or     $Name0 [--help] --winetest [--no-submit] MISSIONS BASETAG ARGS\n";
   print "\n";
   print "Tests the specified patch or runs WineTest in Wine.\n";
   print "\n";
   print "Where:\n";
+  print "  --testexe    Run the executable in Wine.\n";
   print "  --testpatch  Verify that the patch compiles and run the impacted tests.\n";
   print "  --winetest   Run WineTest and submit the result to the website.\n";
   print "  --no-submit  Do not submit the WineTest results to the website.\n";
@@ -346,6 +387,8 @@ if (defined $Usage)
   print "               - win32: The regular 32 bit Wine build.\n";
   print "               - wow32: The 32 bit WoW Wine build.\n";
   print "               - wow64: The 64 bit WoW Wine build.\n";
+  print "  EXE          Is the staging file containing the executable to run.\n";
+  print "  ARGS         Are the arguments for the test executable.\n";
   print "  PATCH        Is the staging file containing the patch to test.\n";
   print "  BASETAG      Is the tag for this WineTest run. Note that the build type is\n";
   print "               automatically added to this tag.\n";
@@ -379,7 +422,11 @@ if ($Action eq "testpatch")
 }
 foreach my $Mission (@{$TaskMissions->{Missions}})
 {
-  if ($Action eq "testpatch")
+  if ($Action eq "testexe")
+  {
+    exit(1) if (!TestExe($Mission, $FileName, \@ARGV));
+  }
+  elsif ($Action eq "testpatch")
   {
     exit(1) if (!TestPatch($Mission, $Impacts));
   }
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index 3b7da0636f..5c40ef5046 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -243,11 +243,7 @@ sub GenerateFields($)
       my $VMs = CreateVMs();
       if ($self->{FileType} eq "exe64")
       {
-          $VMs->AddFilter("Type", ["win64"]);
-      }
-      elsif ($self->{FileType} eq "exe32")
-      {
-          $VMs->AddFilter("Type", ["win32", "win64"]);
+          $VMs->AddFilter("Type", ["win64", "wine"]);
       }
       else
       {
@@ -808,7 +804,7 @@ sub SubmitJob($$$)
           if (!defined $ErrMessage)
           {
             $Task->Timeout(GetBuildTimeout($Impacts, $Missions->[0]));
-            $Task->Missions($Missions->[0]);
+            $Task->Missions($MissionStatement);
 
             # Save the build step so the others can reference it
             (my $ErrKey, my $ErrProperty, $ErrMessage) = $Jobs->Save();
@@ -849,49 +845,54 @@ sub SubmitJob($$$)
     }
   }
 
-  if ($FileType eq "patch")
+  my ($Tasks, $MissionStatement, $Timeout);
+  my $VMs = CreateVMs();
+  $VMs->AddFilter("Type", ["wine"]);
+  my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
+  foreach my $VMKey (@$SortedKeys)
   {
-    my ($Tasks, $MissionStatement, $Timeout);
-    my $VMs = CreateVMs();
-    $VMs->AddFilter("Type", ["wine"]);
-    my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
-    foreach my $VMKey (@$SortedKeys)
-    {
-      my $VM = $VMs->GetItem($VMKey);
-      my $FieldName = "vm_" . $self->CGI->escapeHTML($VMKey);
-      next if (!$self->GetParam($FieldName)); # skip unselected VMs
+    my $VM = $VMs->GetItem($VMKey);
+    my $FieldName = "vm_" . $self->CGI->escapeHTML($VMKey);
+    next if (!$self->GetParam($FieldName)); # skip unselected VMs
 
-      if (!$Tasks)
+    if (!$Tasks)
+    {
+      # First create the Wine test step
+      my $WineStep = $Steps->Add();
+      $WineStep->FileName($BaseName);
+      $WineStep->FileType($FileType);
+      $WineStep->Type("single");
+      $WineStep->DebugLevel($self->GetParam("DebugLevel"));
+      $WineStep->ReportSuccessfulTests(defined($self->GetParam("ReportSuccessfulTests")));
+      $Tasks = $WineStep->Tasks;
+
+      $MissionStatement = ($FileType =~ /^(?:exe32|patch)$/) ? "win32" : "";
+      if ($FileType eq "exe64" or
+          ($FileType eq "patch" and defined $self->GetParam("Run64")))
       {
-        # First create the Wine test step
-        my $WineStep = $Steps->Add();
-        $WineStep->FileName($BaseName);
-        $WineStep->FileType($FileType);
-        $WineStep->Type("single");
-        $WineStep->DebugLevel($self->GetParam("DebugLevel"));
-        $WineStep->ReportSuccessfulTests(defined($self->GetParam("ReportSuccessfulTests")));
-        $Tasks = $WineStep->Tasks;
-
-        $MissionStatement = "win32";
-        $MissionStatement.= ":wow64" if (defined $self->GetParam("Run64"));
-
-        my ($ErrMessage, $Missions) = ParseMissionStatement($MissionStatement);
-        if (defined $ErrMessage)
-        {
-          $self->{ErrMessage} = $ErrMessage;
-          return !1;
-        }
-        $Missions = $Missions->[0];
-        $Timeout = GetBuildTimeout($Impacts, $Missions) +
-                   GetTestTimeout($Impacts, $Missions);
+        $MissionStatement .= ":wow64";
       }
+      $MissionStatement =~ s/^://;
 
-      # Then add a task for this VM
-      my $Task = $Tasks->Add();
-      $Task->VM($VM);
-      $Task->Timeout($Timeout);
-      $Task->Missions($MissionStatement);
+      my ($ErrMessage, $Missions) = ParseMissionStatement($MissionStatement);
+      if (defined $ErrMessage)
+      {
+        $self->{ErrMessage} = $ErrMessage;
+        return !1;
+      }
+      $Missions = $Missions->[0];
+      $Timeout = $FileType ne "patch" ?
+                 $SingleTimeout :
+                 GetBuildTimeout($Impacts, $Missions) +
+                 GetTestTimeout($Impacts, $Missions);
     }
+
+    # Then add a task for this VM
+    my $Task = $Tasks->Add();
+    $Task->VM($VM);
+    $Task->Timeout($Timeout);
+    $Task->Missions($MissionStatement);
+    $Task->CmdLineArg($self->GetParam("CmdLineArg")) if ($FileType ne "patch");
   }
 
   # Now save it all (or whatever's left to save)
-- 
2.19.1




More information about the wine-devel mailing list