File Coverage

blib/lib/TAP/Harness/Archive/MultipleHarnesses.pm
Criterion Covered Total %
statement 79 81 97.5
branch 20 26 76.9
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 107 115 93.0


line stmt bran cond sub pod time code
1             package TAP::Harness::Archive::MultipleHarnesses;
2 2     2   159752 use strict;
  2         5  
  2         91  
3 2     2   13 use base 'TAP::Harness::Archive';
  2         5  
  2         2139  
4 2     2   584657 use File::Path;
  2         11  
  2         143  
5 2     2   13 use File::Spec;
  2         5  
  2         49  
6 2     2   11494 use lib qw( ./lib );
  2         1514  
  2         12  
7 2     2   11960 use TAP::Harness::ReportByDescription;
  2         5  
  2         1890  
8             our $VERSION = '0.06';
9              
10             sub runtests {
11 7     7 1 181759 my ($self, $targetsref, @files) = @_;
12              
13             # tell TAP::Harness to put the raw tap someplace we can find it later
14 7         46 my $dir = $self->{__archive_tempdir};
15 7         61 $ENV{PERL_TEST_HARNESS_DUMP_TAP} = $dir;
16              
17             # get some meta information about this run
18 7         24 my @test_labels = ();
19 7         16 foreach my $subharness (@{$targetsref}) {
  7         35  
20 14         76 my %har = %$subharness;
21 14         30 my @tests = @{$har{tests}};
  14         34  
22 14         30 foreach my $test (@tests) {
23 28         102 push @test_labels, $test->[1];
24             }
25             }
26 7         51 my %meta = (
27             file_order => \@test_labels,
28             start_time => time(),
29             );
30              
31 7         133 my $aggregator = TAP::Parser::Aggregator->new;
32              
33 7         791 $aggregator->start();
34 7         224 foreach my $set (@{$targetsref}) {
  7         20  
35             # rewrite environment
36 14 100       74 &{$set->{rule}} if defined $set->{rule};
  12         72  
37 14         214 my $harness = TAP::Harness::ReportByDescription->new();
38 14         18197 $harness->aggregate_tests($aggregator, @{$set->{tests}});
  14         106  
39             }
40 7         90 $aggregator->stop();
41              
42 7         506 $meta{stop_time} = time();
43              
44 7         41 my @parsers = $aggregator->parsers;
45 7         133 for ( my $i = 0; $i < @parsers; $i++ ) {
46 28         364 $parsers[ $i ] = {
47             start_time => $parsers[ $i ]->start_time,
48             end_time => $parsers[ $i ]->end_time,
49             description => $test_labels[ $i ],
50             };
51             }
52 7         392 $meta{file_attributes} = \@parsers;
53              
54 7         105 my $cwd = Cwd::getcwd();
55 7         34 my $is_dir = $self->{__archive_is_directory};
56 7         15 my ($archive, $output_file);
57 7 100       26 if( $is_dir ) {
58 1         8 $output_file = $self->{__archive_tempdir};
59             }
60             else {
61 6         21 $output_file = $self->{__archive_file};
62              
63             # go into the dir so that we can reference files
64             # relatively and put them in the archive that way
65 6 50       189 chdir($dir) or $self->_croak("Could not change to directory $dir: $!");
66              
67 6 50       644 unless (File::Spec->file_name_is_absolute($output_file)) {
68 0         0 $output_file = File::Spec->catfile($cwd, $output_file);
69             }
70              
71             # create the archive
72 6         160 $archive = Archive::Tar->new();
73 6         331 $archive->add_files($self->_get_all_tap_files);
74 6 50       21497 chdir($cwd) or $self->_croak("Could not return to directory $cwd: $!");
75             }
76              
77             # add in any extra files
78 7 100       46 if(my $x_files = $self->{__archive_extra_files}) {
79 6         13 my @rel_x_files;
80 6         26 foreach my $x_file (@$x_files) {
81             # handle both relative and absolute file names
82 12         17 my $rel_file;
83 12 50       838 if( File::Spec->file_name_is_absolute($x_file) ) {
84 0         0 $rel_file = File::Spec->abs2rel($x_file, $cwd);
85             }
86             else {
87 12         21 $rel_file = $x_file;
88             }
89 12         43 push(@rel_x_files, $rel_file);
90             }
91 6 100       52 $archive->add_files(@rel_x_files) unless $is_dir;
92 6         4914 $meta{extra_files} = \@rel_x_files;
93             }
94              
95             # add any extra_properties to the meta
96 7 100       50 if(my $extra_props = $self->{__archive_extra_props}) {
97 6         19 $meta{extra_properties} = $extra_props;
98             }
99              
100             # create the YAML meta file
101 7         142 my $yaml = YAML::Tiny->new();
102 7         161 $yaml->[0] = \%meta;
103 7 100       29 if( $is_dir ) {
104 1         33 my $meta_file = File::Spec->catfile($output_file, 'meta.yml');
105 1 50       636 open(my $out, '>', $meta_file) or die "Could not create meta.yml: $!";
106 1         9 print $out $yaml->write_string;
107 1         2827 close($out);
108             }
109             else {
110 6         33 $archive->add_data('meta.yml', $yaml->write_string);
111 6 50       8944 $archive->write($output_file, $self->{__archive_format} eq 'tar.gz') or die $archive->errstr;
112             # be nice and clean up
113 6         59738 File::Path::rmtree($dir);
114             }
115              
116 7 100       176 print "\nTAP Archive created at $output_file\n"
117             unless $self->{formatter}->{verbosity} < -1;
118              
119 7         487 return $aggregator;
120             }
121              
122             1;
123              
124             =head1 NAME
125              
126             TAP::Harness::Archive::MultipleHarnesses - Create an archive of multiple
127             harnesses of TAP test results
128              
129             =cut
130              
131             =head1 SYNOPSIS
132              
133             use TAP::Harness::Archive::MultipleHarnesses;
134             my $archive = TAP::Harness::Archive::MultipleHarnesses->new(\%args);
135             $archive->runtests(\@targets);
136              
137             =head1 DESCRIPTION
138              
139             This package subclasses Michael Peters' TAP::Harness::Archive package from
140             CPAN. It provides its own C method for the case where you need to
141             create an archive of test results generated by running multiple harnesses
142             sequentially.
143              
144             For a discussion of use cases for this functionality, see the documentation
145             for TAP::Harness::ReportByDescription.
146              
147             perldoc TAP::Harness::ReportByDescription
148              
149             =head1 METHODS
150              
151             =head2 C
152              
153             Inherited from Test::Harness::Archive.
154              
155             =head2 C
156              
157             Replaces C. B
158             different from other packages' C interface: It takes a reference
159             to an array of hash references rather than a simple array.>
160              
161             Each hash reference holds information on how a particular set of tests is to
162             be run. The various sets are run and placed into the archive in the order in
163             which they appear in the array.
164              
165             Each hash reference needs three elements:
166              
167             =over 4
168              
169             =item * C
170              
171             A list of tests to be run (typically expressed as a list of file glob
172             patterns).
173              
174             =item * C
175              
176             A reference to a subroutine which will be run before a given set of tests is
177             executed. The purpose of this subroutine is to set up the environmental
178             variables as needed for a particular subharness.
179              
180             =item * C
181              
182             A string describing a particular subharness which will be combined with a
183             particular test file's name to form the description of the test both in STDOUT
184             and in the test archive.
185              
186             =back
187              
188             =head2 C
189              
190             Inherited from Test::Harness::Archive.
191              
192             =head1 EXAMPLE
193              
194             Adapted (simplified) from Parrot's C.
195              
196             use Parrot::Harness::Smoke qw( collect_test_environment_data );
197             use TAP::Harness::Archive::MultipleHarnesses;
198              
199             sub set_runcore_target {
200             my ($target) = @_;
201             return {
202             label => "test$target",
203             rule => sub { set_runcore_environmental_args($target) },
204             tests => [
205             map { [ $_, "test${alt}__$_", ] }
206             @Parrot::Harness::TestSets::runcore_test_files
207             ],
208             };
209             }
210             my @targets = map { set_runcore_target($_) } ( qw| b f r | );
211             my %env_data = collect_test_environment_data();
212              
213             my $archive = TAP::Harness::Archive::MultipleHarnesses->new( {
214             verbosity => $ENV{HARNESS_VERBOSE},
215             archive => 'parrot_test_run.tar.gz',
216             merge => 1,
217             jobs => $ENV{TEST_JOBS} || 1,
218             extra_properties => \%env_data,
219             extra_files => [ 'myconfig', 'config_lib.pir' ],
220             } );
221             my $overall_aggregator = $archive->runtests(\@targets);
222             $archive->summary($overall_aggregator);
223              
224             =head1 AUTHOR
225              
226             This code was derived from Michael Peters' Test::Harness::Archive distribution
227             on CPAN, as well as examples in the documentation for TAP::Harness,
228             TAP::Parser, TAP::Parser::Aggregator and other CPAN modules. Documentation
229             and code assemblage by James E Keenan.
230              
231             =head1 LICENSE
232              
233             This is free software and is released under the same terms as Perl itself.
234              
235             =cut
236              
237             # vim:ts=4:sw=4:et:sta