App-Fetchware
view release on metacpan or search on metacpan
lib/Test/Fetchware.pm view on Meta::CPAN
sub make_test_dist {
my %opts = @_;
# Validate options, and set defaults if they need to be set.
if (not defined $opts{file_name}) {
die <<EOD;
Test-Fetchware: file_name named parameter is a mandatory options, and must be
specified despite it pretty much always being just 'test-dist'. It is still
mandatory.
EOD
}
if (not defined $opts{ver_num}) {
die <<EOD;
Test-Fetchware: ver_num named parameter is a mandatory options, and must be
specified despite it pretty much always being just '1.00'. It is still
mandatory.
EOD
}
# $destination_directory is a mandatory option, but if the caller does not
# provide one, then simply use a tempdir().
if (not defined $opts{destination_directory}) {
$opts{destination_directory}
= tempdir("fetchware-test-$$-XXXXXXXXXXX", TMPDIR => 1, CLEANUP => 1);
# Don't *only* create the tempdid $destination_directory, also, it must
# be chmod()'d to 755, unless stay_root is set, so that the dropped priv
# user can still access the directory make_test_dist() creates.
chmod 0755, $opts{destination_directory} or die <<EOD;
Test-Fetchware: Fetchware failed to change the permissions of it's testing
destination directory [$opts{destination_directory}] this shouldn't happen, and is
perhaps a bug. The OS error was [$!].
EOD
}
# This %opts check must go before the code below sets fetchwarefile even if
# the user did not supply it. Perhaps separate things should stay separate,
# and %opts and %test_dist_files should both exist for this, but why bother
# duplicating the same information if only one options is annoyed?
if (defined $opts{fetchwarefile} and defined $opts{append_option}) {
die <<EOD;
fetchware: Run-time error. make_test_dist() can only be called with the
Fetchwarefile option *or* the append_option named parameters never both. Only
specify one.
EOD
}
if (not defined $opts{fetchwarefile}) {
$opts{fetchwarefile} = <<EOF;
# $opts{file_name} is a fake "test distribution" meant for testing fetchware's basic
# installing, upgrading, and so on functionality.
use App::Fetchware;
program '$opts{file_name}';
# Every Fetchwarefile needs a lookup_url...
lookup_url 'file://$opts{destination_directory}';
# ...and a mirror.
mirror 'file://$opts{destination_directory}';
# Need to filter out the cruft.
filter '$opts{file_name}';
# Just use MD5 to verify it.
verify_method 'md5';
EOF
}
if (not defined $opts{configure}) {
$opts{configure} = <<EOF;
#!/bin/sh
# A Test ./configure file for testing Fetchware's install, upgrade, and so on
# functionality.
echo "fetchware: ./configure ran successfully!"
EOF
}
if (not defined $opts{makefile}) {
$opts{makefile} = <<EOF;
# Makefile for test-dist, which is a "test distribution" for testing Fetchware's
# install, upgrade, and so on functionality.
all:
sh -c 'echo "fetchware: make ran successfully!"'
install:
sh -c 'echo "fetchware: make install ran successfully!"'
uninstall:
sh -c 'echo "fetchware: make uninstall ran successfully!"'
build-package:
sh -c 'echo "Build package and creating md5sum."'
sh -c '(cd .. && tar --create --gzip --verbose --file test-dist-1.00.fpkg ./Fetchwarefile test-dist-1.00)'
sh -c '(cd .. && md5sum test-dist-1.00.fpkg > test-dist-1.00.fpkg.md5)'
sh -c 'echo "Build package and creating md5sum for upgrade version."'
sh -c 'cp -R ../test-dist-1.00 ../test-dist-1.01'
sh -c '(cd .. && tar --create --gzip --verbose --file test-dist-1.00/test-dist-1.01.fpkg ./Fetchwarefile test-dist-1.01)'
sh -c 'rm -r ../test-dist-1.01'
sh -c 'md5sum test-dist-1.01.fpkg > test-dist-1.01.fpkg.md5'
EOF
}
if (defined $opts{append_option}) {
$opts{fetchware} .= "\n$opts{append_option}\n"
}
# Set up some variables used during test_dist creation.
# Append $ver_num to $file_name to complete the dist's name.
my $dist_name = "$opts{file_name}-$opts{ver_num}";
$opts{destination_directory} = rel2abs($opts{destination_directory});
my $test_dist_filename = catfile($opts{destination_directory}, "$dist_name.fpkg");
my $configure_path = catfile($dist_name, 'configure');
# Be sure to add a prefix to the generated Fetchwarefile if fetchware is not
# running as root to ensure that our test installs succeed.
lib/Test/Fetchware.pm view on Meta::CPAN
=item * C<configure> - option takes a string that will completely replace the default ./configure file in your generated test dist. This file is expected to be a shell script by fetchware, but will probably transition into being a perl script file fo...
=item * C<makefile> - option takes a string that will completely replace the default Makefile that is placed in your generated test dist. This file is expected to actually be a real Makefile.
=back
=over
=item WARNING
When you specify your own $destination_directory, you must also B<ensure> that
it's permissions are C<0755>, because during testing fetchware may drop_privs()
causing it to lose its ability to access the $destination_directory. Therefore,
when specifying your own $destination_directory, please C<chmod> it to to
C<0755> to ensure its child can still access the test distribution in your
$destination_directory.
=back
=head2 md5sum_file()
my $md5sum_fil_path = md5sum_file($archive_to_md5);
Uses Digest::MD5 to generate a md5sum just like the md5sum program does, and
instead of returning the output it returns the full path to a file containing
the md5sum called C<"$archive_to_md5.md5">.
=head2 expected_filename_listing()
cmd_deeply($got_filelisting, eval(expected_filename_listing()),
'test name');
Returns a crazy string meant for use with Test::Deep for testing that Apache
directory listings have been parsed correctly by lookup().
You must surround expected_filename_listing() with an eval, because Test::Deep's
crazy subroutines for creating complex data structure tests are actual
subroutines that need to be executed. They are not strings that can just be
returned by expected_filename_listing(), and then forwarded along to Test::Deep,
they must be executed:
cmd_deeply($got_filelisting, eval(expected_filename_listing()),
'test name');
=head2 verbose_on()
verbose_on();
Just turns C<$fetchware::vebose> on, by setting it to 1. It does not do anything
else. There is no corresponding verbose_off(). Just a vebose_on().
Meant to be used in test suites, so that you can see any vmsg()s that print
during testing for debugging purposes.
=head2 export_ok()
export_ok($sorted_subs, $sorted_export);
my @api_subs
= qw(start lookup download verify unarchive build install uninstall);
export_ok(\@api_subs, \@TestPackage::EXPORT);
Just loops over C<@{$sorted_subs}>, and array ref, and ensures that each one
matches the same element of C<@{$sorted_export}>. You do not have to pre sort
these array refs, because export_ok() will copy them, and sort that copy of
them. Uses Test::More's pass() or fail() for each element in the arrays.
=head2 end_ok()
Because end() no longer uses File::Temp's cleanup() to delete B<all> temporary
File::Temp managed temporary directories when end() is called, you can no longer
test end() we a simple C<ok(not -e $temp_dir, $test_name);>; instead, you should
use this testing subroutine. It tests if the specified $temp_dir still has a
locked C<'fetchware.sem'> fetchware semaphore file. If the file is not locked,
then end_ok() reports success, but if it cannot obtain a lock, end_ok reports
failure simply using ok().
=head2 add_prefix_if_nonroot()
my $prefix = add_prefix_if_nonroot();
my $callbacks_return_value = add_prefix_if_nonroot(sub { a callback });
fetchware is designed to be run as root, and to install system software in
system directories requiring root privileges. But, fetchware is flexible enough
to let you specifiy where you want the software you're going to install be
installed via the prefix configuration option. This subroutine when run creates
a temporary directory in File::Spec's tmpdir(), and then it directly runs
config() itself to create this config option for you.
However, if you supply a coderef, add_prefix_if_nonroot() will instead call your
coderef instead of using config() directly. If your callback returns a scalar
such as the temporary directory that add_prefix_if_nonroot() normally returns,
this scalar is also returned back to the caller.
It returns the path of the prefix that it configured for use, or it returns
false if it's conditions were not met causing it not to add a prefix.
=head2 create_test_fetchwarefile()
my $fetchwarefile_path = create_test_fetchwarefile($fetchwarefile_content);
Writes the provided $fetchwarefile_content to a C<Fetchwarefile> inside a
File::Temp::tempfile(), and returns that file's path, $fetchwarefile_path.
=head2 rmdashr_ok()
rmdashr_ok($dir_to_recursive_delete, $test_message)
Recursively deletes the specified directory using L<File::Path>'s remove_tree()
subroutine. Returns nothing, but does call L<Test::More>'s ok() for you with
your $test_message if remove_tree() was successful.
=over
=item NOTE:
rmdashr_ok() reports its test as PASS if I<any> number of files are successfully
deleted. It only reports FAIL if I<no> directories were deleted. L<Test::More>'s
note() is used to print out verbose info about exactly what files were deleted,
( run in 0.934 second using v1.01-cache-2.11-cpan-39bf76dae61 )