File Coverage

blib/lib/App/TestOnTap/ParallelGroupManager.pm
Criterion Covered Total %
statement 30 54 55.5
branch 2 14 14.2
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 39 77 50.6


line stmt bran cond sub pod time code
1             package App::TestOnTap::ParallelGroupManager;
2              
3 19     19   136 use strict;
  19         48  
  19         563  
4 19     19   95 use warnings;
  19         46  
  19         1010  
5              
6             our $VERSION = '1.001';
7             my $version = $VERSION;
8             $VERSION = eval $VERSION;
9              
10 19     19   113 use Grep::Query;
  19         41  
  19         722  
11 19     19   10364 use List::MoreUtils qw(singleton);
  19         227682  
  19         123  
12              
13             # CTOR
14             #
15             sub new
16             {
17 27     27 0 109 my $class = shift;
18 27         83 my $cfg = shift;
19              
20 27         138 my $self = bless( {}, $class);
21 27         297 $self->__parseParallelGroups($cfg);
22            
23 27         109 return $self;
24             }
25              
26             sub cull
27             {
28 55     55 0 227 my $self = shift;
29 55         208 my $inprogress = shift;
30 55         132 my $eligible = shift;
31              
32 55 100       276 return () unless @$eligible;
33            
34 2         4 foreach my $pgname (sort(keys(%{$self->{pargroups}})))
  2         11  
35             {
36 0         0 my $matcher = $self->{pargroups}->{$pgname}->{match};
37 0         0 my $maxconcurrent = $self->{pargroups}->{$pgname}->{maxconcurrent};
38            
39 0         0 my @matchingInprogress = $matcher->qgrep(@$inprogress);
40 0         0 my @matchingEligible = $matcher->qgrep(@$eligible);
41              
42 0         0 my @allmatching = (@matchingInprogress, @matchingEligible);
43 0         0 my $leave = scalar(@allmatching) - $maxconcurrent;
44 0 0       0 $leave = 0 if $leave < 0;
45 0         0 shift(@allmatching) while (@allmatching > $leave);
46 0         0 @$eligible = singleton(@allmatching, @$eligible);
47             }
48            
49 2         9 return @$eligible;
50             }
51              
52             sub __parseParallelGroups
53             {
54 27     27   68 my $self = shift;
55 27         57 my $cfg = shift;
56              
57 27         52 my %parGroups;
58             # find all parallelgroup sections
59             #
60 27         162 my $pgRx = qr(^\s*PARALLELGROUP\s+(.+?)\s*$);
61 27         273 foreach my $pgRuleSectionName (grep(/$pgRx/, keys(%$cfg)))
62             {
63 0         0 $pgRuleSectionName =~ /$pgRx/;
64 0         0 my $pgRuleName = $1;
65            
66             # all pg sections requires 'match' Grep::Query queries
67             # in case match is written as array, just join using newlines
68             #
69 0         0 my $match = $cfg->{$pgRuleSectionName}->{match};
70 0 0       0 die("Missing key 'match' in parallel group rule section '$pgRuleName'\n") unless defined($match);
71 0 0       0 $match = join("\n", @$match) if ref($match) eq 'ARRAY';
72 0         0 $parGroups{$pgRuleName}->{match} = Grep::Query->new($match);
73              
74             # all pg sections requires 'maxconcurrent' positive integer values
75             #
76 0         0 my $maxconcurrent = $cfg->{$pgRuleSectionName}->{maxconcurrent};
77 0 0       0 die("Missing key 'maxconcurrent' in parallel group rule section '$pgRuleName'\n") unless defined($maxconcurrent);
78 0 0       0 die("Illegal value for 'maxconcurrent' in parallel group rule section '$pgRuleName'\n") unless $maxconcurrent > 1;
79 0         0 $parGroups{$pgRuleName}->{maxconcurrent} = $maxconcurrent;
80            
81             # check for unknown keys...
82             #
83 0         0 my %validSectionKeys = map { $_ => 1 } qw(match maxconcurrent);
  0         0  
84 0         0 foreach my $key (keys(%{$cfg->{$pgRuleSectionName}}))
  0         0  
85             {
86 0 0       0 warn("WARNING: Unknown key '$key' in section '[$pgRuleSectionName]'\n") unless exists($validSectionKeys{$key});
87             }
88             }
89 27         245 $self->{pargroups} = \%parGroups;
90             }
91              
92             1;