File Coverage

blib/lib/HPC/Runner/Command/stats.pm
Criterion Covered Total %
statement 27 84 32.1
branch 0 30 0.0
condition 0 21 0.0
subroutine 9 15 60.0
pod n/a
total 36 150 24.0


line stmt bran cond sub pod time code
1             package HPC::Runner::Command::stats;
2              
3 1     1   1309 use MooseX::App::Command;
  1         2  
  1         12  
4 1     1   14530 use Moose::Util qw/apply_all_roles/;
  1         2  
  1         10  
5             extends 'HPC::Runner::Command';
6              
7             with 'HPC::Runner::Command::Logger::JSON';
8             with 'HPC::Runner::Command::stats::Logger::JSON::Summary';
9             with 'HPC::Runner::Command::stats::Logger::JSON::Long';
10             with 'HPC::Runner::Command::Logger::Loggers';
11              
12 1     1   237 use JSON;
  1         2  
  1         11  
13 1     1   151 use File::Find::Rule;
  1         2  
  1         15  
14 1     1   72 use File::stat;
  1         2  
  1         10  
15 1     1   66 use File::Spec;
  1         2  
  1         24  
16 1     1   6 use Path::Tiny;
  1         2  
  1         46  
17 1     1   6 use File::Basename;
  1         2  
  1         50  
18 1     1   5 use Capture::Tiny ':all';
  1         2  
  1         944  
19              
20             command_short_description 'Query submissions by project, or jobname';
21             command_long_description 'Query submissions by project, or jobname. ' . 'This
22             searches through the tars created during execution.'
23             . ' If you have a large number
24             of submissions you may want to specify a project, '
25             . 'or supply the desired submission with --data_tar.';
26              
27             option 'most_recent' => (
28             is => 'rw',
29             isa => 'Bool',
30             required => 0,
31             default => 1,
32             documentation => q(Show only the most recent submission.),
33             trigger => sub {
34             my $self = shift;
35             $self->all(1) if !$self->most_recent;
36             }
37             );
38              
39             option 'all' => (
40             is => 'rw',
41             isa => 'Bool',
42             required => 0,
43             default => 0,
44             documentation => 'Show all submissions.',
45             trigger => sub {
46             my $self = shift;
47             $self->most_recent(1) if !$self->all;
48             },
49             cmd_aliases => ['a'],
50             );
51              
52             option '+project' => ( documentation => 'Query by project.', );
53              
54             option 'jobname' => (
55             is => 'rw',
56             isa => 'Str',
57             documentation => 'Query by jobname',
58             required => 0,
59             predicate => 'has_jobname',
60             );
61              
62             option 'summary' => (
63             is => 'rw',
64             isa => 'Bool',
65             documentation =>
66             'Summary view of your jobs - Number of running, completed, failed, successful.',
67             required => 0,
68             default => 1,
69             );
70              
71             option 'long' => (
72             is => 'rw',
73             isa => 'Bool',
74             documentation =>
75             'Long view. More detailed report - Task tags, exit codes, duration, etc.',
76             required => 0,
77             default => 0,
78             trigger => sub {
79             my $self = shift;
80             $self->summary(0) if $self->long;
81             },
82             cmd_aliases => ['l'],
83             );
84              
85             option 'json' => (
86             is => 'rw',
87             isa => 'Bool',
88             default => 0,
89             documentation => 'Output data in json instead of a table. '
90             . 'This option suppresses logging output.',
91             cmd_aliases => ['j'],
92             );
93              
94             has 'task_data' => (
95             is => 'rw',
96             isa => 'HashRef',
97             default => sub { {} },
98             clearer => 'clear_task_data',
99             );
100              
101             parameter 'stats_type' => (
102             is => 'rw',
103             isa => 'Str',
104             default => 'JSON',
105             documentation =>
106             'hpcrunner.pl stats JSON/Sqlite/Elasticsearch .',
107             );
108              
109             sub BUILD {
110 0     0     my $self = shift;
111              
112 0 0 0       if ( $self->json && $self->summary ) {
    0 0        
    0 0        
    0 0        
113 0           apply_all_roles( $self,
114             'HPC::Runner::Command::stats::Logger::'
115             . $self->stats_type
116             . '::Summary::JSONOutput' );
117             }
118             elsif ( !$self->json && $self->summary ) {
119 0           apply_all_roles( $self,
120             'HPC::Runner::Command::stats::Logger::'
121             . $self->stats_type
122             . '::Summary::TableOutput' );
123             }
124             elsif ( $self->json && $self->long ) {
125 0           apply_all_roles( $self,
126             'HPC::Runner::Command::stats::Logger::'
127             . $self->stats_type
128             . '::Long::JSONOutput' );
129             }
130             elsif ( !$self->json && $self->long ) {
131 0           apply_all_roles( $self,
132             'HPC::Runner::Command::stats::Logger::'
133             . $self->stats_type
134             . '::Long::TableOutput' );
135             }
136             }
137              
138             sub execute {
139 0     0     my $self = shift;
140              
141 0           $self->iter_submissions;
142             }
143              
144             sub iter_submissions {
145 0     0     my $self = shift;
146              
147 0           my $results = $self->get_submissions();
148              
149 0           foreach my $result ( @{$results} ) {
  0            
150 0           $self->clear_archive;
151 0           $self->data_tar($result);
152             capture {
153 0     0     $self->archive->read( $self->data_tar );
154 0           };
155 0           my $basename = $self->data_tar->basename('.tar.gz');
156 0           my $submission_file =
157             File::Spec->catdir( $basename, 'submission.json' );
158 0 0         if ( $self->archive->contains_file($submission_file) ) {
159 0           my $submission_json = $self->archive->get_content($submission_file);
160 0           my $submission = decode_json($submission_json);
161 0           my $jobref = $submission->{jobs};
162              
163 0 0         $self->iter_jobs_summary( $submission, $jobref )
164             if $self->summary;
165 0 0         $self->iter_jobs_long( $submission, $jobref ) if $self->long;
166             }
167             else {
168 0           $self->screen_log->info( 'Data Tar '
169             . $self->data_tar
170             . ' does not contain any submission info!' );
171             }
172             }
173              
174             }
175              
176             sub get_submissions {
177 0     0     my $self = shift;
178              
179             ## Skip over this searching nonsense
180 0           my $results;
181 0 0 0       if ( $self->has_data_tar && $self->data_tar->exists ) {
    0 0        
182 0           my $file = $self->data_tar;
183 0           $results = ["$file"];
184             }
185             elsif ( $self->has_data_tar && !$self->data_tar->exists ) {
186 0           $self->screen_log->fatal(
187             'You have supplied a data tar that does not exist.');
188 0           $self->screen_log->fatal(
189             'Data Tar ' . $self->data_tar . ' does not exist' );
190 0           exit 1;
191             }
192             else {
193 0           $results = $self->search_submission;
194             }
195              
196 0           return $results;
197             }
198              
199             sub search_submission {
200 0     0     my $self = shift;
201              
202 0           my $data_path = "";
203 0 0         if ( $self->project ) {
204 0           $data_path = File::Spec->catdir( $self->data_dir, $self->project );
205             }
206             else {
207 0           $data_path = File::Spec->catdir( $self->data_dir );
208             }
209              
210 0 0 0       if ( !path($data_path)->exists && path($data_path)->is_dir ) {
211 0           $self->screen_log->info( 'There is no data logged. '
212             . 'Please ensure you either in the project directory, '
213             . 'or that you have supplied --data_dir to the correct location.'
214             );
215             }
216              
217             ##TODO In the case of a lot of submissions - get the most recent directory
218 0           my @files = File::Find::Rule->file()->name('*.tar.gz')->in($data_path);
219 0 0         if ( !$self->json ) {
220 0           $self->screen_log->info( 'Found ' . scalar @files . ' submissions.' );
221 0 0         $self->screen_log->info('Reporting on the most recent.')
222             if $self->most_recent;
223 0 0         $self->screen_log->info('Reporting on all submissions.') if $self->all;
224             }
225              
226 0           my %stats = ();
227 0           map { my $st = stat($_); $stats{ $st->[9] } = $_ } @files;
  0            
  0            
228              
229 0           my @sorted_files = ();
230 0           foreach ( sort { $b <=> $a } keys(%stats) ) {
  0            
231 0           push( @sorted_files, $stats{$_} );
232 0 0         last if $self->most_recent;
233             }
234              
235 0           return \@sorted_files;
236             }
237              
238             __PACKAGE__->meta()->make_immutable();
239              
240             1;