| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# PODNAME: App::ape::plan |
|
2
|
|
|
|
|
|
|
# ABSTRACT: plan testing using elasticsearch |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package App::ape::plan; |
|
5
|
|
|
|
|
|
|
$App::ape::plan::VERSION = '0.001'; |
|
6
|
3
|
|
|
3
|
|
116998
|
use strict; |
|
|
3
|
|
|
|
|
13
|
|
|
|
3
|
|
|
|
|
74
|
|
|
7
|
3
|
|
|
3
|
|
12
|
use warnings; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
81
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
3
|
|
|
3
|
|
535
|
use Getopt::Long qw{GetOptionsFromArray}; |
|
|
3
|
|
|
|
|
8293
|
|
|
|
3
|
|
|
|
|
18
|
|
|
10
|
3
|
|
|
3
|
|
746
|
use App::Prove::Elasticsearch::Utils; |
|
|
3
|
|
|
|
|
28
|
|
|
|
3
|
|
|
|
|
72
|
|
|
11
|
3
|
|
|
3
|
|
1170
|
use App::Prove::State; |
|
|
3
|
|
|
|
|
29824
|
|
|
|
3
|
|
|
|
|
86
|
|
|
12
|
3
|
|
|
3
|
|
427
|
use Pod::Usage; |
|
|
3
|
|
|
|
|
35654
|
|
|
|
3
|
|
|
|
|
318
|
|
|
13
|
3
|
|
|
3
|
|
1975
|
use IO::Prompter [ -yesno, -single, -stdio, -style => 'bold' ]; |
|
|
3
|
|
|
|
|
74296
|
|
|
|
3
|
|
|
|
|
49
|
|
|
14
|
3
|
|
|
3
|
|
216
|
use List::Util qw{shuffle}; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
170
|
|
|
15
|
3
|
|
|
3
|
|
15
|
use File::Basename qw{basename}; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
132
|
|
|
16
|
3
|
|
|
3
|
|
14
|
use POSIX qw{strftime}; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
22
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub new { |
|
19
|
4
|
|
|
4
|
1
|
2382
|
my ($class, @args) = @_; |
|
20
|
|
|
|
|
|
|
|
|
21
|
4
|
|
|
|
|
7
|
my (%options, @conf, $help); |
|
22
|
|
|
|
|
|
|
GetOptionsFromArray( |
|
23
|
|
|
|
|
|
|
\@args, |
|
24
|
|
|
|
|
|
|
'platform=s@' => \$options{platforms}, |
|
25
|
|
|
|
|
|
|
'version=s' => \$options{version}, |
|
26
|
|
|
|
|
|
|
'show' => \$options{show}, |
|
27
|
|
|
|
|
|
|
'prompt' => \$options{prompt}, |
|
28
|
|
|
|
|
|
|
'pairwise' => \$options{pairwise}, |
|
29
|
|
|
|
|
|
|
'all-platforms' => \$options{allplatforms}, |
|
30
|
|
|
|
|
|
|
'recurse' => \$options{recurse}, |
|
31
|
|
|
|
|
|
|
'extension=s@' => \$options{exts}, |
|
32
|
|
|
|
|
|
|
'name' => \$options{name}, |
|
33
|
|
|
|
|
|
|
'requeue' => \$options{requeue}, |
|
34
|
|
|
|
|
|
|
'replay' => \$options{replay}, |
|
35
|
4
|
|
|
|
|
37
|
'help' => \$help, |
|
36
|
|
|
|
|
|
|
); |
|
37
|
4
|
|
100
|
|
|
2694
|
$options{platforms} //= []; |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
#Deliberately exiting here, as I "unit" test this as the binary |
|
40
|
4
|
50
|
|
|
|
9
|
pod2usage(0) if $help; |
|
41
|
|
|
|
|
|
|
|
|
42
|
4
|
100
|
|
|
|
8
|
if (!$options{version}) { |
|
43
|
1
|
|
|
|
|
7
|
pod2usage( |
|
44
|
|
|
|
|
|
|
-exitval => "NOEXIT", |
|
45
|
|
|
|
|
|
|
-msg => "Insufficient arguments. You must pass --version.", |
|
46
|
|
|
|
|
|
|
); |
|
47
|
1
|
|
|
|
|
4732
|
return 2; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
3
|
50
|
66
|
|
|
10
|
if ($options{prompt} && $options{show}) { |
|
51
|
1
|
|
|
|
|
4
|
pod2usage( |
|
52
|
|
|
|
|
|
|
-exitval => "NOEXIT", |
|
53
|
|
|
|
|
|
|
-msg => |
|
54
|
|
|
|
|
|
|
"--prompt and --show are mutually exclusive options. You must pass one or the other.", |
|
55
|
|
|
|
|
|
|
); |
|
56
|
1
|
|
|
|
|
4221
|
return 3; |
|
57
|
|
|
|
|
|
|
} |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
#Store platform groups in the configuration to differentiate further plans |
|
60
|
2
|
|
|
|
|
5
|
my $conf = App::Prove::Elasticsearch::Utils::process_configuration(@conf); |
|
61
|
|
|
|
|
|
|
|
|
62
|
2
|
100
|
|
|
|
12
|
if ( |
|
63
|
|
|
|
|
|
|
scalar( |
|
64
|
|
|
|
|
|
|
grep { |
|
65
|
2
|
|
|
|
|
3
|
my $subj = $_; |
|
66
|
2
|
|
|
|
|
4
|
grep { $subj eq $_ } qw{server.host server.port} |
|
|
4
|
|
|
|
|
8
|
|
|
67
|
|
|
|
|
|
|
} keys(%$conf) |
|
68
|
|
|
|
|
|
|
) != 2 |
|
69
|
|
|
|
|
|
|
) { |
|
70
|
1
|
|
|
|
|
5
|
pod2usage( |
|
71
|
|
|
|
|
|
|
-exitval => "NOEXIT", |
|
72
|
|
|
|
|
|
|
-msg => |
|
73
|
|
|
|
|
|
|
"Insufficient information provided to associate defect with test results to elasticsearch", |
|
74
|
|
|
|
|
|
|
); |
|
75
|
1
|
|
|
|
|
4156
|
return 4; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
1
|
|
|
|
|
2
|
my $self = {}; |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
#default platforms to whatever platformer can figure out |
|
81
|
1
|
0
|
33
|
|
|
1
|
if (!scalar(@{$options{platforms}}) && !$options{allplatforms}) { |
|
|
1
|
|
|
|
|
6
|
|
|
82
|
0
|
|
|
|
|
0
|
my $platformer = |
|
83
|
|
|
|
|
|
|
App::Prove::Elasticsearch::Utils::require_platformer($conf); |
|
84
|
0
|
|
|
|
|
0
|
$options{platforms} = &{\&{$platformer . "::get_platforms"}}(); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
1
|
|
|
|
|
3
|
$self->{planner} = App::Prove::Elasticsearch::Utils::require_planner($conf); |
|
88
|
1
|
|
|
|
|
5
|
&{\&{$self->{planner} . "::check_index"}}($conf); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
7
|
|
|
89
|
|
|
|
|
|
|
|
|
90
|
1
|
|
|
|
|
3
|
my $queue = App::Prove::Elasticsearch::Utils::require_queue($conf); |
|
91
|
1
|
|
|
|
|
3
|
$self->{queue} = &{\&{$queue . "::new"}}($queue, \@conf); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
5
|
|
|
92
|
1
|
|
|
|
|
14
|
$self->{queue}->{requeue} = $options{requeue}; |
|
93
|
|
|
|
|
|
|
|
|
94
|
1
|
|
|
|
|
4
|
$self->{searcher} = $self->{queue}->_get_searcher(); |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#Use Prove's arg parser to grab tests & globs correctly |
|
97
|
1
|
|
|
|
|
6
|
my $proveState = App::Prove::State->new(); |
|
98
|
1
|
50
|
|
|
|
7
|
$proveState->extensions($options{exts}) if $options{exts}; |
|
99
|
1
|
|
|
|
|
4
|
my @tests_filtered = $proveState->get_tests($options{'recurse'}, @args); |
|
100
|
1
|
|
|
|
|
6
|
@args = map { basename $_ } grep { -f $_ } @tests_filtered; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
101
|
1
|
|
|
|
|
2
|
$self->{cases} = \@args; |
|
102
|
|
|
|
|
|
|
|
|
103
|
1
|
|
|
|
|
2
|
$self->{conf} = $conf; |
|
104
|
1
|
|
|
|
|
2
|
$self->{options} = \%options; |
|
105
|
|
|
|
|
|
|
|
|
106
|
1
|
|
|
|
|
13
|
return bless($self, $class); |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub run { |
|
110
|
5
|
|
|
5
|
1
|
1787
|
my $self = shift; |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
my @plans = _build_plans( |
|
113
|
|
|
|
|
|
|
$self->{planner}, $self->{conf}, $self->{cases}, |
|
114
|
5
|
|
|
|
|
11
|
%{$self->{options}} |
|
|
5
|
|
|
|
|
18
|
|
|
115
|
|
|
|
|
|
|
); |
|
116
|
|
|
|
|
|
|
|
|
117
|
5
|
|
|
|
|
17
|
my $global_result = 0; |
|
118
|
5
|
|
|
|
|
6
|
my $queue_result = 0; |
|
119
|
5
|
|
|
|
|
17
|
foreach my $plan (@plans) { |
|
120
|
|
|
|
|
|
|
|
|
121
|
5
|
100
|
|
|
|
11
|
if ($self->{options}{show}) { |
|
122
|
1
|
50
|
|
|
|
4
|
$plan->{replay} = $self->{cases} if $self->{options}{replay}; |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
#Get the state of the plan |
|
125
|
1
|
|
|
|
|
2
|
$plan->{state} = []; |
|
126
|
1
|
|
|
|
|
3
|
@{$plan->{state}} = &{\&{$self->{planner} . "::get_plan_status"}} |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
127
|
1
|
|
|
|
|
2
|
($plan, $self->{searcher}); |
|
128
|
|
|
|
|
|
|
|
|
129
|
1
|
|
|
|
|
6
|
_print_plan($plan, 1); |
|
130
|
1
|
|
|
|
|
3
|
next; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
4
|
100
|
|
|
|
10
|
if ($self->{options}{prompt}) { |
|
133
|
3
|
|
|
|
|
6
|
_print_plan($plan); |
|
134
|
3
|
100
|
|
|
|
10
|
if (!$plan->{noop}) { |
|
135
|
2
|
50
|
|
|
|
3
|
IO::Prompter::prompt("Do you want to enact the above changes?") |
|
136
|
|
|
|
|
|
|
or next; |
|
137
|
|
|
|
|
|
|
} else { |
|
138
|
|
|
|
|
|
|
( |
|
139
|
|
|
|
|
|
|
IO::Prompter::prompt("Do you want to re-queue the plan?") |
|
140
|
|
|
|
|
|
|
or next |
|
141
|
1
|
50
|
50
|
|
|
4
|
) unless $self->{options}{requeue}; |
|
142
|
1
|
|
|
|
|
8
|
$self->{queue}->{requeue} = 1; |
|
143
|
1
|
|
|
|
|
4
|
$queue_result += $self->{queue}->queue_jobs($plan); |
|
144
|
1
|
|
|
|
|
3
|
next; |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
#Ensure bogus data doesn't get into ES |
|
149
|
3
|
|
|
|
|
9
|
delete $plan->{replay}; |
|
150
|
3
|
|
|
|
|
4
|
delete $plan->{requeue}; |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
$global_result += |
|
153
|
3
|
|
|
|
|
5
|
&{\&{$self->{planner} . "::add_plan_to_index"}}($plan); |
|
|
3
|
|
|
|
|
3
|
|
|
|
3
|
|
|
|
|
11
|
|
|
154
|
|
|
|
|
|
|
$queue_result += $self->{queue}->queue_jobs($plan) |
|
155
|
3
|
50
|
66
|
|
|
21
|
if !$plan->{noop} || $self->{options}{requeue}; |
|
156
|
|
|
|
|
|
|
} |
|
157
|
5
|
100
|
|
|
|
43
|
print "$global_result plans failed to be created, examine above output\n" |
|
158
|
|
|
|
|
|
|
if $global_result; |
|
159
|
5
|
100
|
|
|
|
16
|
print "$queue_result plans failed to be queued, examine above output\n" |
|
160
|
|
|
|
|
|
|
if $queue_result; |
|
161
|
5
|
100
|
|
|
|
28
|
return $global_result ? 2 : 0; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub _build_plans { |
|
165
|
0
|
|
|
0
|
|
0
|
my ($planner, $conf, $tests, %options) = @_; |
|
166
|
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
0
|
my @plans; |
|
168
|
0
|
|
|
|
|
0
|
my @pgroups = grep { $_ =~ m/PlatformGroups/ } keys(%$conf); |
|
|
0
|
|
|
|
|
0
|
|
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
#filter groups by what we actually passed, if we have any |
|
171
|
0
|
0
|
0
|
|
|
0
|
if (scalar(@{$options{platforms}}) && !$options{allplatforms}) { |
|
|
0
|
|
|
|
|
0
|
|
|
172
|
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
0
|
foreach my $grp (@pgroups) { |
|
174
|
0
|
|
|
|
|
0
|
@{$conf->{$grp}} = grep { |
|
175
|
0
|
|
|
|
|
0
|
my $grp = $_; |
|
176
|
0
|
|
|
|
|
0
|
grep { $grp eq $_ } @{$options{platforms}}; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
177
|
0
|
|
|
|
|
0
|
} @{$conf->{$grp}}; |
|
|
0
|
|
|
|
|
0
|
|
|
178
|
0
|
0
|
|
|
|
0
|
delete $conf->{$grp} unless scalar(@{$conf->{$grp}}); |
|
|
0
|
|
|
|
|
0
|
|
|
179
|
|
|
|
|
|
|
} |
|
180
|
0
|
|
|
|
|
0
|
@pgroups = grep { $_ =~ m/PlatformGroups/ } keys(%$conf); |
|
|
0
|
|
|
|
|
0
|
|
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
|
|
183
|
0
|
0
|
|
|
|
0
|
if (scalar(@pgroups)) { |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
#break out the groups depending if we are pairwise or not |
|
186
|
0
|
0
|
|
|
|
0
|
if ($options{pairwise}) { |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
#Randomize execution order |
|
189
|
0
|
|
|
|
|
0
|
@$tests = shuffle(@$tests); |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# The idea here is to have at least one pigeon in each hole. |
|
192
|
|
|
|
|
|
|
# This is accomplished by finding the longest list of groups, and then iterating over everything we have modulo their size. |
|
193
|
0
|
|
|
|
|
0
|
my $longest; |
|
194
|
0
|
|
|
|
|
0
|
foreach my $pgroup (@pgroups) { |
|
195
|
0
|
|
0
|
|
|
0
|
$longest ||= $pgroup; |
|
196
|
|
|
|
|
|
|
$longest = $pgroup |
|
197
|
0
|
0
|
|
|
|
0
|
if scalar(@{$conf->{$pgroup}}) > scalar(@{$conf->{$longest}}); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
0
|
my @last_tests_apportioned; |
|
201
|
0
|
|
|
|
|
0
|
for (my $i = 0; $i < scalar(@{$conf->{$longest}}); $i++) { |
|
|
0
|
|
|
|
|
0
|
|
|
202
|
0
|
|
|
|
|
0
|
my %cloned = %options; |
|
203
|
0
|
|
|
|
|
0
|
my @newplats; |
|
204
|
0
|
|
|
|
|
0
|
foreach my $pgroup (@pgroups) { |
|
205
|
0
|
|
|
|
|
0
|
my $idx = $i % scalar(@{$conf->{$pgroup}}); |
|
|
0
|
|
|
|
|
0
|
|
|
206
|
0
|
|
|
|
|
0
|
push(@newplats, $conf->{$pgroup}->[$idx]); |
|
207
|
|
|
|
|
|
|
} |
|
208
|
0
|
|
|
|
|
0
|
$cloned{platforms} = \@newplats; |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
#Figure out how many tests to dole out to the run |
|
211
|
0
|
|
|
|
|
0
|
my @tests_apportioned; |
|
212
|
|
|
|
|
|
|
my $tests_picked = |
|
213
|
0
|
|
|
|
|
0
|
int(scalar(@$tests) / scalar(@{$conf->{$longest}})); |
|
|
0
|
|
|
|
|
0
|
|
|
214
|
0
|
|
|
|
|
0
|
for (0 .. $tests_picked) { |
|
215
|
0
|
|
|
|
|
0
|
my $picked = shift @$tests; |
|
216
|
0
|
0
|
|
|
|
0
|
push(@tests_apportioned, $picked) if $picked; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
#Handle the corner case where we are passed less tests than we have platforms |
|
220
|
|
|
|
|
|
|
@tests_apportioned = @last_tests_apportioned |
|
221
|
0
|
0
|
|
|
|
0
|
if !scalar(@tests_apportioned); |
|
222
|
0
|
|
|
|
|
0
|
@last_tests_apportioned = @tests_apportioned; |
|
223
|
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
0
|
push( |
|
225
|
|
|
|
|
|
|
@plans, |
|
226
|
|
|
|
|
|
|
_build_plan($planner, \@tests_apportioned, %cloned) |
|
227
|
|
|
|
|
|
|
); |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
} else { |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
#construct iterator |
|
232
|
0
|
|
|
|
|
0
|
my @pigeonholes = map { $conf->{$_} } @pgroups; |
|
|
0
|
|
|
|
|
0
|
|
|
233
|
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
0
|
my @iterator = @{$pigeonholes[0]}; |
|
|
0
|
|
|
|
|
0
|
|
|
235
|
0
|
|
|
|
|
0
|
while (scalar(@iterator)) { |
|
236
|
0
|
|
|
|
|
0
|
my $subj = shift @iterator; |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
#Handle initial elements |
|
239
|
0
|
0
|
|
|
|
0
|
$subj = [$subj] if ref $subj ne 'ARRAY'; |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
#Break out of the loop if we have no more possibilities to exploit |
|
242
|
0
|
0
|
|
|
|
0
|
if (scalar(@$subj) == scalar(@pigeonholes)) { |
|
243
|
0
|
|
|
|
|
0
|
my %cloned = %options; |
|
244
|
0
|
|
|
|
|
0
|
$cloned{platforms} = $subj; |
|
245
|
0
|
|
|
|
|
0
|
push(@plans, _build_plan($planner, $tests, %cloned)); |
|
246
|
0
|
|
|
|
|
0
|
next; |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
#Keep pushing partials on to the end of the iterator, until we run out of categories to add |
|
250
|
0
|
|
|
|
|
0
|
foreach my $element (@{$pigeonholes[ scalar(@$subj) ]}) { |
|
|
0
|
|
|
|
|
0
|
|
|
251
|
0
|
|
|
|
|
0
|
my @partial = @$subj; |
|
252
|
0
|
|
|
|
|
0
|
push(@partial, $element); |
|
253
|
0
|
|
|
|
|
0
|
push(@iterator, \@partial); |
|
254
|
|
|
|
|
|
|
} |
|
255
|
|
|
|
|
|
|
} |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
} else { |
|
259
|
0
|
|
|
|
|
0
|
push(@plans, _build_plan($planner, $tests, %options)); |
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
#TODO inject creator & created time into plans |
|
263
|
|
|
|
|
|
|
@plans = |
|
264
|
0
|
|
|
|
|
0
|
map { $_->{created} = strftime("%Y-%m-%d %H:%M:%S", localtime()); $_ } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
265
|
|
|
|
|
|
|
@plans; |
|
266
|
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
0
|
return @plans; |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
sub _build_plan { |
|
271
|
2
|
|
|
2
|
|
2184
|
my ($planner, $tests, %options) = @_; |
|
272
|
2
|
|
|
|
|
5
|
$options{tests} = $tests; |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
#First, see if we already have a plan like this. |
|
275
|
2
|
|
|
|
|
3
|
my $existing = &{\&{$planner . "::get_plan"}}(%options); |
|
|
2
|
|
|
|
|
2
|
|
|
|
2
|
|
|
|
|
10
|
|
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
#If not, make the plan. Otherwise, construct the update statements needed to 'make it so'. |
|
278
|
2
|
100
|
|
|
|
11
|
if (!$existing) { |
|
279
|
1
|
|
|
|
|
2
|
$existing = &{\&{$planner . "::make_plan"}}(%options); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
280
|
|
|
|
|
|
|
} else { |
|
281
|
1
|
|
|
|
|
2
|
$existing = &{\&{$planner . "::make_plan_update"}}($existing, %options); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
282
|
|
|
|
|
|
|
} |
|
283
|
|
|
|
|
|
|
|
|
284
|
2
|
|
|
|
|
12
|
return $existing; |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub _print_plan { |
|
288
|
7
|
|
|
7
|
|
14266
|
my ($plan, $force) = @_; |
|
289
|
7
|
100
|
100
|
|
|
30
|
if (!$plan->{noop} || $force) { |
|
290
|
6
|
50
|
|
|
|
118
|
print "Name: $plan->{name}\n" if $plan->{name}; |
|
291
|
6
|
|
|
|
|
54
|
print "SUT version: $plan->{version}\n"; |
|
292
|
6
|
|
|
|
|
11
|
print "Platforms: " . join(', ', @{$plan->{platforms}}) . "\n"; |
|
|
6
|
|
|
|
|
46
|
|
|
293
|
|
|
|
|
|
|
print "Pairwise? " |
|
294
|
6
|
50
|
|
|
|
52
|
. ($plan->{pairwise} ne 'false' ? 'yes' : 'no') . "\n"; |
|
295
|
6
|
|
|
|
|
43
|
print "Created at $plan->{created}\n"; |
|
296
|
6
|
|
|
|
|
38
|
print "=========================\n"; |
|
297
|
6
|
100
|
|
|
|
19
|
if ($plan->{state}) { |
|
298
|
4
|
|
|
|
|
5
|
foreach my $t (@{$plan->{state}}) { |
|
|
4
|
|
|
|
|
10
|
|
|
299
|
8
|
50
|
66
|
|
|
23
|
if ($plan->{replay} && $t->{body}) { |
|
300
|
|
|
|
|
|
|
next |
|
301
|
2
|
|
|
|
|
6
|
if (scalar(@{$plan->{replay}}) |
|
302
|
2
|
50
|
33
|
|
|
3
|
&& !grep { $_ eq $t->{name} } @{$plan->{replay}}); |
|
|
4
|
|
|
|
|
11
|
|
|
|
2
|
|
|
|
|
4
|
|
|
303
|
2
|
|
|
|
|
34
|
print "\n$t->{name}..\n"; |
|
304
|
|
|
|
|
|
|
print "Test Version: $t->{test_version}\n" |
|
305
|
2
|
50
|
|
|
|
19
|
if $t->{test_version}; |
|
306
|
2
|
|
|
|
|
13
|
print "=========================\n"; |
|
307
|
2
|
|
|
|
|
15
|
print "$t->{body}"; |
|
308
|
|
|
|
|
|
|
} |
|
309
|
|
|
|
|
|
|
|
|
310
|
8
|
|
|
|
|
13
|
my $pln = ''; |
|
311
|
8
|
100
|
66
|
|
|
26
|
if ( ($t->{status} ne 'UNTESTED') |
|
312
|
|
|
|
|
|
|
&& (ref($t->{steps}) eq 'ARRAY')) { |
|
313
|
4
|
|
|
|
|
6
|
my $executed = scalar(@{$t->{steps}}); |
|
|
4
|
|
|
|
|
6
|
|
|
314
|
4
|
|
|
|
|
7
|
my $planned = $t->{steps_planned}; |
|
315
|
4
|
|
|
|
|
7
|
$pln = "$executed/$planned "; |
|
316
|
|
|
|
|
|
|
} |
|
317
|
8
|
|
|
|
|
92
|
printf "%-60s %-10s %s\n", $t->{name}, $pln, $t->{status}; |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
} else { |
|
320
|
2
|
|
|
|
|
3
|
foreach my $t (@{$plan->{tests}}) { |
|
|
2
|
|
|
|
|
5
|
|
|
321
|
4
|
|
|
|
|
28
|
print "$t\n"; |
|
322
|
|
|
|
|
|
|
} |
|
323
|
2
|
50
|
|
|
|
10
|
if ($plan->{update}) { |
|
324
|
2
|
50
|
|
|
|
6
|
if (ref $plan->{update}->{subtraction}->{tests} eq 'ARRAY') { |
|
325
|
2
|
|
|
|
|
14
|
print "\nRemove the following from the plan:\n"; |
|
326
|
2
|
|
|
|
|
12
|
print "=========================\n"; |
|
327
|
2
|
|
|
|
|
5
|
foreach my $t (@{$plan->{update}->{subtraction}->{tests}}) { |
|
|
2
|
|
|
|
|
5
|
|
|
328
|
2
|
|
|
|
|
13
|
print "$t\n"; |
|
329
|
|
|
|
|
|
|
} |
|
330
|
|
|
|
|
|
|
} |
|
331
|
2
|
50
|
|
|
|
9
|
if (ref $plan->{update}->{addition}->{tests} eq 'ARRAY') { |
|
332
|
2
|
|
|
|
|
13
|
print "\nAdd the following to the plan:\n"; |
|
333
|
2
|
|
|
|
|
13
|
print "=========================\n"; |
|
334
|
2
|
|
|
|
|
4
|
foreach my $t (@{$plan->{update}->{addition}->{tests}}) { |
|
|
2
|
|
|
|
|
5
|
|
|
335
|
2
|
|
|
|
|
24
|
print "$t\n"; |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
} |
|
338
|
|
|
|
|
|
|
} |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
} else { |
|
341
|
1
|
|
|
|
|
36
|
print "Plan already exists, and no updates will be made.\n"; |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
} |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
1; |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
__END__ |