File Coverage

blib/lib/Test/Fetchware.pm
Criterion Covered Total %
statement 143 175 81.7
branch 37 72 51.3
condition 5 18 27.7
subroutine 27 32 84.3
pod 13 13 100.0
total 225 310 72.5


line stmt bran cond sub pod time code
1             package Test::Fetchware;
2             $Test::Fetchware::VERSION = '1.014';
3             # ABSTRACT: Provides testing subroutines for App::Fetchware.
4 50     50   3790356 use strict;
  50         101  
  50         2183  
5 50     50   281 use warnings;
  50         98  
  50         1726  
6              
7             # CPAN modules making Fetchwarefile better.
8 50     50   53972 use File::Temp 'tempdir';
  50         1158269  
  50         4039  
9 50     50   30837 use File::Spec::Functions qw(catfile rel2abs updir tmpdir);
  50         29539  
  50         4211  
10 50     50   413 use Test::More 0.98; # some utility test subroutines need it.
  50         1772  
  50         528  
11 50     50   22731 use Cwd;
  50         91  
  50         2825  
12 50     50   65814 use Archive::Tar;
  50         5988461  
  50         4228  
13 50     50   42850 use Path::Class;
  50         1280334  
  50         4080  
14 50     50   493 use Digest::MD5;
  50         94  
  50         1803  
15 50     50   2617 use Fcntl qw(:flock :mode);
  50         143  
  50         23920  
16 50     50   348 use Perl::OSType 'is_os_type';
  50         99  
  50         3202  
17 50     50   288 use File::Temp 'tempfile';
  50         129  
  50         2935  
18              
19 50     50   53632 use App::Fetchware::Util ':UTIL';
  50         160  
  50         17314  
20 50     50   553 use App::Fetchware::Config ':CONFIG';
  50         118  
  50         6986  
21              
22             # Enable Perl 6 knockoffs, and use 5.10.1, because smartmatching and other
23             # things in 5.10 were changed in 5.10.1+.
24 50     50   1373 use 5.010001;
  50         183  
  50         2097  
25              
26              
27             # Set up Exporter to bring App::Fetchware's API to everyone who use's it
28             # including fetchware's ability to let you rip into its guts, and customize it
29             # as you need.
30 50     50   400 use Exporter qw( import );
  50         125  
  50         127324  
31             # By default fetchware exports its configuration file like subroutines and
32             # fetchware().
33             #
34              
35             # These tags go with the override() subroutine, and together allow you to
36             # replace some or all of fetchware's default behavior to install unusual
37             # software.
38             our %EXPORT_TAGS = (
39             TESTING => [qw(
40             eval_ok
41             print_ok
42             fork_ok
43             skip_all_unless_release_testing
44             make_clean
45             make_test_dist
46             md5sum_file
47             expected_filename_listing
48             verbose_on
49             export_ok
50             end_ok
51             add_prefix_if_nonroot
52             create_test_fetchwarefile
53             )],
54             );
55             # *All* entries in @EXPORT_TAGS must also be in @EXPORT_OK.
56             our @EXPORT_OK = map {@{$_}} values %EXPORT_TAGS;
57              
58              
59              
60             sub eval_ok {
61 45     45 1 28334 my ($code, $expected_exception_text_or_regex, $test_name) = @_;
62 45         88 eval {$code->()};
  45         159  
63             # Test if an exception was actually thrown.
64 45 50       9200 if (not defined $@) {
65 0         0 BAIL_OUT("[$test_name]'s provided code did not actually throw an exception");
66             }
67            
68             # Support regexing the thrown exception's test if needed.
69 45 100       199 if (ref $expected_exception_text_or_regex ne 'Regexp') {
    50          
70 35         187 is($@, $expected_exception_text_or_regex, $test_name);
71             } elsif (ref $expected_exception_text_or_regex eq 'Regexp') {
72 10         143 like($@, qr/$expected_exception_text_or_regex/, $test_name);
73             }
74              
75             }
76              
77              
78              
79             sub print_ok {
80 72     72 1 2217002 my ($printer, $expected, $test_name) = @_;
81              
82 72         352 my $error;
83             my $stdout;
84             # Use eval to catch errors that $printer->() could possibly throw.
85             eval {
86 72         750 local *STDOUT;
87             # Turn on Autoflush mode, so each time print is called it causes perl to
88             # flush STDOUT's buffer. Otherwise a write could happen, that may not
89             # actually get written before this eval closes, causing $stdout to stay
90             # undef instead of getting whatever was written to STDOUT.
91 72         820 $| = 1;
92 72 50   24   5444 open STDOUT, '>', \$stdout
  24         609  
  24         146  
  24         448  
93             or $error = 'Can\'t open STDOUT to test cmd_upgrade using cmd_list';
94              
95             # Execute $printer
96 72         56828 $printer->();
97              
98 63 50       1011 close STDOUT
99             or $error = 'WTF! closing STDOUT actually failed! Huh?';
100 72 50       679 } or do {
101 0 0       0 $error = $@ if $@;
102 0 0       0 fail($error) if defined $error;
103             };
104              
105             # Since Test::More's testing subroutines return true or false if the test
106             # passes or fails, return this true or false value back to the caller.
107 63 100       867 if (ref($expected) eq '') {
    100          
    50          
108 27         124 return is($stdout, $expected,
109             $test_name);
110             } elsif (ref($expected) eq 'Regexp') {
111 4         42 return like($stdout, $expected,
112             $test_name);
113             } elsif (ref($expected) eq 'CODE') {
114             # Call the provided callback with what $printer->() printed.
115 32         183 return ok($expected->($stdout),
116             $test_name);
117             }
118             }
119              
120              
121              
122             sub fork_ok {
123 154     154 1 434169 my $coderef = shift;
124 154         719 my $test_name = shift;
125              
126              
127 154         622164 my $kid = fork;
128 154 50       11526 die "Couldn't fork: $!\n" if not defined $kid;
129             # ... parent code here ...
130 154 100       6488 if ( $kid ) {
131             # Block waiting for the child process ($kid) to exit.
132 137         552161290 waitpid($kid, 0);
133             }
134             # ... child code here ...
135             else {
136             # Run caller's code wihtout any args.
137             # And exit based on the success or failure of $coderef.
138 17 50       5261 $coderef->() ? exit 0 : exit 1;
139             }
140              
141             # And test that the child returned successfully.
142 137         8484 ok($? == 0, $test_name);
143              
144 137         156117 return $?;
145             }
146              
147              
148              
149             sub skip_all_unless_release_testing {
150 70 50 33 70 1 503572 if (not exists $ENV{FETCHWARE_RELEASE_TESTING}
      33        
151             or not defined $ENV{FETCHWARE_RELEASE_TESTING}
152             or $ENV{FETCHWARE_RELEASE_TESTING}
153             ne '***setting this will install software on your computer!!!!!!!***'
154              
155             # Enforce having *all* other FETCHWARE_* env vars set too to make it
156             # even harder to easily enable FETCHWARE_RELEASE_TESTING. This is
157             # because FETCHWARE_RELEASE_TESTING *installs* software on your
158             # computer.
159             #
160             # Furthermore, the env vars below are required for
161             # FETCHWARE_RELEASE_TESTING to work properly, so without them being set,
162             # then FETCHWARE_RELEASE_TESTING will not work properly, because these
163             # env vars will be undef; therefore, check to see if they're enabled.
164             ) {
165 70         421 plan skip_all => 'Not testing for release.';
166             }
167             }
168              
169              
170              
171             sub make_clean {
172 0 0 0 0 1 0 BAIL_OUT(<
173             Running make_clean() inside of fetchware's own directory! make_clean() should
174             only be called inside testing build directories, and perhaps also only called if
175             FETCHWARE_RELEASE_TESTING has been set.
176             EOF
177 0         0 system('make', 'clean');
178 0 0       0 chdir(updir()) or fail(q{Can't chdir(updir())!});
179             }
180              
181              
182              
183             ###BUGALERT### make_test_dist() only works properly on Unix, because of its
184             #dependencies on the shell and make, just replace those commands with perl
185             #itself, which we can pretty much guaranteed to be installed.
186             ###BUGALERT### 5 arguments!!! Just go full named parameters.
187             ###BUGALERT### Leave this undocumented, because I instead want to just take this
188             #whole subroutine to use named parameters.
189             ### # You can also specify a Fetchwarefile, but that makes specifying the
190             ### # $destination_directory *mandatory*. This limitation will be fixed in a
191             ### # later version by making all of this subroutines arguments named
192             ### # parameters, but until then it's mandatory. If you don't want to customize
193             ### # the $destination_directory, then just specify the default of
194             ### # File::Spec::tmpdir().
195             ### my $test_dist_path = make_test_dist($file_name, $ver_num,
196             ### rel2abs($destination_directory), Fetchwarefile => $fetchwarefile);
197             ### # Or specify AppendOption, but never both, and AppendOption also requires
198             ### # that you specify the $destination_directory too.
199             ### my $test_dist_path = make_test_dist($file_name, $ver_num,
200             ### rel2abs($destination_directory), AppendOption => $config_option);
201             ###BUGALERT###Inflexible, and forces any fetchware extension writers to copy and
202             #paste it and modify it, or come up with something else.. Not good :)
203             sub make_test_dist {
204 176     176 1 30243259 my $file_name = shift;
205 176         1368 my $ver_num = shift;
206 176         674 my $destination_directory = shift;
207              
208             # $destination_directory is a mandatory option, but if the caller does not
209             # provide one, then simply use a tempdir().
210 176 100       4345 if (not defined $destination_directory) {
211 73         1706 $destination_directory
212             = tempdir("fetchware-test-$$-XXXXXXXXXXX", TMPDIR => 1, CLEANUP => 1);
213             # Don't *only* create the tempdid $destination_directory, also, it must
214             # be chmod()'d to 755, unless stay_root is set, so that the dropped priv
215             # user can still access the directory make_test_dist() creates.
216 73 50       71751 chmod 0755, $destination_directory or die <
217             Test-Fetchware: Fetchware failed to change the permissions of it's testing
218             destination directory [$destination_directory] this shouldn't happen, and is
219             perhaps a bug. The OS error was [$!].
220             EOD
221              
222             }
223              
224             # Support other options such as Fetchwarefile and AppendOption.
225 176         573 my %opts = @_;
226              
227             # Append $ver_num to $file_name to complete the dist's name.
228 176         764 my $dist_name = "$file_name-$ver_num";
229              
230 176         1418 $destination_directory = rel2abs($destination_directory);
231              
232              
233 176         7580 my $test_dist_filename = catfile($destination_directory, "$dist_name.fpkg");
234              
235 176         5784 my $configure_path = catfile($dist_name, 'configure');
236 176         4017 my %test_dist_files = (
237             './Fetchwarefile' => <
238             # $file_name is a fake "test distribution" meant for testing fetchware's basic
239             # installing, upgrading, and so on functionality.
240             use App::Fetchware;
241              
242             program '$file_name';
243              
244             # Need to filter out the cruft.
245             filter '$file_name';
246              
247             # Just use MD5 to verify it.
248             verify_method 'md5';
249              
250             EOF
251             ,
252              
253             $configure_path => <
254             #!/bin/sh
255              
256             # A Test ./configure file for testing Fetchware's install, upgrade, and so on
257             # functionality.
258              
259             echo "fetchware: ./configure ran successfully!"
260             EOF
261             ,
262             catfile($dist_name, 'Makefile') => <
263             # Makefile for test-dist, which is a "test distribution" for testing Fetchware's
264             # install, upgrade, and so on functionality.
265              
266             all:
267             sh -c 'echo "fetchware: make ran successfully!"'
268              
269             install:
270             sh -c 'echo "fetchware: make install ran successfully!"'
271              
272             uninstall:
273             sh -c 'echo "fetchware: make uninstall ran successfully!"'
274              
275             build-package:
276             sh -c 'echo "Build package and creating md5sum."'
277              
278             sh -c '(cd .. && tar --create --gzip --verbose --file test-dist-1.00.fpkg ./Fetchwarefile test-dist-1.00)'
279              
280             sh -c '(cd .. && md5sum test-dist-1.00.fpkg > test-dist-1.00.fpkg.md5)'
281              
282             sh -c 'echo "Build package and creating md5sum for upgrade version."'
283              
284             sh -c 'cp -R ../test-dist-1.00 ../test-dist-1.01'
285              
286             sh -c '(cd .. && tar --create --gzip --verbose --file test-dist-1.00/test-dist-1.01.fpkg ./Fetchwarefile test-dist-1.01)'
287              
288             sh -c 'rm -r ../test-dist-1.01'
289              
290             sh -c 'md5sum test-dist-1.01.fpkg > test-dist-1.01.fpkg.md5'
291             EOF
292             ,
293             );
294              
295             # Append the lookup_url customized based the the $destination_directory for
296             # this generated test dist.
297 176         1626 $test_dist_files{'./Fetchwarefile'}
298             .=
299             "lookup_url 'file://$destination_directory';\n";
300              
301             # I must also add a mirror, which in make_test_dist()'s case is the same
302             # things as $destination_directory.
303 176         998 $test_dist_files{'./Fetchwarefile'}
304             .=
305             "mirror 'file://$destination_directory';\n";
306              
307              
308             # Be sure to add a prefix to the generated Fetchwarefile if fetchware is not
309             # running as root to ensure that our test installs succeed.
310             add_prefix_if_nonroot(sub {
311 0     0   0 my $prefix_dir = tempdir("fetchware-test-$$-XXXXXXXXXX",
312             TMPDIR => 1, CLEANUP => 1);
313 0         0 $test_dist_files{'./Fetchwarefile'}
314             .=
315             "prefix '$prefix_dir';";
316             }
317 176         3665 );
318              
319             # You can only specify Fetchwarefile or AppendOption never both.
320 176 50 66     6459 die <
321             fetchware: Run-time error. make_test_dist() can only be called with the
322             Fetchwarefile option *or* the AppendOption named parameters never both. Only
323             specify one.
324             EOD
325             # Replace the default Fetchwarefile with the one the caller specified.
326 176 100       961 $test_dist_files{'./Fetchwarefile'} = $opts{Fetchwarefile}
327             if exists $opts{Fetchwarefile};
328             # Or append AppendOption onto the generated Fetchwarefile.
329 176 100       821 $test_dist_files{'./Fetchwarefile'} .= "\n$opts{AppendOption}\n"
330             if exists $opts{AppendOption};
331              
332             # Create a temp dir to create or test-dist-1.$ver_num directory in.
333             # Must be done before original_cwd() is used to set $destination_directory,
334             # because original_cwd() is undef until create_tempdir() sets it.
335 176         1621 my $temp_dir = create_tempdir();
336              
337 176 50       35518 mkdir($dist_name) or die <
338             fetchware: Run-time error. Fetchware failed to create the directory
339             [$dist_name] in the current directory of [$temp_dir]. The OS error was
340             [$!].
341             EOD
342              
343 176         6466 for my $file_to_create (keys %test_dist_files) {
344 528 50       378042 open(my $fh, '>', $file_to_create) or die <
345             fetchware: Run-time error. Fetchware failed to open
346             [$file_to_create] for writing to create the Configure script that
347             test-dist needs to work properly. The OS error was [$!].
348             EOD
349 528         3558 print $fh $test_dist_files{$file_to_create};
350 528         34206 close $fh;
351             }
352              
353             # chmod() ./configure, so it can be executed.
354 176 50       6078 chmod(0755, $configure_path) or die <
355             fetchware: run-time error. fetchware failed to chmod [$configure_path] to add
356             execute permissions, which ./configure needs. Os error [$!].
357             EOC
358              
359             # Create a tar archive of all of the files needed for test-dist.
360 176 50       7295 Archive::Tar->create_archive("$test_dist_filename", COMPRESS_GZIP,
361             keys %test_dist_files) or die <
362             fetchware: Run-time error. Fetchware failed to create the test-dist archive for
363 0         0 testing [$test_dist_filename] The error was [@{[Archive::Tar->error()]}].
364             EOD
365              
366             # Cd back to original_cwd() and delete $temp_dir.
367 176         1938332 cleanup_tempdir();
368              
369 176         6785 return rel2abs($test_dist_filename);
370             }
371              
372              
373              
374             sub md5sum_file {
375 160     160 1 10124 my $archive_to_md5 = shift;
376              
377 160 50       11445 open(my $package_fh, '<', $archive_to_md5)
378             or die <
379             App-Fetchware: run-time error. Fetchware failed to open the file it downloaded
380             while trying to read it in order to check its MD5 sum. The file was
381             [$archive_to_md5]. OS error [$!]. See perldoc App::Fetchware.
382             EOD
383              
384 160         3428 my $digest = Digest::MD5->new();
385              
386             # Digest requires the filehandle to have binmode set.
387 160         677 binmode $package_fh;
388              
389 160         397 my $calculated_digest;
390 160         360 eval {
391             # Add the file for digesting.
392 160         4196 $digest->addfile($package_fh);
393             # Actually digest it.
394 160         1306 $calculated_digest = $digest->hexdigest();
395             };
396 160 50       571 if ($@) {
397 0         0 die <
398             App-Fetchware: run-time error. Digest::MD5 croak()ed an error [$@].
399             See perldoc App::Fetchware.
400             EOD
401             }
402              
403 160 50       2338 close $package_fh or die <
404             App-Fetchware: run-time error Fetchware failed to close the file
405             [$archive_to_md5] after opening it for reading. See perldoc App::Fetchware.
406             EOD
407            
408 160         810 my $md5sum_file = rel2abs($archive_to_md5);
409 160         2704 $md5sum_file = "$md5sum_file.md5";
410 160 50       164990 open(my $md5_fh, '>', $md5sum_file) or die <
411             fetchware: run-time error. Failed to open [$md5sum_file] while calculating a
412             md5sum. Os error [$!].
413             EOD
414              
415 160         1040 print $md5_fh "$calculated_digest @{[file($archive_to_md5)->basename()]}";
  160         2349  
416              
417 160 50       139509 close $md5_fh or die <
418             App-Fetchware: run-time error Fetchware failed to close the file
419             [$md5sum_file] after opening it for reading. See perldoc App::Fetchware.
420             EOD
421              
422 160         2450 return $md5sum_file;
423             }
424              
425              
426              
427             sub expected_filename_listing {
428 2     2 1 7 my $expected_filename_listing = <<'EOC';
429             array_each(
430             array_each(any(
431             re(qr/Announcement2.\d.(html|txt)/),
432             re(qr/CHANGES_2\.\d(\.\d+)?/),
433             re(qr/CURRENT(-|_)IS(-|_)\d\.\d+?\.\d+/),
434             re(qr/
435             HEADER.html
436             |
437             KEYS
438             |
439             README.html
440             |
441             binaries
442             |
443             docs
444             |
445             flood
446             /x),
447             re(qr/httpd-2\.\d\.\d+?-win32-src\.zip(\.asc)?/),
448             re(qr/httpd-2\.\d\.\d+?\.tar\.(bz2|gz)(\.asc)?/),
449             re(qr/httpd-2\.\d\.\d+?-deps\.tar\.(bz2|gz)(\.asc)?/),
450             re(qr/
451             libapreq
452             |
453             mod_fcgid
454             |
455             mod_ftp
456             |
457             patches
458             /x),
459             re(qr/\d{10,12}/)
460             ) # end any
461             )
462             );
463             EOC
464              
465 2         978 return $expected_filename_listing;
466             }
467              
468              
469              
470             sub verbose_on {
471             # Turn on verbose functionality.
472 22     22 1 19539 $fetchware::verbose = 1;
473             }
474              
475              
476              
477             sub export_ok{
478 12     12 1 5149 my ($sorted_subs, $sorted_export) = @_;
479              
480             package main;
481 12         26 $main::VERSION = '1.014';
482 12         114 my @sorted_subs = sort @$sorted_subs;
483 12         84 my @sorted_export = sort @$sorted_export;
484              
485 12 50       40 fail("Specified arrays have a different length.\n[@sorted_subs]\n[@sorted_export]")
486             if @sorted_subs != @sorted_export;
487              
488 12         19 my $i = 0;
489 12         26 for my $e (@sorted_subs) {
490 159 50       416 if ($e eq $sorted_export[$i]) {
491 159         641 pass("[$e] matches [$sorted_export[$i]]");
492             } else {
493 0         0 fail("[$e] does *not* match [$sorted_export[$i]]");
494             }
495 159         58047 $i++;
496             }
497             }
498              
499              
500              
501             sub end_ok {
502 0     0 1 0 my $temp_dir = shift;
503              
504 0         0 ok(open(my $fh_sem, '>', catfile($temp_dir, 'fetchware.sem')),
505             'checked cleanup_tempdir() open fetchware lock file success.');
506 0         0 ok( flock($fh_sem, LOCK_EX | LOCK_NB),
507             'checked cleanup_tempdir() success.');
508 0         0 ok(close $fh_sem,
509             'checked cleanup_tempdir() released fetchware lock file success.');
510             }
511              
512              
513              
514             sub add_prefix_if_nonroot {
515 176     176 1 645 my $callback = shift;
516 176         333 my $prefix;
517 176 50 33     2467 if (not is_os_type('Unix') or $> != 0 ) {
518 0 0       0 if (not defined $callback) {
519 0         0 $prefix = tempdir("fetchware-test-$$-XXXXXXXXXX",
520             TMPDIR => 1, CLEANUP => 1);
521 0         0 note("Running as nonroot or nonunix using prefix temp dir [$prefix]");
522 0         0 config(prefix => $prefix);
523             } else {
524 0         0 ok(ref $callback eq 'CODE', <
525             Received callback that is a proper coderef [$callback].
526             EOD
527 0         0 $prefix = $callback->();
528             }
529            
530             # Return the prefix that will be used.
531 0         0 return $prefix;
532             } else {
533             # Return undef meaning no prefix was added.
534 176         10394 return;
535             }
536             }
537              
538              
539              
540             sub create_test_fetchwarefile {
541 0     0 1 0 my $fetchwarefile_content = shift;
542              
543             # Use a temp dir outside of the installation directory
544 0         0 my ($fh, $fetchwarefile_path)
545             =
546             tempfile("fetchware-$$-XXXXXXXXXXXXXX", TMPDIR => 1, UNLINK => 1);
547              
548             # Chmod 644 to ensure a possibly dropped priv child can still at least read
549             # the file. It doesn't need write access just read.
550 0 0 0     0 unless (chmod 0644, $fetchwarefile_path
551             and
552             # Only Unix drops privs. Nonunix does not.
553             is_os_type('Unix')
554             ) {
555 0         0 die <
556             fetchware: Failed to chmod 0644, [$fetchwarefile_path]! This is a fatal error,
557             because if the file is not chmod()ed, then fetchware cannot access the file if
558             it was created by root, and then tried to read it, but root on Unix dropped
559             privs. OS error [$!].
560             EOD
561             }
562              
563             # Be sure to add a prefix to the generated Fetchwarefile if fetchware is not
564             # running as root to ensure that our test installs succeed.
565             #
566             # Prepend a newline to ensure that prefix is not added to an existing line.
567             add_prefix_if_nonroot(sub {
568 0     0   0 my $prefix_dir = tempdir("fetchware-test-$$-XXXXXXXXXX",
569             TMPDIR => 1, CLEANUP => 1);
570 0         0 $fetchwarefile_content
571             .=
572             "\nprefix '$prefix_dir';";
573             }
574 0         0 );
575              
576             # Put test stuff in Fetchwarefile.
577 0         0 print $fh "$fetchwarefile_content";
578              
579             # Close the file in case it bothers Archive::Tar reading it.
580 0         0 close $fh;
581              
582 0         0 return $fetchwarefile_path;
583             }
584              
585              
586              
587             ###BUGALERT### Create a frt() subroutine to mirror my frt bash function that
588             #will work like Util's config() does, but access %ENV instead of %CONFIG, and if
589             #the requested env var does not exist it will print a failure mesage using
590             #fail(). I could also use this function as a place to paste in frt() as well.
591              
592              
593             1;
594              
595             =pod
596              
597             =head1 NAME
598              
599             Test::Fetchware - Provides testing subroutines for App::Fetchware.
600              
601             =head1 VERSION
602              
603             version 1.014
604              
605             =head1 SYNOPSIS
606              
607             use Test::Fetchware ':TESTING';
608              
609             eval_ok($code, $expected_exception_text_or_regex, $test_name);
610             eval_ok(sub { some_code_that_dies()},
611             <
612             some_code_that_dies() died with this message!
613             EOE
614             eval_ok(sub { some_code_whose_messages_change(),
615             qr/A regex that matches some_code_whose_messages_change() error message/,
616             'checked some_code_whose_messages_change() exception');
617              
618             print_ok(\&printer, $expected, $test_name);
619             print_ok(sub { some_func_that_prints()},
620             \$expected, 'checked some_func_that_prints() printed $expected');
621             print_ok(sub {some_func_that_prints()},
622             qr/some regex that matches what some_func_that_prints() prints/,
623             'checked some_func_that_prints() printed matched expected regex');
624             print_ok(sub { some_func_that_prints()},
625              
626             sub { # a coderef that returns true of some_func_that_prints() printed what it
627             #should print and returns false if it did not
628             }, 'checked some_func_that_prints() printed matched coderefs expectations.');
629              
630             subtest 'some subtest that tests fetchware' => sub {
631             skip_all_unless_release_testing();
632              
633             # ... Your tests go here that will be skipped unless
634             # FETCHWARE_RELEASE_TESTING among other env vars are set properly.
635             };
636              
637             make_clean();
638              
639             my $test_dist_path = make_test_dist($file_name, $ver_num, rel2abs($destination_directory));
640              
641             my $md5sum_fil_path = md5sum_file($archive_to_md5);
642              
643              
644             my $expected_filename_listing = expected_filename_listing()
645              
646             =head1 DESCRIPTION
647              
648             These subroutines provide miscellaneous subroutines that App::Fetchware's test
649             suite uses. Some are quite specific such as make_test_dist(), while others are
650             simple subroutines replacing entire CPAN modules such as eval_ok (similar to
651             Test::Exception) and print_ok (similar to Test::Output). I wrote them instead of
652             using the CPAN dependency, because all it would take is a relatively simple
653             function that I could easily write and test. And their interfaces disagreed with
654             me.
655              
656             =head1 TESTING SUBROUTINES
657              
658             =head2 eval_ok()
659              
660             eval_ok($code, $expected_exception_text_or_regex, $test_name);
661              
662             Executes the $code coderef, and compares its thrown exception, C<$@>, to
663             $expected_exception_text_or_regex, and uses $test_name as the name for the test if
664             provided.
665              
666             If $expected_exception_text_or_regex is a string then Test::More's is() is used,
667             and if $expected_exception_text_or_regex is a C<'Regexp'> according to ref(),
668             then like() is used, which will treat $expected_exception_text_or_regex as a
669             regex instead of as just a string.
670              
671             =head2 print_ok()
672              
673             print_ok(\&printer, $expected, $test_name);
674              
675             Tests if $expected is in the output that C<\&printer-E()> produces on C.
676              
677             It passes $test_name along to the underlying L function that it uses
678             to do the test.
679              
680             $expected can be a C, C, or C as returned by Perl's
681             L function.
682              
683             =over
684              
685             =item * If $expected is a SCALAR according to ref()
686              
687             =over
688              
689             =item * Then Use eq to determine if the test passes.
690              
691             =back
692              
693             =item * If $expected is a Regexp according to ref()
694              
695             =over
696              
697             =item * Then use a regex comparision just like Test::More's like() function.
698              
699             =back
700              
701             =item * If $expected is a CODEREF according to ref()
702              
703             =over
704              
705             =item * Then execute the coderef with a copy of the $printer's STDOUT and use the result of that expression to determine if the test passed or failed .
706              
707             =back
708              
709             =back
710              
711             =over
712              
713             NOTICE: C manipuation of STDOUT only works for the current Perl
714             process. STDOUT may be inherited by forks, but for some reason my knowledge of
715             Perl and Unix lacks a better explanation other than that print_ok() does not
716             work for testing what C and C processes do such as those
717             executed with run_prog().
718              
719             I also have not tested other possibilities, such as using IO::Handle to
720             manipulate STDOUT, or tie()ing STDOUT like Test::Output does. These methods
721             probably would not survive a fork() and an exec() though either.
722              
723             =back
724              
725             =head2 fork_ok()
726              
727             fork_ok(&code_fork_should_do, $test_name);
728              
729             Simply properly forks, and runs the caller's provided coderef in the child,
730             and tests that the child's exit value is 0 for success using a simple ok() call from
731             Test::More. The child's exit value is controlled by the caller based on what
732             &code_fork_should_do returns. If &code_fork_should_do returns true, then the
733             child returns C<0> for success, and if &code_fork_should_do returns false, then
734             the child returns C<1> for failure.
735              
736             Because the fork()ed child is a copy of the current perl process you can still
737             access whatever Test::More or Test::Fetchware testing subroutines you may have
738             imported for use in the test file that uses fork_ok().
739              
740             This testing helper subroutine only exists for testing fetchware's command line
741             interface. This interface is fetchware's run() subroutine and when you actually
742             execute the fetchware program from the command line such as C.
743              
744             =over
745              
746             =item WARNING
747              
748             fork_ok() has a major bug that makes any tests you attempt to run in
749             &code_fork_should_do that fail never report this failure properly to
750             Test::Builder. Also, any success is not reported either. This is not fork_ok()'s
751             fault it is Test::Builder's fault for still not having support for forking. This
752             lack of support for forking may be fixed in Test::Builder 1.5 or perhaps 2.0,
753             but those are still in development.
754              
755             =back
756              
757             =head2 skip_all_unless_release_testing()
758              
759             subtest 'some subtest that tests fetchware' => sub {
760             skip_all_unless_release_testing();
761              
762             # ... Your tests go here that will be skipped unless
763             # FETCHWARE_RELEASE_TESTING among other env vars are set properly.
764             };
765              
766             Skips all tests in your test file or subtest() if fetchware's testing
767             environment variable, C, is not set to its proper
768             value. See L
769             for more information.
770              
771             =over
772              
773             =item WARNING
774              
775             If you call skip_all_unless_release_testing() in your main test file without
776             being enclosed inside a subtest, then skip_all_unless_release_testing() will
777             skip all of your test from that point on till then end of the file, so be
778             careful where you use it, or just I use it in subtests to be safe.
779              
780             =back
781              
782             =head2 make_clean()
783              
784             make_clean();
785              
786             Runs C and then chdirs to the parent directory. This subroutine is
787             used in build() and install()'s test scripts to run make clean in between test
788             runs. If you override build() or install() you may wish to use make_clean to
789             automate this for you.
790              
791             make_clean() also makes some simple checks to ensure that you are not running it
792             inside of fetchware's own build directory. If it detects this, it BAIL_OUT()'s
793             of the test file to indicate that the test file has gone crazy, and is about to
794             do something it shouldn't.
795              
796             =head2 make_test_dist()
797              
798             my $test_dist_path = make_test_dist($file_name, $ver_num, rel2abs($destination_directory));
799              
800             Makes a C<$filename-$ver_num.fpkg> fetchware package that can be used for
801             testing fetchware's functionality without actually installing anything.
802              
803             Reuses create_tempdir() to create a temp directory that is used to put the
804             test-dist's files in. Then an archive is created based on original_cwd() or
805             $destination_directory if provided, which is the current working directory
806             before you call make_test_dist(). After the archive is created in original_cwd(),
807             make_test_dist() deletes the $temp_dir using cleanup_tempdir().
808              
809             If $destination_directory is not provided as an argument, then make_test_dist()
810             will just use tmpdir(), File::Spec's location for your system's temporary
811             directory.
812              
813             Returns the full path to the created test-dist fetchwware package.
814              
815             =over
816              
817             =item WARNING
818              
819             When you specify your own $destination_directory, you must also B that
820             it's permissions are C<0755>, because during testing fetchware may drop_privs()
821             causing it to lose its ability to access the $destination_directory. Therefore,
822             when specifying your own $destination_directory, please C it to to
823             C<0755> to ensure its child can still access the test distribution in your
824             $destination_directory.
825              
826             =back
827              
828             =head2 md5sum_file()
829              
830             my $md5sum_fil_path = md5sum_file($archive_to_md5);
831              
832             Uses Digest::MD5 to generate a md5sum just like the md5sum program does, and
833             instead of returning the output it returns the full path to a file containing
834             the md5sum called C<"$archive_to_md5.md5">.
835              
836             =head2 expected_filename_listing()
837              
838             cmd_deeply($got_filelisting, eval(expected_filename_listing()),
839             'test name');
840              
841             Returns a crazy string meant for use with Test::Deep for testing that Apache
842             directory listings have been parsed correctly by lookup().
843              
844             You must surround expected_filename_listing() with an eval, because Test::Deep's
845             crazy subroutines for creating complex data structure tests are actual
846             subroutines that need to be executed. They are not strings that can just be
847             returned by expected_filename_listing(), and then forwarded along to Test::Deep,
848             they must be executed:
849              
850             cmd_deeply($got_filelisting, eval(expected_filename_listing()),
851             'test name');
852              
853             =head2 verbose_on()
854              
855             verbose_on();
856              
857             Just turns C<$fetchware::vebose> on, by setting it to 1. It does not do anything
858             else. There is no corresponding verbose_off(). Just a vebose_on().
859              
860             Meant to be used in test suites, so that you can see any vmsg()s that print
861             during testing for debugging purposes.
862              
863             =head2 export_ok()
864              
865             export_ok($sorted_subs, $sorted_export);
866            
867             my @api_subs
868             = qw(start lookup download verify unarchive build install uninstall);
869             export_ok(\@api_subs, \@TestPackage::EXPORT);
870              
871             Just loops over C<@{$sorted_subs}>, and array ref, and ensures that each one
872             matches the same element of C<@{$sorted_export}>. You do not have to pre sort
873             these array refs, because export_ok() will copy them, and sort that copy of
874             them. Uses Test::More's pass() or fail() for each element in the arrays.
875              
876             =head2 end_ok()
877              
878             Because end() no longer uses File::Temp's cleanup() to delete B temporary
879             File::Temp managed temporary directories when end() is called, you can no longer
880             test end() we a simple C; instead, you should
881             use this testing subroutine. It tests if the specified $temp_dir still has a
882             locked C<'fetchware.sem'> fetchware semaphore file. If the file is not locked,
883             then end_ok() reports success, but if it cannot obtain a lock, end_ok reports
884             failure simply using ok().
885              
886             =head2 add_prefix_if_nonroot()
887              
888             my $prefix = add_prefix_if_nonroot();
889              
890             my $callbacks_return_value = add_prefix_if_nonroot(sub { a callback });
891              
892             fetchware is designed to be run as root, and to install system software in
893             system directories requiring root privileges. But, fetchware is flexible enough
894             to let you specifiy where you want the software you're going to install be
895             installed via the prefix configuration option. This subroutine when run creates
896             a temporary directory in File::Spec's tmpdir(), and then it directly runs
897             config() itself to create this config option for you.
898              
899             However, if you supply a coderef, add_prefix_if_nonroot() will instead call your
900             coderef instead of using config() directly. If your callback returns a scalar
901             such as the temporary directory that add_prefix_if_nonroot() normally returns,
902             this scalar is also returned back to the caller.
903              
904             It returns the path of the prefix that it configured for use, or it returns
905             false if it's conditions were not met causing it not to add a prefix.
906              
907             =head2 create_test_fetchwarefile()
908              
909             my $fetchwarefile_path = create_test_fetchwarefile($fetchwarefile_content);
910              
911             Writes the provided $fetchwarefile_content to a C inside a
912             File::Temp::tempfile(), and returns that file's path, $fetchwarefile_path.
913              
914             =head1 ERRORS
915              
916             As with the rest of App::Fetchware, Test::Fetchware does not return any error
917             codes; instead, all errors are die()'d if it's Test::Fetchware's error, or
918             croak()'d if its the caller's fault. These exceptions are simple strings, and
919             usually more than just one line long to help further describe the problem to
920             make fixing it easier.
921              
922             =head1 SEE ALSO
923              
924             L is similar to Test::Fetchware's eval_ok().
925              
926             L is similar to Test::Fetchware's print_ok().
927              
928             =head1 AUTHOR
929              
930             David Yingling
931              
932             =head1 COPYRIGHT AND LICENSE
933              
934             This software is copyright (c) 2013 by David Yingling.
935              
936             This is free software; you can redistribute it and/or modify it under
937             the same terms as the Perl 5 programming language system itself.
938              
939             =cut
940              
941             __END__