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   141 use strict;
  19         50  
  19         593  
4 19     19   107 use warnings;
  19         47  
  19         489  
5              
6 19     19   143 use Grep::Query;
  19         61  
  19         904  
7 19     19   10511 use List::MoreUtils qw(singleton);
  19         238235  
  19         120  
8              
9             # CTOR
10             #
11             sub new
12             {
13 27     27 0 351 my $class = shift;
14 27         229 my $cfg = shift;
15              
16 27         162 my $self = bless( {}, $class);
17 27         343 $self->__parseParallelGroups($cfg);
18            
19 27         121 return $self;
20             }
21              
22             sub cull
23             {
24 55     55 0 216 my $self = shift;
25 55         240 my $inprogress = shift;
26 55         167 my $eligible = shift;
27              
28 55 100       276 return () unless @$eligible;
29            
30 2         6 foreach my $pgname (sort(keys(%{$self->{pargroups}})))
  2         28  
31             {
32 0         0 my $matcher = $self->{pargroups}->{$pgname}->{match};
33 0         0 my $maxconcurrent = $self->{pargroups}->{$pgname}->{maxconcurrent};
34            
35 0         0 my @matchingInprogress = $matcher->qgrep(@$inprogress);
36 0         0 my @matchingEligible = $matcher->qgrep(@$eligible);
37              
38 0         0 my @allmatching = (@matchingInprogress, @matchingEligible);
39 0         0 my $leave = scalar(@allmatching) - $maxconcurrent;
40 0 0       0 $leave = 0 if $leave < 0;
41 0         0 shift(@allmatching) while (@allmatching > $leave);
42 0         0 @$eligible = singleton(@allmatching, @$eligible);
43             }
44            
45 2         13 return @$eligible;
46             }
47              
48             sub __parseParallelGroups
49             {
50 27     27   82 my $self = shift;
51 27         62 my $cfg = shift;
52              
53 27         55 my %parGroups;
54             # find all parallelgroup sections
55             #
56 27         178 my $pgRx = qr(^\s*PARALLELGROUP\s+(.+?)\s*$);
57 27         285 foreach my $pgRuleSectionName (grep(/$pgRx/, keys(%$cfg)))
58             {
59 0         0 $pgRuleSectionName =~ /$pgRx/;
60 0         0 my $pgRuleName = $1;
61            
62             # all pg sections requires 'match' Grep::Query queries
63             # in case match is written as array, just join using newlines
64             #
65 0         0 my $match = $cfg->{$pgRuleSectionName}->{match};
66 0 0       0 die("Missing key 'match' in parallel group rule section '$pgRuleName'\n") unless defined($match);
67 0 0       0 $match = join("\n", @$match) if ref($match) eq 'ARRAY';
68 0         0 $parGroups{$pgRuleName}->{match} = Grep::Query->new($match);
69              
70             # all pg sections requires 'maxconcurrent' positive integer values
71             #
72 0         0 my $maxconcurrent = $cfg->{$pgRuleSectionName}->{maxconcurrent};
73 0 0       0 die("Missing key 'maxconcurrent' in parallel group rule section '$pgRuleName'\n") unless defined($maxconcurrent);
74 0 0       0 die("Illegal value for 'maxconcurrent' in parallel group rule section '$pgRuleName'\n") unless $maxconcurrent > 1;
75 0         0 $parGroups{$pgRuleName}->{maxconcurrent} = $maxconcurrent;
76            
77             # check for unknown keys...
78             #
79 0         0 my %validSectionKeys = map { $_ => 1 } qw(match maxconcurrent);
  0         0  
80 0         0 foreach my $key (keys(%{$cfg->{$pgRuleSectionName}}))
  0         0  
81             {
82 0 0       0 warn("WARNING: Unknown key '$key' in section '[$pgRuleSectionName]'\n") unless exists($validSectionKeys{$key});
83             }
84             }
85 27         265 $self->{pargroups} = \%parGroups;
86             }
87              
88             1;