File Coverage

blib/lib/App/Prove/Elasticsearch/Queue/Default.pm
Criterion Covered Total %
statement 92 93 98.9
branch 14 16 87.5
condition 3 6 50.0
subroutine 11 11 100.0
pod 5 5 100.0
total 125 131 95.4


line stmt bran cond sub pod time code
1             package App::Prove::Elasticsearch::Queue::Default;
2             $App::Prove::Elasticsearch::Queue::Default::VERSION = '0.001';
3              
4             # PODNAME: App::Prove::Elasticsearch::Queue::Default;
5             # ABSTRACT: Coordinate the running of test plans across multiple forks.
6              
7 2     2   82498 use strict;
  2         13  
  2         44  
8 2     2   8 use warnings;
  2         8  
  2         55  
9              
10 2     2   9 use List::Util 1.45 qw{shuffle uniq};
  2         40  
  2         143  
11 2     2   352 use App::Prove::Elasticsearch::Utils;
  2         3  
  2         1442  
12              
13             sub new {
14 1     1 1 108 my ($class, $input) = @_;
15 1         2 my $conf = App::Prove::Elasticsearch::Utils::process_configuration($input);
16              
17 1         9 my $planner = App::Prove::Elasticsearch::Utils::require_planner($conf);
18 1         3 &{\&{$planner . "::check_index"}}($conf);
  1         2  
  1         4  
19              
20 1         6 return bless({config => $conf, planner => $planner}, $class);
21             }
22              
23             sub get_jobs {
24 3     3 1 1149 my ($self, $jobspec) = @_;
25              
26 3         8 $self->_get_searcher();
27              
28 3         14 $jobspec->{searcher} = $self->{searcher};
29 3         6 my $plans = &{\&{$self->{planner} . "::get_plans_needing_work"}}(%$jobspec);
  3         4  
  3         13  
30 3 100       18 return () unless scalar(@$plans);
31              
32 2         3 my @tests;
33 2         4 foreach my $plan (@$plans) {
34             my @tmp_tests =
35 4 50       10 ref $plan->{tests} eq 'ARRAY' ? @{$plan->{tests}} : ($plan->{tests});
  4         8  
36 4         9 push(@tests, @tmp_tests);
37             }
38 2         13 @tests = shuffle($self->{searcher}->filter(uniq @tests));
39 2 100       47 return @tests unless $self->{config}->{'queue.granularity'};
40 1         3 @tests = splice(@tests, 0, $self->{config}->{'queue.granularity'});
41 1         5 return @tests;
42             }
43              
44             sub _get_indexer {
45 2     2   408 my $self = shift;
46             $self->{indexer} //=
47 2   66     10 App::Prove::Elasticsearch::Utils::require_indexer($self->{config});
48 2         10 return $self->{indexer};
49             }
50              
51             sub _get_searcher {
52 2     2   401 my $self = shift;
53 2 100       8 return $self->{searcher} if $self->{searcher};
54             my $searcher =
55 1         4 App::Prove::Elasticsearch::Utils::require_searcher($self->{config});
56              
57 1         3 $self->{searcher} = &{\&{$searcher . "::new"}}
  1         6  
58 1         6 ($searcher, $self->{config}, $self->_get_indexer());
59 1         5 return $self->{searcher};
60             }
61              
62             sub list_queues {
63 2     2 1 1217 my ($self, %matrix) = @_;
64 2         5 my $pf = [];
65 2         4 @$pf = grep { defined $_ } values(%{$matrix{cur_platforms}});
  4         11  
  2         7  
66 2         5 push(@$pf, @{$matrix{unsatisfiable_platforms}});
  2         5  
67             my %jobspec = (
68             version => $matrix{cur_version},
69 2         7 platforms => $pf,
70             searcher => $self->_get_searcher(),
71             );
72 2         15 my $plans = &{\&{$self->{planner} . "::get_plans_needing_work"}}(%jobspec);
  2         2  
  2         13  
73 2 100       25 return @$plans if @$plans;
74              
75             #construct iterator
76             my @pigeonholes =
77 2         7 map { $matrix{platforms}{$_} }
78 1         4 grep { scalar(@{$matrix{platforms}{$_}}) } keys(%{$matrix{platforms}});
  2         5  
  2         7  
  1         5  
79              
80 1         3 my @plots;
81 1         2 my @iterator = @{$pigeonholes[0]};
  1         4  
82 1         4 while (scalar(@iterator)) {
83 6         10 my $subj = shift @iterator;
84              
85             #Handle initial elements
86 6 100       13 $subj = [$subj] if ref $subj ne 'ARRAY';
87              
88             #Break out of the loop if we have no more possibilities to exploit
89 6 100       13 if (scalar(@$subj) == scalar(@pigeonholes)) {
90 4         5 push(@plots, $subj);
91 4         7 next;
92             }
93              
94             #Keep pushing partials on to the end of the iterator, until we run out of categories to add
95 2         4 foreach my $element (@{$pigeonholes[ scalar(@$subj) ]}) {
  2         5  
96 4         9 my @partial = @$subj;
97 4         7 push(@partial, $element);
98 4         12 push(@iterator, \@partial);
99             }
100             }
101 1         3 @plots = map { [ @$_, @{$matrix{'unsatisfiable_platforms'}} ] } @plots;
  4         5  
  4         9  
102              
103             #OK, now I have a list of potential platforms I can ask whether they exist
104 1         3 foreach my $gambit (@plots) {
105 1         2 $jobspec{platforms} = $gambit;
106 1         3 $plans = &{\&{$self->{planner} . "::get_plans_needing_work"}}(%jobspec);
  1         1  
  1         6  
107 1 50 33     16 return @$plans if (ref($plans) eq 'ARRAY') && @$plans;
108             }
109 0         0 return ();
110             }
111              
112             sub queue_jobs {
113 1     1 1 125 print "Queued local job.\n";
114 1         10 return 0;
115             }
116              
117             sub build_queue_name {
118 1     1 1 737 my ($self, $jobspec) = @_;
119 1         3 my $name = $jobspec->{version};
120 1         4 $name .= join('', @{$jobspec->{platforms}});
  1         5  
121 1         7 return $name;
122             }
123              
124             1;
125              
126             __END__