File Coverage

blib/lib/Test/Reporter/Transport/Metabase/Fallback.pm
Criterion Covered Total %
statement 47 66 71.2
branch 8 20 40.0
condition 0 3 0.0
subroutine 10 10 100.0
pod 2 2 100.0
total 67 101 66.3


line stmt bran cond sub pod time code
1             package Test::Reporter::Transport::Metabase::Fallback;
2              
3             # $Id: Fallback.pm 54 2018-01-25 02:06:01Z stro $
4              
5 1     1   84099 use strict;
  1         3  
  1         23  
6 1     1   5 use warnings;
  1         1  
  1         25  
7 1     1   5 use parent 'Test::Reporter::Transport';
  1         2  
  1         4  
8              
9 1     1   505 use Carp;
  1         2  
  1         42  
10 1     1   4 use Test::Reporter;
  1         3  
  1         16  
11 1     1   427 use Test::Reporter::Transport::File;
  1         297  
  1         23  
12 1     1   368 use Test::Reporter::Transport::Metabase;
  1         76246  
  1         47  
13              
14             our $MAX_FILES = 25;
15              
16             BEGIN {
17 1     1   540 $Test::Reporter::Transport::Metabase::Fallback::VERSION = '1.001';
18             }
19              
20             my @metabase_required_args = ( 'uri', 'id_file' );
21             my @metabase_allowed_args = ( 'client', @metabase_required_args );
22             my @file_allowed_args = ( 'File' );
23             my @this_allowed_args = ( 'max_files' );
24              
25             sub new {
26 2     2 1 82972 my $class = shift;
27              
28 2 50       20 Carp::confess __PACKAGE__ . " requires transport args in key/value pairs\n" if @_ % 2;
29 2         23 my %args = @_;
30              
31 2         14 foreach my $k ( @metabase_required_args ) {
32 4 50       20 Carp::confess __PACKAGE__ . " requires $k argument\n" unless exists $args{$k};
33             }
34              
35 2         11 foreach my $k ( keys %args ) {
36 6 50       13 Carp::confess __PACKAGE__ . " unknown argument '$k'\n" unless grep { $k eq $_ } @metabase_allowed_args, @file_allowed_args, @this_allowed_args;
  30         63  
37             }
38              
39 2 50       7 unless ($args{'File'}) {
40 0         0 require CPAN::Reporter::Config;
41 0         0 $args{'File'} = CPAN::Reporter::Config::_get_config_dir();
42             }
43              
44 2         21 $args{'__file'} = Test::Reporter::Transport::File->new( $args{'File'} );
45              
46 2         96 $args{'__metabase'} = Test::Reporter::Transport::Metabase->new( map { $_ => $args{$_} } grep { $args{$_} } @metabase_allowed_args );
  4         32  
  6         12  
47              
48 2 50       95 $args{'max_files'} = $MAX_FILES unless $args{'max_files'};
49              
50 2         20 return bless \%args => $class;
51             }
52              
53              
54             sub send {
55 1     1 1 10 my ($self, $report) = @_;
56              
57 1         5 my @errors;
58              
59             # Try Metabase
60 1 50       31 if (my $rv_m = eval { $self->{'__metabase'}->send($report) } ) {
  1         10  
61             # Metabase seems working, let's see if we have some files queued
62 0 0       0 if (opendir(my $DIR => $self->{'File'})) {
63 0         0 my @files = map { File::Spec->catfile($self->{'File'}, $_) } grep { /\.rpt/ } readdir $DIR;
  0         0  
  0         0  
64 0         0 closedir $DIR;
65 0         0 foreach my $file (splice(@files, 0, $self->{'max_files'})) {
66             my $tr = Test::Reporter->new(
67             'transport' => 'Metabase',
68             'transport_args' => [
69 0         0 map { $_ => $self->{$_} } grep { $self->{$_} } @metabase_allowed_args
  0         0  
  0         0  
70             ],
71             )->read( $file );
72 0         0 print __PACKAGE__ . ': sending queued report ' . $file . "\n";
73 0 0 0     0 if ($tr and $tr->send()) {
74 0         0 unlink $file;
75 0         0 sleep 1; # Don't try to hammer the Metabase
76             } else {
77 0         0 print __PACKAGE__ . ': cannot submit the file to Metabase, stop queue processing.' . "\n";
78             # Cannot send file to Metabase. Let's stop.
79 0         0 last;
80             }
81             }
82             }
83             } else {
84 1         373286 push @errors, __PACKAGE__ . ' Metabase error: ' . $@,
85             __PACKAGE__ . ' Saving report in the queue.';
86              
87             # Try File
88 1         3 my $rv_f;
89 1 50       2 unless ($rv_f = eval { $self->{'__file'}->send($report) }) {
  1         7  
90 0         0 push @errors, __PACKAGE__ . ' File error: ' . $@;
91             }
92              
93 1 50       875 Carp::carp join("\n", @errors, '') if @errors;
94              
95 1         71 return $rv_f;
96             }
97              
98 0           return 1;
99             }
100              
101             1;
102              
103             # ABSTRACT: Metabase transport for Test::Reporter with fallback to File transport
104              
105             =head1 NAME
106              
107             Test::Reporter::Transport::Metabase::Fallback
108              
109             =head1 SYNOPSIS
110              
111             my $report = Test::Reporter->new(
112             transport => 'Metabase::Fallback',
113             transport_args => [
114             uri => 'http://metabase.example.com:3000/',
115             id_file => '/home/jdoe/.metabase/metabase_id.json',
116             File => '/home/jdoe/.cpanreporter/reports',
117             ],
118             );
119              
120             # use space-separated in a CPAN::Reporter config.ini
121             transport = Metabase::Fallback uri http://metabase.example.com:3000/ ... File /home/stro/reports max_files 42
122              
123             =head1 DESCRIPTION
124              
125             This module creates a fallback mechanism for Test::Reporter Metabase
126             instance, combining L and
127             L functionality.
128              
129             Whenever Metabase submission fails, the report file is saved locally.
130             When the next report is successfully submitted to Metabase, all queued
131             reports are submitted along with it.
132              
133             "max_files" parameter specifies how many reports are sent from the queue
134             during the regular submission. Default value is 25. You may want to
135             increase it if you're running a smoker or decrease it if you don't want to
136             wait for too long during the casual CPAN shell usage. Keep in mind that
137             your queue is only processed when a report is being sent so if you're using
138             CPAN shell irregularly, a small number may keep some reports sitting in a
139             queue for a very long time.
140              
141             =head1 ISSUES
142              
143             If a saved report is corrupted (for example, has 0 byte length because your
144             disk is full), it will stay in your queue forever.
145              
146             If a saved report is corrupted in a way that it cannot be accepted by
147             Metabase, you queue may stuck until you manually remove the offending file.
148              
149             You probably couldn't use multiple CPAN shells at once unless you separate
150             .cpanreporter dir for each Perl.
151              
152             =head1 SUGGESTIONS
153              
154             Send your suggestions through RT, to stro@cpan.org, or post to
155             cpan-testers-discuss@perl.org mailing list.
156              
157             =head1 AUTHOR
158              
159             Serguei Trouchelle
160              
161             =head1 LICENSE AND COPYRIGHT
162              
163             Copyright (c) 2018 by Serguei Trouchelle
164              
165             This is free software; you can redistribute it and/or modify it under
166             the same terms as the Perl 5 programming language system itself.
167              
168             =cut
169