Archive-Tar-Builder
view release on metacpan or search on metacpan
t/lib-Archive-Tar-Builder.t view on Meta::CPAN
open( $fh, '>', $file ) or die("Unable to open $file for writing: $!");
print {$fh} "Meow\n";
close $fh;
return $tmpdir;
}
my $badfile = '/dev/null/impossible';
my $tar = find_tar();
{
my $builder = Archive::Tar::Builder->new;
eval { $builder->archive(); };
like( $@ => qr/No paths to archive specified/, '$builder->archive() dies if no paths are specified' );
eval { $builder->archive('foo'); };
like( $@ => qr/No file handle set/, '$builder->archive() dies if no file handle is set' );
eval { $builder->archive_as( 'foo' => 'bar' ); };
like( $@ => qr/No file handle set/, '$builder->archive_as() dies if no file handle is set' );
}
SKIP: {
skip( 'Cannot test permissions failures as root', 2 ) if $< == 0;
my $tmp = File::Temp::tempdir( 'CLEANUP' => 1 );
my $dir = "$tmp/foo";
mkdir( $dir, 0000 );
my $builder = Archive::Tar::Builder->new( 'quiet' => 1 );
open( my $fh, '>', '/dev/null' ) or die("Unable to open /dev/null: $!");
$builder->set_handle($fh);
$builder->archive($tmp);
eval { $builder->finish(); };
like( $@ => qr/^Delayed nonzero exit/, '$builder->finish() still die()s with "quiet" but not "ignore_errors" for non-fatals' );
undef $@;
$builder = Archive::Tar::Builder->new(
'quiet' => 1,
'ignore_errors' => 1
);
$builder->set_handle($fh);
$builder->archive($tmp);
eval { $builder->finish(); };
ok( !$@, '$builder->finish() does not die() if "ignore_errors" is set for non-fatals' );
chmod( 0600, $dir );
}
#
# Test external functionality
#
{
my $oldpwd = Cwd::getcwd();
my $tmpdir = build_tree();
chdir($tmpdir) or die("Unable to chdir() to $tmpdir: $!");
my $archive = Archive::Tar::Builder->new;
my %paths = (
'foo' => 'foo',
'bar' => 'foo',
'baz' => 'foo',
'home' => 'home'
);
#
# Test Archive::Tar::Builder's ability to exclude files
#
$archive->exclude_from_file("$tmpdir/foo/exclude.txt");
$archive->exclude('baz');
ok( $archive->is_excluded("$tmpdir/baz"), '$archive->is_excluded() works when excluding added with $archive->exclude()' );
ok( $archive->is_excluded("$tmpdir/foo/cats/meow"), '$archive->is_excluded() works when exclusion added with $archive->exclude_from_file()' );
#
# Test to see the expected contents are written.
#
my $reader_pid = IPC::Open3::open3( my ( $in, $out ), undef, $tar, '-tf', '-' );
my $writer_pid = fork();
$archive->set_handle($in);
if ( !defined $writer_pid ) {
die("Unable to fork(): $!");
}
elsif ( $writer_pid == 0 ) {
close $out;
foreach my $member ( sort keys %paths ) {
my $path = $paths{$member};
$archive->archive_as( $path => $member );
}
$archive->finish();
#
# This may seem a bit gratuitous, but this is needed because Perl 5.6.2's
# distribution of File::Temp has a bug in which directories are cleaned
# up regardless if the process exiting is a child of the process that
# created the directory in question, or not. execve() is the easiest way
# to clear away atexit() handlers in this case.
#
exec( '/bin/sh', '-c', 'true' );
}
t/lib-Archive-Tar-Builder.t view on Meta::CPAN
print {$fh} "foo\n";
print {$fh} "bar\n";
print {$fh} "baz\n";
close $fh;
eval { $archive->include('meow'); };
is( $@ => '', '$archive->include() does not die when adding inclusion pattern' );
eval { $archive->include_from_file($badfile); };
like( $@ => qr/^Cannot add items to inclusion list from file $badfile:/, '$archive->include_from_file() dies on invalid file' );
eval { $archive->include_from_file($file); };
is( $@ => '', '$archive->include_from_file() does not die when adding include patterns from file' );
my %TESTS = (
'foo' => 1,
'bar/poo' => 1,
'baz/poo' => 1,
'meow/cats' => 1,
'haz/meow/poo' => 0,
'haz/poo/meow' => 0,
'bleh' => 0
);
foreach my $path ( sort keys %TESTS ) {
my $should_be_included = $TESTS{$path};
if ($should_be_included) {
ok( !$archive->is_excluded($path), "'$path' is included" );
}
else {
ok( $archive->is_excluded($path), "'$path' is not included" );
}
}
unlink($file);
}
# Test error handling
SKIP: {
skip( 'Test will not work as root', 1 ) unless $<;
my $tmpdir = File::Temp::tempdir( 'CLEANUP' => 1 );
my $path = "$tmpdir/foo";
mkdir( $path, 0 );
open( my $fh, '>', '/dev/null' );
my $builder = Archive::Tar::Builder->new( 'quiet' => 1 );
$builder->set_handle($fh);
$builder->archive($tmpdir);
eval { $builder->finish(); };
like( $@ => qr/^Delayed nonzero exit/, '$builder->finish() dies if any errors were encountered' );
chmod( 0600, $path );
}
# Test long filenames, symlinks
foreach my $ext (qw/gnu posix/) {
my $tmpdir = File::Temp::tempdir( 'CLEANUP' => 1 );
my $path = "$tmpdir/" . ( 'foops/' x 60 );
File::Path::mkpath($path) or die("Unable to create long path: $!");
my $long_symlink = "${path}foo";
$long_symlink =~ s/^\///;
$long_symlink =~ s/\/$//;
symlink( 'foo', "$tmpdir/bar" ) or die("Unable to symlink() $tmpdir/bar to foo: $!");
symlink( $long_symlink, "$tmpdir/baz" ) or die("Unable to symlink() $tmpdir/baz to $long_symlink: $!");
my $archive = Archive::Tar::Builder->new( "${ext}_extensions" => 1 );
my $err = Symbol::gensym();
my $reader_pid = IPC::Open3::open3( my ( $in, $out ), $err, $tar, '-tvf', '-' );
my $writer_pid = fork();
if ( !defined $writer_pid ) {
die("Unable to fork(): $!");
}
elsif ( $writer_pid == 0 ) {
$archive->set_handle($in);
$archive->archive($tmpdir);
$archive->flush();
exec( '/bin/sh', '-c', 'true' );
}
my ( $paths, $errors );
my $rin = '';
vec( $rin, fileno($out), 1 ) = 1;
vec( $rin, fileno($err), 1 ) = 1;
my %FOUND;
my %SYMLINKS;
close $in;
while ( select( my $rout = $rin, undef, undef, undef ) > 0 ) {
my $buf;
my $len;
if ( vec( $rout, fileno($out), 1 ) ) {
$len = sysread( $out, $buf, 512 );
if ( !$len ) {
vec( $rin, fileno($out), 1 ) = 0;
}
else {
$paths .= $buf;
}
}
if ( vec( $rout, fileno($err), 1 ) ) {
( run in 1.990 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )