File Coverage

blib/lib/Tapper/CLI/Testplan.pm
Criterion Covered Total %
statement 29 154 18.8
branch 0 46 0.0
condition 0 9 0.0
subroutine 10 13 76.9
pod 3 3 100.0
total 42 225 18.6


line stmt bran cond sub pod time code
1             package Tapper::CLI::Testplan;
2             our $AUTHORITY = 'cpan:TAPPER';
3             # ABSTRACT: Handle testplans
4             $Tapper::CLI::Testplan::VERSION = '5.0.6';
5 1     1   904 use 5.010;
  1         4  
6 1     1   5 use warnings;
  1         2  
  1         27  
7 1     1   5 use strict;
  1         3  
  1         23  
8 1     1   449 use Perl6::Junction qw/all/;
  1         7128  
  1         67  
9 1     1   8 use English '-no_match_vars';
  1         3  
  1         5  
10 1     1   343 no if $] >= 5.018, warnings => "experimental";
  1         3  
  1         8  
11              
12 1     1   755 use JSON::XS;
  1         2668  
  1         59  
13 1     1   426 use YAML::XS;
  1         2710  
  1         676  
14              
15              
16              
17             sub testplanlist
18             {
19              
20 0     0 1   my ($c) = @_;
21 0           $c->getopt( 'name|n=s@', 'path|p=s@', 'testrun|t=s@', 'id|i=i@','active|a','verbose|v', 'format=s', 'help|?' );
22              
23 0 0         if ( $c->options->{help} ) {
24 0           say STDERR "Usage: $0 testplan-list [--path=path|-p=path]* [--name|-n=name]* [--testrun=id|-t=id]* [--id=number|-i=number] [--active|-a] [ --format=JSON|YAML ] [--verbose|-v]";
25 0           say STDERR "";
26 0           say STDERR " --path|-p Path name of testplans to list.";
27 0           say STDERR " Only slashes(/) are allowed as separators.";
28 0           say STDERR " Can be an SQL like condition (i.e. '\%name\%'). Make sure your shell does not break it.";
29 0           say STDERR " Can be given multiple times";
30 0           say STDERR " Will reduce number of testplans when given with --testrun or --name, can't go with --id";
31 0           say STDERR " --name|-n name of testplans to list.";
32 0           say STDERR " Can be an SQL like condition (i.e. '\%name\%'). Make sure your shell does not break it.";
33 0           say STDERR " Can be given multiple times";
34 0           say STDERR " Will reduce number of testplans when given with --testrun or --path, can't go with --id";
35 0           say STDERR " --testrun|-t Show testplan containing this testrun id";
36 0           say STDERR " Can be given multiple times";
37 0           say STDERR " Will reduce number of testplans when given with --name or --path, can't go with --id";
38 0           say STDERR " --id|-i Show testplan of given id";
39 0           say STDERR " Can be given multiple times. Implies -v";
40 0           say STDERR " Will override --testrun, --path and --name";
41 0           say STDERR " --active|-a Only show testplan with testruns that are not finished yet.";
42 0           say STDERR " Will reduce number of testplans when given with any other filter.";
43 0           say STDERR " --format Give output in this format. Valid values are YAML, JSON. Case insensitive. Always verbose.";
44 0           say STDERR " --verbose|-v Show testplan with id, name and associated testruns. Without only testplan id is shown.";
45 0           say STDERR " --help Print this help message and exit.";
46 0           exit -1;
47             }
48 0           my @ids;
49             my $filtered;
50 0           my $format = $c->options->{format};
51              
52 0           require Tapper::Model;
53 0 0         if (@{$c->options->{testrun} || []}) {
  0 0          
    0          
54 0           my $testruns = Tapper::Model::model('TestrunDB')->resultset('Testrun')->search({id => $c->options->{testrun}});
55 0           while (my $testrun = $testruns->next) {
56 0 0         push @ids, $testrun->testplan_id if $testrun->testplan_id;
57             }
58 0 0         } elsif ( @{$c->options->{name} || []}) {
59 0           my $regex = join("|", map { "($_)" } @{$c->options->{name}});
  0            
  0            
60 0           my $instances = Tapper::Model::model('TestrunDB')->resultset('TestplanInstance');
61 0           while (my $instance = $instances->next) {
62 0 0 0       push @ids, $instance->id if $instance->path and $instance->path =~ /$regex/;
63             }
64             } else {
65 0           my $instances = Tapper::Model::model('TestrunDB')->resultset('TestplanInstance');
66 0           while (my $instance = $instances->next) {
67 0           push @ids, $instance->id;
68             }
69 0           $c->options->{verbose} = 1;
70             }
71              
72             # a join would be faster and maybe cleaner
73 0 0         if ($c->options->{active}) {
74 0           my @local_ids = @ids;
75 0           my $instances = Tapper::Model::model('TestrunDB')->resultset('TestplanInstance')->search({id => \@local_ids});
76 0           @ids = ();
77 0           while (my $instance = $instances->next) {
78 0 0 0       if ($instance->testruns and grep {$_->testrun_scheduling->status ne 'finished'} $instance->testruns->all) {
  0            
79 0           push @ids, $instance->id;
80             }
81             }
82 0           $instances = Tapper::Model::model('TestrunDB')->resultset('TestplanInstance')->search({id => [ @ids ]});
83             }
84              
85 0 0         if ($c->options->{quiet}) {
86 0           return join ("\n",@ids);
87             }
88              
89 0           my %inst_data;
90 0           my $instances = Tapper::Model::model('TestrunDB')->resultset('TestplanInstance')->search({id => \@ids});
91 0           while (my $instance = $instances->next) {
92             $inst_data{$instance->id} =
93             {
94             path => $instance->path ? $instance->path : '',
95             name => $instance->path ? $instance->path : '',
96 0 0         testruns => [ map { {id => $_->id, status => ''.$_->testrun_scheduling->status} } $instance->testruns ], # stringify enum object
  0 0          
97             }
98             }
99 0 0         if ($c->options->{format}) {
100 1     1   8 use Data::Dumper;
  1         3  
  1         559  
101 0           given(lc($c->options->{format})) {
102 0           when ('yaml') { return YAML::XS::Dump(\%inst_data)}
  0            
103 0           when ('json') { return encode_json(\%inst_data)}
  0            
104 0           default { die "unknown format: ",$c->options->{format}}
  0            
105             }
106             } else {
107 0 0         if ($c->options->{verbose}) {
108 0           my @testplan_info;
109 0           foreach my $id (keys %inst_data) {
110             my $line = join(" - ",
111             $id,
112             $inst_data{$id}->{path},
113 0           "testruns: ".join(", ", map{$_->{id}} @{$inst_data{$id}->{testruns}})
  0            
  0            
114             );
115 0           push @testplan_info, $line;
116             }
117 0           return join "\n", @testplan_info;
118             } else {
119 0           return join "\n", map { $_->id} $instances->all;
  0            
120             }
121             }
122              
123             }
124              
125              
126             sub testplannew
127             {
128 0     0 1   my ($c) = @_;
129 0           $c->getopt( 'include|I=s@', 'name=s', 'path=s', 'file=s', 'D=s%', 'dryrun|n', 'guide|g', 'quiet|q', 'subst_json=s','verbose|v', 'help|?' );
130              
131 0           my $opt = $c->options;
132              
133 0 0 0       if ( $opt->{help} or not $opt->{file}) {
134 0           say STDERR "Usage: $0 testplan-new --file=s [ -dry-run|n ] [ -v ] [ -Dkey=value ] [ --path=s ] [ --name=s ] [ --include=s ]*";
135 0           say STDERR "";
136 0           say STDERR " -D Define a key=value pair used for macro expansion";
137 0           say STDERR " --dryrun Just print evaluated testplan without submit to DB";
138 0           say STDERR " --file Use (macro) testplan file";
139 0           say STDERR " --guide Just print self-documentation";
140 0           say STDERR " --include Add include directory (multiple allowed)";
141 0           say STDERR " --name Provide a name for this testplan instance";
142 0           say STDERR " --path Put this path into db instead of file path";
143 0           say STDERR " --subst_json File name that contains macro expansion values in JSON formaxt";
144 0           say STDERR " --verbose Show more progress output.";
145 0           say STDERR " --quiet Only show testplan ids, suppress path, name and testrun ids.";
146 0           say STDERR " --help Print this help message and exit.";
147 0           exit -1;
148             }
149              
150 0 0         die "Testplan file needed\n" if not $opt->{file};
151 0 0         die "Testplan file @{[ $opt->{file} ]} does not exist" if not -e $opt->{file};
  0            
152 0 0         die "Testplan file @{[ $opt->{file} ]} is not readable" if not -r $opt->{file};
  0            
153              
154 0           require Tapper::Cmd::Testplan;
155 0 0         if ($opt->{subst_json}) {
156 1     1   8 use File::Slurp;
  1         2  
  1         393  
157 0           my $data = File::Slurp::read_file($opt->{subst_json});
158 0           $opt->{substitutes} = JSON::XS::decode_json($data);
159             } else {
160 0           $opt->{substitutes} = $opt->{D};
161             }
162 0           my $cmd = Tapper::Cmd::Testplan->new;
163 0 0         if ($opt->{guide}) {
164 0           return $cmd->guide($opt->{file}, $opt->{substitutes}, $opt->{include});
165             }
166 0 0         if ($opt->{dryrun}) {
167 0           return $cmd->apply_macro($opt->{file}, $opt->{substitutes}, $opt->{include});
168             }
169              
170 0           my $answer = $cmd->testplannew($opt);
171             # Format:
172             # TESTPLANID: TESTRUNID TESTRUNID TESTRUNID
173             my $output =
174             $answer->{testplan_id}
175             . ': '
176 0 0         . join(' ', @{$answer->{testrun_ids} || []});
  0            
177              
178 0           return $output;
179             }
180              
181              
182              
183             sub setup
184             {
185 0     0 1   my ($c) = @_;
186 0           $c->register('testplan-send', \&testplansend, 'Send choosen testplan reports');
187 0           $c->register('testplan-list', \&testplanlist, 'List testplans matching a given pattern');
188 0           $c->register('testplan-tj-send', \&testplan_tj_send, 'Send all testplan reports that are due according to taskjuggler plan');
189 0           $c->register('testplan-tj-generate', \&testplan_tj_generate, 'Apply all testplans that are due according to taskjuggler plan');
190 0           $c->register('testplan-new', \&testplannew, 'Create new testplan instance from file');
191 0 0         if ($c->can('group_commands')) {
192 0           $c->group_commands('Testplan commands', 'testplan-send', 'testplan-list', 'testplan-tj-send', 'testplan-tj-generate', 'testplan-new');
193             }
194 0           return;
195             }
196              
197             1; # End of Tapper::CLI
198              
199             __END__
200              
201             =pod
202              
203             =encoding UTF-8
204              
205             =head1 NAME
206              
207             Tapper::CLI::Testplan - Handle testplans
208              
209             =head1 SYNOPSIS
210              
211             This module is part of the Tapper::CLI framework. It is supposed to be
212             used together with App::Rad. All following functions expect their
213             arguments as $c->options->{$arg}.
214              
215             use App::Rad;
216             use Tapper::CLI::Testplan;
217             Tapper::CLI::Testplan::setup($c);
218             App::Rad->run();
219              
220             =head1 NAME
221              
222             Tapper::CLI::Testplan - Tapper - testplan related commands for the tapper CLI
223              
224             =head1 FUNCTIONS
225              
226             =head2 testplanlist
227              
228             List testplans matching a given pattern.
229              
230             =head2 testplannew
231              
232             Create new testplan instance from file.
233              
234             =head2 setup
235              
236             Initialize the testplan functions for tapper CLI
237              
238             =head1 AUTHOR
239              
240             AMD OSRC Tapper Team <tapper@amd64.org>
241              
242             =head1 COPYRIGHT AND LICENSE
243              
244             This software is Copyright (c) 2020 by Advanced Micro Devices, Inc..
245              
246             This is free software, licensed under:
247              
248             The (two-clause) FreeBSD License
249              
250             =cut