Module: tools
Branch: master
Commit: 25d01cd2b4496290c5fc0b257e72efc04d2734f3
URL: http://source.winehq.org/git/tools.git/?a=commit;h=25d01cd2b4496290c5fc0b25…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Tue May 6 12:41:31 2014 +0200
testbot/lib: Pass the Step object to Task::Run() so it does not have to look it up.
---
testbot/lib/WineTestBot/Jobs.pm | 4 ++--
testbot/lib/WineTestBot/Tasks.pm | 16 ++++++----------
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/testbot/lib/WineTestBot/Jobs.pm b/testbot/lib/WineTestBot/Jobs.pm
index 8e36a32..b042bea 100644
--- a/testbot/lib/WineTestBot/Jobs.pm
+++ b/testbot/lib/WineTestBot/Jobs.pm
@@ -1,5 +1,5 @@
# Copyright 2009 Ge van Geldorp
-# Copyright 2012 Francois Gouget
+# Copyright 2012-2014 Francois Gouget
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -511,7 +511,7 @@ sub ScheduleOnHost($$$)
my ($ErrProperty, $ErrMessage) = $VM->Save();
return $ErrMessage if (defined $ErrMessage);
- $ErrMessage = $Task->Run($Job->Id, $Step->No);
+ $ErrMessage = $Task->Run($Step);
return $ErrMessage if (defined $ErrMessage);
$Job->UpdateStatus();
diff --git a/testbot/lib/WineTestBot/Tasks.pm b/testbot/lib/WineTestBot/Tasks.pm
index 28e0727..fd848f2 100644
--- a/testbot/lib/WineTestBot/Tasks.pm
+++ b/testbot/lib/WineTestBot/Tasks.pm
@@ -1,5 +1,5 @@
# Copyright 2009 Ge van Geldorp
-# Copyright 2012 Francois Gouget
+# Copyright 2012-2014 Francois Gouget
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -72,16 +72,13 @@ Where $Type corresponds to the Task's type.
=back
=cut
-sub Run
+sub Run($$)
{
- my $self = shift;
- my ($JobId, $StepNo) = @_;
+ my ($self, $Step) = @_;
$self->Status("running");
$self->Save();
- my $Job = WineTestBot::Jobs::CreateJobs()->GetItem($JobId);
- my $Step = $Job->Steps->GetItem($StepNo);
my $RunScript;
if ($Step->Type eq "build")
{
@@ -95,8 +92,6 @@ sub Run
{
$RunScript = "RunTask.pl";
}
- $Step = undef;
- $Job = undef;
$self->GetBackEnd()->PrepareForFork();
my $Pid = fork;
@@ -107,7 +102,8 @@ sub Run
elsif (!$Pid)
{
# Capture Perl errors in the task's generic error log
- my $TaskDir = "$DataDir/jobs/$JobId/$StepNo/" . $self->No;
+ my ($JobId, $StepNo, $TaskNo) = @{$self->GetMasterKey()};
+ my $TaskDir = "$DataDir/jobs/$JobId/$StepNo/$TaskNo";
mkdir $TaskDir;
unlink "$TaskDir/err"; # truncate the log since this is a new run
if (open(STDERR, ">>", "$TaskDir/err"))
@@ -123,7 +119,7 @@ sub Run
}
$ENV{PATH} = "/usr/bin:/bin";
delete $ENV{ENV};
- exec("$BinDir/${ProjectName}$RunScript", $JobId, $StepNo, $self->No) or
+ exec("$BinDir/${ProjectName}$RunScript", $JobId, $StepNo, $TaskNo) or
require WineTestBot::Log;
WineTestBot::Log::LogMsg("Unable to exec ${ProjectName}$RunScript: $!\n");
exit(1);
Module: tools
Branch: master
Commit: ad5dc5add5223edefd45ab693d238be5208b1c74
URL: http://source.winehq.org/git/tools.git/?a=commit;h=ad5dc5add5223edefd45ab69…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Tue May 6 12:40:49 2014 +0200
testbot/lib: Make sure we have a consistent view of the VMs Status, no matter which Task we get the corresponding object from.
This ensures we don't schedule two tasks on the same VM when there is more than one VM host.
Specifically, in the single VM host scenario the scheduler actions go
like this:
Schedule Jobs on Host1
Load Job1 from database
Load Step1 from database
Load Task1 from database
Load VM1 (e.g. buildvm) from database
VM1 is idle -> start Task1
VM1->Status = running
Save VM1 to the database
Load Job2 from database
Load Step2 from database
Load Task2 from database
Load VM2 (e.g. the same buildvm) from database
-> VM2->Status is up to date
VM2->Status is running -> nothing to do
All done
But in the two (or more) VM hosts scenario the first pass is when all
the objects are being loaded from database, while the second one just
reuses the already created Collections and Items. So in some cases
scheduling goes like this:
Schedule Jobs on Host1
Load Job1 from database
Load Step1 from database
Load Task1 from database
Load VM1 (e.g. buildvm) from database
VM1 is not on Host1 so continue
Load Job2 from database
Load Step2 from database
Load Task2 from database
Load VM2 (e.g. the same buildvm) from database
VM2 is not on Host1 so continue
Schedule Jobs on Host2
Job1 is already in memory
Step1 is already in memory
Task1 is already in memory
VM1 is already in memory
VM1 is idle -> start Task1
VM1->Status = running
Save VM1 to the database
Job2 is already in memory
Step2 is already in memory
Task2 is already in memory
VM2 is already in memory
-> VM2->Status has not been updated so
VM2->Status is still idle -> start Task2
-> Bug!!!
At this point we have two tasks trying to run on a single VM. When the
first one completes the VM gets powered off, leaving the second one
hanging.
With this patch VM1 and VM2 are the same object, and thus we
always have VM1->Status == VM2->Status which fixes this issue.
---
testbot/lib/WineTestBot/Jobs.pm | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/testbot/lib/WineTestBot/Jobs.pm b/testbot/lib/WineTestBot/Jobs.pm
index 1bf9de6..8e36a32 100644
--- a/testbot/lib/WineTestBot/Jobs.pm
+++ b/testbot/lib/WineTestBot/Jobs.pm
@@ -429,11 +429,12 @@ $MaxVMsWhenIdle VMs (or $MaxActiveVMs if not set) for future jobs.
=back
=cut
-sub ScheduleOnHost($$)
+sub ScheduleOnHost($$$)
{
- my ($SortedJobs, $Hypervisors) = @_;
+ my ($ScopeObject, $SortedJobs, $Hypervisors) = @_;
- my $HostVMs = CreateVMs();
+
+ my $HostVMs = CreateVMs($ScopeObject);
$HostVMs->FilterEnabledRole();
$HostVMs->FilterHypervisors($Hypervisors);
@@ -674,7 +675,7 @@ sub ScheduleJobs()
# we should check if there are VMs to revert
my %Hosts;
- my $VMs = CreateVMs();
+ my $VMs = CreateVMs($Jobs);
$VMs->FilterEnabledRole();
foreach my $VM (@{$VMs->GetItems()})
{
@@ -686,7 +687,7 @@ sub ScheduleJobs()
foreach my $Host (keys %Hosts)
{
my @HostHypervisors = keys %{$Hosts{$Host}};
- my $HostErrMessage = ScheduleOnHost(\@SortedJobs, \@HostHypervisors);
+ my $HostErrMessage = ScheduleOnHost($Jobs, \@SortedJobs, \@HostHypervisors);
push @ErrMessages, $HostErrMessage if (defined $HostErrMessage);
}
return @ErrMessages ? join("\n", @ErrMessages) : undef;
Module: tools
Branch: master
Commit: c1658af0dac543ad77c327eecb7216b8cadc0fdc
URL: http://source.winehq.org/git/tools.git/?a=commit;h=c1658af0dac543ad77c327ee…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Tue May 6 12:40:27 2014 +0200
testbot/lib: Make Collections try harder to return existing Item objects to avoid inconsistencies.
Assume we have the following code:
1: my $Jobs = CreateJobs();
2: my $VM1 = $Jobs->GetItem(100)->Steps->GetItem(1)->Tasks->GetItem(1)->VM;
3: my $VM2 = $Jobs->GetItem(101)->Steps->GetItem(1)->Tasks->GetItem(1)->VM;
4: my $VM2b = $Jobs->GetItem(101)->Steps->GetItem(1)->Tasks->GetItem(1)->VM;
5: print $VM1->Name, " is ", $VM1->Status, "\n"; # Prints 'buildvm is idle'
6: print $VM2->Name, " is ", $VM2->Status, "\n"; # Prints 'buildvm is idle'
7: $VM1->Status('running');
8: $VM1->Save();
9: print $VM1->Name, " is ", $VM1->Status, "\n"; # Prints 'buildvm is running'
10: print $VM2->Name, " is ", $VM2->Status, "\n"; # Prints 'buildvm is idle' !!!
11: print $VM2b->Name, " is ", $VM2b->Status, "\n"; # Prints 'buildvm is running'
The problem is that although $VM1, $VM2 and $VM2b refer to the same
VM (buildvm), they are all separate objects. Then $VM2->Status gets
loaded from the database for the print statement on line 6, and is
then never refreshed; hence the out-of-date value printed on line
10. In contrast $VM2b->Status is loaded from database for the print
statement on line 11 and thus shows the up-to-date value that was
saved on line 8. This is very confusing.
This patch associates a scope to each Collection and ensures that
there is no duplicate Item objects within that scope. Further, any
object created from a Collection inherits its scope. So in the example
above, because all objects can ultimately be traced back to the $Jobs
collection, $VM1, $VM2 and $VM2b all point to the same object which
avoids any inconsistency.
It's also possible to ensure that two Collections share the same scope
by passing the reference collection as a parameter. For instance, in
the above sample code, CreateVMs($Jobs)->GetItem('buildvm') will
return $VM1.
As before, creating a new Collection normally, CreateVMs() for
instance, ensures gets a new, empty, scope and thus reload the objects
from the database. This ensures the new objects will reflect changes
made to the database by other processes. This is also why having a
global persistent cache would not work.
---
testbot/bin/WineSendLog.pl | 2 +-
testbot/lib/ObjectModel/Collection.pm | 199 +++++++++++++++++++++++----
testbot/lib/ObjectModel/DBIBackEnd.pm | 10 +-
testbot/lib/ObjectModel/Item.pm | 27 +++-
testbot/lib/WineTestBot/Branches.pm | 6 +-
testbot/lib/WineTestBot/CGI/Sessions.pm | 5 +-
testbot/lib/WineTestBot/Jobs.pm | 6 +-
testbot/lib/WineTestBot/Patches.pm | 5 +-
testbot/lib/WineTestBot/PendingPatchSets.pm | 5 +-
testbot/lib/WineTestBot/PendingPatches.pm | 6 +-
testbot/lib/WineTestBot/Roles.pm | 5 +-
testbot/lib/WineTestBot/Steps.pm | 7 +-
testbot/lib/WineTestBot/StepsTasks.pm | 6 +-
testbot/lib/WineTestBot/Tasks.pm | 7 +-
testbot/lib/WineTestBot/UserRoles.pm | 7 +-
testbot/lib/WineTestBot/Users.pm | 6 +-
testbot/lib/WineTestBot/VMs.pm | 6 +-
testbot/web/JobDetails.pl | 2 +-
18 files changed, 250 insertions(+), 67 deletions(-)
Diff: http://source.winehq.org/git/tools.git/?a=commitdiff;h=c1658af0dac543ad77c3…
Module: tools
Branch: master
Commit: 8fee9165bb6b1026e8eaf3913098d9942e482cea
URL: http://source.winehq.org/git/tools.git/?a=commit;h=8fee9165bb6b1026e8eaf391…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Tue May 6 11:56:10 2014 +0200
testbot/VMs: Make sure the VM status has been set to 'reverting' before starting RevertVM.
---
testbot/lib/WineTestBot/VMs.pm | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index be95bcc..3c7f3fa 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -1,5 +1,5 @@
# Copyright 2009 Ge van Geldorp
-# Copyright 2012 Francois Gouget
+# Copyright 2012-2014 Francois Gouget
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -533,7 +533,8 @@ sub RunRevert
my $self = shift;
$self->Status("reverting");
- $self->Save();
+ my ($ErrProperty, $ErrMessage) = $self->Save();
+ return $ErrMessage if (defined $ErrMessage);
$self->GetBackEnd()->PrepareForFork();
my $Pid = fork;