This allows specifying extra builds or locales that a VM can handle, without having these used for every mailing list patch or WineTest run. The extra capabilities can then be used when manually scheduling a job on the TestBot.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47853 Signed-off-by: Francois Gouget fgouget@codeweavers.com ---
This patch requires updating the database schema by applying update42.sql. Note that the new MissionCaps field is defined as NOT NULL and in my tests mysql initialized it to empty strings.
The patch also requires restarting the web server and TestBot Engine.
testbot/ddl/update42.sql | 5 +++++ testbot/ddl/winetestbot.sql | 1 + testbot/doc/winetestbot-schema.dia | 23 +++++++++++++++++++++++ testbot/lib/WineTestBot/Missions.pm | 26 ++++++++++++++++++++++++-- testbot/lib/WineTestBot/VMs.pm | 10 +++++++++- testbot/web/Submit.pl | 2 +- testbot/web/admin/VMDetails.pl | 3 ++- 7 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 testbot/ddl/update42.sql
diff --git a/testbot/ddl/update42.sql b/testbot/ddl/update42.sql new file mode 100644 index 0000000000..f38833e3da --- /dev/null +++ b/testbot/ddl/update42.sql @@ -0,0 +1,5 @@ +USE winetestbot; + +ALTER TABLE VMs + ADD MissionCaps VARCHAR(512) NOT NULL + AFTER Missions; diff --git a/testbot/ddl/winetestbot.sql b/testbot/ddl/winetestbot.sql index e6114e0917..e1cb5714f3 100644 --- a/testbot/ddl/winetestbot.sql +++ b/testbot/ddl/winetestbot.sql @@ -49,6 +49,7 @@ CREATE TABLE VMs Type ENUM('win32', 'win64', 'build', 'wine') NOT NULL, Role ENUM('extra', 'base', 'winetest', 'retired', 'deleted') NOT NULL, Missions VARCHAR(256) NOT NULL, + MissionCaps VARCHAR(512) NOT NULL, Status ENUM('dirty', 'reverting', 'sleeping', 'idle', 'running', 'off', 'offline', 'maintenance') NOT NULL, Errors INT(2) NULL, ChildPid INT(5) NULL, diff --git a/testbot/doc/winetestbot-schema.dia b/testbot/doc/winetestbot-schema.dia index 372d3bf006..81ab656b7f 100644 --- a/testbot/doc/winetestbot-schema.dia +++ b/testbot/doc/winetestbot-schema.dia @@ -2406,6 +2406,29 @@ dia:string##</dia:string> </dia:attribute> </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#MissionCaps#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(512)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> <dia:composite type="table_attribute"> <dia:attribute name="name"> dia:string#Status#</dia:string> diff --git a/testbot/lib/WineTestBot/Missions.pm b/testbot/lib/WineTestBot/Missions.pm index 4f8387542f..810eb4dda4 100644 --- a/testbot/lib/WineTestBot/Missions.pm +++ b/testbot/lib/WineTestBot/Missions.pm @@ -142,9 +142,10 @@ sub GetTaskMissionDescription($$) return $Description; }
-sub GetMissionCaps($) +sub GetMissionCaps($$) { - my ($MissionStatement) = @_; + my ($MissionStatement, $MissionCaps) = @_; + my $Capabilities = { build => {}, lang => {} };
# Extract capabilities from the mission statement @@ -165,6 +166,27 @@ sub GetMissionCaps($) } } } + + # Parse the additional capabilities + foreach my $Capability (split /,/, $MissionCaps || "") + { + if ($Capability =~ s/^lang=//) + { + foreach my $Lang (split /[|]/, $Capability) + { + $Capabilities->{lang}->{$Lang} = 1; + } + } + elsif ($Capability =~ /^(?:win32|wow32|wow64)$/) + { + $Capabilities->{build}->{$Capability} = 1; + } + else + { + $ErrMessage ||= "Invalid option capability '$Capability'"; + } + } + if (%{$Capabilities->{lang}}) { # en_US is the default for Wine VMs and must always be supported diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm index 6c3c8b759f..6dd1ff2bb1 100644 --- a/testbot/lib/WineTestBot/VMs.pm +++ b/testbot/lib/WineTestBot/VMs.pm @@ -311,6 +311,7 @@ sub ResetModified($) $self->SUPER::ResetModified(); $self->{OldType} = $self->Type; $self->{OldMissions} = $self->Missions; + $self->{OldMissionCaps} = $self->MissionCaps; }
my $_SupportedMissions = { @@ -347,7 +348,8 @@ sub Validate($) return ("Role", "Only win32, win64 and wine VMs can have a role of '" . $self->Role . "'"); } if ($self->ValuesDiffer($self->{OldType}, $self->Type) or - $self->ValuesDiffer($self->{OldMissions}, $self->Missions)) + $self->ValuesDiffer($self->{OldMissions}, $self->Missions) or + $self->ValuesDiffer($self->{OldMissionCaps}, $self->MissionCaps)) { my ($ErrMessage, $Missions) = ParseMissionStatement($self->Missions); return ("Missions", $ErrMessage) if (defined $ErrMessage); @@ -366,8 +368,13 @@ sub Validate($) } } } + + ($ErrMessage, my $_Caps) = GetMissionCaps("", $self->MissionCaps); + return ("MissionCaps", $ErrMessage) if (defined $ErrMessage); + $self->{OldType} = $self->Type; $self->{OldMissions} = $self->Missions; + $self->{OldMissionCaps} = $self->MissionCaps; }
return $self->SUPER::Validate(); @@ -734,6 +741,7 @@ my @PropertyDescriptors = ( CreateEnumPropertyDescriptor("Type", "Type of VM", !1, 1, ['win32', 'win64', 'build', 'wine']), CreateEnumPropertyDescriptor("Role", "VM Role", !1, 1, ['extra', 'base', 'winetest', 'retired', 'deleted']), CreateBasicPropertyDescriptor("Missions", "Missions", !1, 1, "A", 256), + CreateBasicPropertyDescriptor("MissionCaps", "Mission Capabilities", !1, !1, "A", 512), CreateEnumPropertyDescriptor("Status", "Current status", !1, 1, ['dirty', 'reverting', 'sleeping', 'idle', 'running', 'off', 'offline', 'maintenance']), CreateBasicPropertyDescriptor("Errors", "Errors", !1, !1, "N", 2), CreateBasicPropertyDescriptor("ChildPid", "Child process id", !1, !1, "N", 5), diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl index f76ca6e1af..5e9a61e7c3 100644 --- a/testbot/web/Submit.pl +++ b/testbot/web/Submit.pl @@ -484,7 +484,7 @@ sub _initialize($$$) foreach my $VMKey (@$SortedKeys) { my $VM = $VMs->GetItem($VMKey); - my ($ErrMessage, $Caps) = GetMissionCaps($VM->Missions); + my ($ErrMessage, $Caps) = GetMissionCaps($VM->Missions, $VM->MissionCaps); LogMsg "$ErrMessage\n" if (defined $ErrMessage);
my @Builds = $VM->Type eq "wine" ? keys %{$Caps->{build}} : ("vm"); diff --git a/testbot/web/admin/VMDetails.pl b/testbot/web/admin/VMDetails.pl index 095de3a1eb..27ffd2f382 100644 --- a/testbot/web/admin/VMDetails.pl +++ b/testbot/web/admin/VMDetails.pl @@ -74,7 +74,7 @@ sub GenerateFooter($) print "<thead><tr><th class='Record'>Legend</th></tr></thead>\n"; print "<tbody><tr><td class='Record'>\n";
- print "<p>The Missions syntax is <i>mission1:mission2:...|mission3|...</i> where <i>mission1</i> and <i>mission2</i> will be run in the same task, and <i>mission3</i> in a separate task.<br>\n"; + print "<p>The <b>Missions</b> syntax is <i>mission1:mission2:...|mission3|...</i> where <i>mission1</i> and <i>mission2</i> will be run in the same task, and <i>mission3</i> in a separate task.<br>\n"; print "Each mission is composed of a build and options separated by commas: <i>build,option1=value,option2,...</i>. The value can be omitted for boolean options and defaults to true.<br>\n"; print "The supported builds are <i>build</i> for build VMs; <i>exe32</i> and <i>exe64</i> for Windows VMs;<i> win32</i>, <i>wow32</i> and <i>wow64</i> for Wine VMs.</p>\n"; print "<p>On Wine VMs:<br>\n"; @@ -82,6 +82,7 @@ sub GenerateFooter($) print "The <i>lang</i> option can be set to run the tests in the specified $LANG locale. The default is en_US (<i>.UTF-8</i> can be omitted).<br>\n"; print "The <i>dir</i> option can be set to specify the directory in which to run the tests. A path starting with a single letter followed by a slash specifies the drive, for instance 'c/' for 'c:' (the default).<br>\n"; print "If set, the <i>nosubmit</i> option specifies that the WineTest results should not be published online.</p>\n"; + print "<p>The <b>MissionCaps</b> syntax is <i>option1,option2=value1|value2,...</i> where <i>option1</i> is either a build or an option name, and <i>option2</i> is the name of an option that can be set to either <i>value1</i> or <i>value2</i>.<br>\n"; print "</td></tr></tbody>\n"; print "</table></div>\n"; $self->SUPER::GenerateFooter();