Advertisement
Guest User

perl-5.16.3/cpan/Archive-Extract/t/01_Archive-Extract.t

a guest
Jul 13th, 2015
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.25 KB | None | 0 0
  1. BEGIN { chdir 't' if -d 't' };
  2. BEGIN { mkdir 'out' unless -d 'out' };
  3.  
  4. ### left behind, at least on Win32. See core patch #31904
  5. END { rmtree('out') };
  6.  
  7. use strict;
  8. use lib qw[../lib];
  9.  
  10. use constant IS_WIN32 => $^O eq 'MSWin32' ? 1 : 0;
  11. use constant IS_CYGWIN => $^O eq 'cygwin' ? 1 : 0;
  12. use constant IS_VMS => $^O eq 'VMS' ? 1 : 0;
  13.  
  14. use Cwd qw[cwd];
  15. use Test::More qw[no_plan];
  16. use File::Spec;
  17. use File::Spec::Unix;
  18. use File::Path;
  19. use Data::Dumper;
  20. use File::Basename qw[basename];
  21. use Module::Load::Conditional qw[check_install];
  22.  
  23. ### uninitialized value in File::Spec warnings come from A::Zip:
  24. # t/01_Archive-Extract....ok 135/0Use of uninitialized value in concatenation (.) or string at /opt/lib/perl5/5.8.3/File/Spec/Unix.pm line 313.
  25. # File::Spec::Unix::catpath('File::Spec','','','undef') called at /opt/lib/perl5/site_perl/5.8.3/Archive/Zip.pm line 473
  26. # Archive::Zip::_asLocalName('') called at /opt/lib/perl5/site_perl/5.8.3/Archive/Zip.pm line 652
  27. # Archive::Zip::Archive::extractMember('Archive::Zip::Archive=HASH(0x9679c8)','Archive::Zip::ZipFileMember=HASH(0x9678fc)') called at ../lib/Archive/Extract.pm line 753
  28. # Archive::Extract::_unzip_az('Archive::Extract=HASH(0x966eac)') called at ../lib/Archive/Extract.pm line 674
  29. # Archive::Extract::_unzip('Archive::Extract=HASH(0x966eac)') called at ../lib/Archive/Extract.pm line 275
  30. # Archive::Extract::extract('Archive::Extract=HASH(0x966eac)','to','/Users/kane/sources/p4/other/archive-extract/t/out') called at t/01_Archive-Extract.t line 180
  31. #BEGIN { $SIG{__WARN__} = sub { require Carp; Carp::cluck(@_) } };
  32.  
  33. if ((IS_WIN32 or IS_CYGWIN) && ! $ENV{PERL_CORE}) {
  34. diag( "Older versions of Archive::Zip may cause File::Spec warnings" );
  35. diag( "See bug #19713 in rt.cpan.org. It is safe to ignore them" );
  36. }
  37.  
  38. my $Me = basename( $0 );
  39. my $Class = 'Archive::Extract';
  40.  
  41. use_ok($Class);
  42.  
  43. ### debug will always be enabled on dev versions
  44. my $Debug = (not $ENV{PERL_CORE} and
  45. ($ARGV[0] or $Archive::Extract::VERSION =~ /_/))
  46. ? 1
  47. : 0;
  48.  
  49. my $Self = File::Spec->rel2abs(
  50. IS_WIN32 ? &Win32::GetShortPathName( cwd() ) : cwd()
  51. );
  52. my $SrcDir = File::Spec->catdir( $Self,'src' );
  53. my $OutDir = File::Spec->catdir( $Self,'out' );
  54.  
  55. ### stupid stupid silly stupid warnings silly! ###
  56. $Archive::Extract::DEBUG = $Archive::Extract::DEBUG = $Debug;
  57. $Archive::Extract::WARN = $Archive::Extract::WARN = $Debug;
  58.  
  59. diag( "\n\n*** DEBUG INFORMATION ENABLED ***\n\n" ) if $Debug;
  60.  
  61. # Be as evil as possible to print
  62. $\ = "ORS_FLAG";
  63. $, = "OFS_FLAG";
  64. $" = "LISTSEP_FLAG";
  65.  
  66. my $tmpl = {
  67. ### plain files
  68. 'x.bz2' => { programs => [qw[bunzip2]],
  69. modules => [qw[IO::Uncompress::Bunzip2]],
  70. method => 'is_bz2',
  71. outfile => 'a',
  72. },
  73. 'x.tgz' => { programs => [qw[gzip tar]],
  74. modules => [qw[Archive::Tar IO::Zlib]],
  75. method => 'is_tgz',
  76. outfile => 'a',
  77. },
  78. 'x.tar.gz' => { programs => [qw[gzip tar]],
  79. modules => [qw[Archive::Tar IO::Zlib]],
  80. method => 'is_tgz',
  81. outfile => 'a',
  82. },
  83. 'x.tar' => { programs => [qw[tar]],
  84. modules => [qw[Archive::Tar]],
  85. method => 'is_tar',
  86. outfile => 'a',
  87. },
  88. 'x.gz' => { programs => [qw[gzip]],
  89. modules => [qw[Compress::Zlib]],
  90. method => 'is_gz',
  91. outfile => 'a',
  92. },
  93. 'x.Z' => { programs => [qw[uncompress]],
  94. modules => [qw[Compress::Zlib]],
  95. method => 'is_Z',
  96. outfile => 'a',
  97. },
  98. 'x.zip' => { programs => [qw[unzip]],
  99. modules => [qw[Archive::Zip]],
  100. method => 'is_zip',
  101. outfile => 'a',
  102. },
  103. 'x.jar' => { programs => [qw[unzip]],
  104. modules => [qw[Archive::Zip]],
  105. method => 'is_zip',
  106. outfile => 'a',
  107. },
  108. 'x.ear' => { programs => [qw[unzip]],
  109. modules => [qw[Archive::Zip]],
  110. method => 'is_zip',
  111. outfile => 'a',
  112. },
  113. 'x.war' => { programs => [qw[unzip]],
  114. modules => [qw[Archive::Zip]],
  115. method => 'is_zip',
  116. outfile => 'a',
  117. },
  118. 'x.par' => { programs => [qw[unzip]],
  119. modules => [qw[Archive::Zip]],
  120. method => 'is_zip',
  121. outfile => 'a',
  122. },
  123. 'x.lzma' => { programs => [qw[unlzma]],
  124. modules => [qw[Compress::unLZMA]],
  125. method => 'is_lzma',
  126. outfile => 'a',
  127. },
  128. 'x.xz' => { programs => [qw[unxz]],
  129. modules => [qw[IO::Uncompress::UnXz]],
  130. method => 'is_xz',
  131. outfile => 'a',
  132. },
  133. 'x.txz' => { programs => [qw[unxz tar]],
  134. modules => [qw[Archive::Tar
  135. IO::Uncompress::UnXz]],
  136. method => 'is_txz',
  137. outfile => 'a',
  138. },
  139. 'x.tar.xz'=> { programs => [qw[unxz tar]],
  140. modules => [qw[Archive::Tar
  141. IO::Uncompress::UnXz]],
  142. method => 'is_txz',
  143. outfile => 'a',
  144. },
  145. ### with a directory
  146. 'y.tbz' => { programs => [qw[bunzip2 tar]],
  147. modules => [qw[Archive::Tar
  148. IO::Uncompress::Bunzip2]],
  149. method => 'is_tbz',
  150. outfile => 'z',
  151. outdir => 'y',
  152. },
  153. 'y.tar.bz2' => { programs => [qw[bunzip2 tar]],
  154. modules => [qw[Archive::Tar
  155. IO::Uncompress::Bunzip2]],
  156. method => 'is_tbz',
  157. outfile => 'z',
  158. outdir => 'y'
  159. },
  160. 'y.txz' => { programs => [qw[unxz tar]],
  161. modules => [qw[Archive::Tar
  162. IO::Uncompress::UnXz]],
  163. method => 'is_txz',
  164. outfile => 'z',
  165. outdir => 'y',
  166. },
  167. 'y.tar.xz' => { programs => [qw[unxz tar]],
  168. modules => [qw[Archive::Tar
  169. IO::Uncompress::UnXz]],
  170. method => 'is_txz',
  171. outfile => 'z',
  172. outdir => 'y'
  173. },
  174. 'y.tgz' => { programs => [qw[gzip tar]],
  175. modules => [qw[Archive::Tar IO::Zlib]],
  176. method => 'is_tgz',
  177. outfile => 'z',
  178. outdir => 'y'
  179. },
  180. 'y.tar.gz' => { programs => [qw[gzip tar]],
  181. modules => [qw[Archive::Tar IO::Zlib]],
  182. method => 'is_tgz',
  183. outfile => 'z',
  184. outdir => 'y'
  185. },
  186. 'y.tar' => { programs => [qw[tar]],
  187. modules => [qw[Archive::Tar]],
  188. method => 'is_tar',
  189. outfile => 'z',
  190. outdir => 'y'
  191. },
  192. 'y.zip' => { programs => [qw[unzip]],
  193. modules => [qw[Archive::Zip]],
  194. method => 'is_zip',
  195. outfile => 'z',
  196. outdir => 'y'
  197. },
  198. 'y.par' => { programs => [qw[unzip]],
  199. modules => [qw[Archive::Zip]],
  200. method => 'is_zip',
  201. outfile => 'z',
  202. outdir => 'y'
  203. },
  204. 'y.jar' => { programs => [qw[unzip]],
  205. modules => [qw[Archive::Zip]],
  206. method => 'is_zip',
  207. outfile => 'z',
  208. outdir => 'y'
  209. },
  210. 'y.ear' => { programs => [qw[unzip]],
  211. modules => [qw[Archive::Zip]],
  212. method => 'is_zip',
  213. outfile => 'z',
  214. outdir => 'y'
  215. },
  216. 'y.war' => { programs => [qw[unzip]],
  217. modules => [qw[Archive::Zip]],
  218. method => 'is_zip',
  219. outfile => 'z',
  220. outdir => 'y'
  221. },
  222. ### with non-same top dir
  223. 'double_dir.zip' => {
  224. programs => [qw[unzip]],
  225. modules => [qw[Archive::Zip]],
  226. method => 'is_zip',
  227. outfile => 'w',
  228. outdir => 'x'
  229. },
  230. };
  231.  
  232. ### XXX special case: on older solaris boxes (8),
  233. ### bunzip2 is version 0.9.x. Older versions (pre 1),
  234. ### only extract files that end in .bz2, and nothing
  235. ### else. So remove that test case if we have an older
  236. ### bunzip2 :(
  237. { if( $Class->have_old_bunzip2 ) {
  238. delete $tmpl->{'y.tbz'};
  239. diag "Old bunzip2 detected, skipping .tbz test";
  240. }
  241. }
  242.  
  243. ### show us the tools IPC::Cmd will use to run binary programs
  244. if( $Debug ) {
  245. diag( "IPC::Run enabled: $IPC::Cmd::USE_IPC_RUN " );
  246. diag( "IPC::Run available: " . IPC::Cmd->can_use_ipc_run );
  247. diag( "IPC::Run vesion: $IPC::Run::VERSION" );
  248. diag( "IPC::Open3 enabled: $IPC::Cmd::USE_IPC_OPEN3 " );
  249. diag( "IPC::Open3 available: " . IPC::Cmd->can_use_ipc_open3 );
  250. diag( "IPC::Open3 vesion: $IPC::Open3::VERSION" );
  251. }
  252.  
  253. ### test all type specifications to new()
  254. ### this tests bug #24578: Wrong check for `type' argument
  255. { my $meth = 'types';
  256.  
  257. can_ok( $Class, $meth );
  258.  
  259. my @types = $Class->$meth;
  260. ok( scalar(@types), " Got a list of types" );
  261.  
  262. for my $type ( @types ) {
  263. my $obj = $Class->new( archive => $Me, type => $type );
  264. ok( $obj, " Object created based on '$type'" );
  265. ok( !$obj->error, " No error logged" );
  266. }
  267.  
  268. ### test unknown type
  269. { ### must turn on warnings to catch error here
  270. local $Archive::Extract::WARN = 1;
  271.  
  272. my $warnings;
  273. local $SIG{__WARN__} = sub { $warnings .= "@_" };
  274.  
  275. my $ae = $Class->new( archive => $Me );
  276. ok( !$ae, " No archive created based on '$Me'" );
  277. ok( !$Class->error, " Error not captured in class method" );
  278. ok( $warnings, " Error captured as warning" );
  279. like( $warnings, qr/Cannot determine file type for/,
  280. " Error is: unknown file type" );
  281. }
  282. }
  283.  
  284. ### test multiple errors
  285. ### XXX whitebox test
  286. { ### grab a random file from the template, so we can make an object
  287. my $ae = Archive::Extract->new(
  288. archive => File::Spec->catfile($SrcDir,[keys %$tmpl]->[0])
  289. );
  290. ok( $ae, "Archive created" );
  291. ok( not($ae->error), " No errors yet" );
  292.  
  293. ### log a few errors
  294. { local $Archive::Extract::WARN = 0;
  295. $ae->_error( $_ ) for 1..5;
  296. }
  297.  
  298. my $err = $ae->error;
  299. ok( $err, " Errors retrieved" );
  300.  
  301. my $expect = join $/, 1..5;
  302. is( $err, $expect, " As expected" );
  303.  
  304. ### this resets the errors
  305. ### override the 'check' routine to return false, so we bail out of
  306. ### extract() early and just run the error reset code;
  307. { no warnings qw[once redefine];
  308. local *Archive::Extract::check = sub { return };
  309. $ae->extract;
  310. }
  311. ok( not($ae->error), " Errors erased after ->extract() call" );
  312. }
  313.  
  314. ### XXX whitebox test
  315. ### test __get_extract_dir
  316. SKIP: { my $meth = '__get_extract_dir';
  317.  
  318. ### get the right separator -- File::Spec does clean ups for
  319. ### paths, so we need to join ourselves.
  320. my $sep = [ split '', File::Spec->catfile( 'a', 'b' ) ]->[1];
  321.  
  322. ### bug #23999: Attempt to generate Makefile.PL gone awry
  323. ### showed that dirs in the style of './dir/' were reported
  324. ### to be unpacked in '.' rather than in 'dir'. here we test
  325. ### for this.
  326. for my $prefix ( '', '.' ) {
  327. skip "Prepending ./ to a valid path doesn't give you another valid path on VMS", 2
  328. if IS_VMS && length($prefix);
  329.  
  330. my $dir = basename( $SrcDir );
  331.  
  332. ### build a list like [dir, dir/file] and [./dir ./dir/file]
  333. ### where the dir and file actually exist, which is important
  334. ### for the method call
  335. my @files = map { length $prefix
  336. ? join $sep, $prefix, $_
  337. : $_
  338. } $dir, File::Spec->catfile( $dir, [keys %$tmpl]->[0] );
  339.  
  340. my $res = $Class->$meth( \@files );
  341. $res = &Win32::GetShortPathName( $res ) if IS_WIN32;
  342.  
  343. ok( $res, "Found extraction dir '$res'" );
  344. is( $res, $SrcDir, " Is expected dir '$SrcDir'" );
  345. }
  346. }
  347.  
  348. ### configuration to run in: allow perl or allow binaries
  349. for my $switch ( [0,1], [1,0] ) {
  350. my $cfg = "PP: $switch->[0] Bin: $switch->[1]";
  351.  
  352. local $Archive::Extract::_ALLOW_PURE_PERL = $switch->[0];
  353. local $Archive::Extract::_ALLOW_BIN = $switch->[1];
  354.  
  355. diag("Running extract with configuration: $cfg") if $Debug;
  356.  
  357. for my $archive (keys %$tmpl) {
  358. diag("Archive : $archive") if $Debug;
  359.  
  360. ### check first if we can do the proper
  361.  
  362. my $ae = Archive::Extract->new(
  363. archive => File::Spec->catfile($SrcDir,$archive) );
  364.  
  365. ### Do an extra run with _ALLOW_TAR_ITER = 0 if it's a tar file of some
  366. ### sort
  367. my @with_tar_iter = ( 1 );
  368. push @with_tar_iter, 0 if grep { $ae->$_ } qw[is_tbz is_tgz is_txz is_tar];
  369.  
  370. for my $tar_iter (@with_tar_iter) { SKIP: {
  371.  
  372. ### Doesn't matter unless .tar, .tbz, .tgz, .txz
  373. local $Archive::Extract::_ALLOW_TAR_ITER = $tar_iter;
  374.  
  375. diag("Archive::Tar->iter: $tar_iter") if $Debug;
  376.  
  377. isa_ok( $ae, $Class );
  378.  
  379. my $method = $tmpl->{$archive}->{method};
  380. ok( $ae->$method(), "Archive type $method recognized properly" );
  381.  
  382. my $file = $tmpl->{$archive}->{outfile};
  383. my $dir = $tmpl->{$archive}->{outdir}; # can be undef
  384. my $rel_path = File::Spec->catfile( grep { defined } $dir, $file );
  385. my $abs_path = File::Spec->catfile( $OutDir, $rel_path );
  386. my $abs_dir = File::Spec->catdir(
  387. grep { defined } $OutDir, $dir );
  388. my $nix_path = File::Spec::Unix->catfile(
  389. grep { defined } $dir, $file );
  390.  
  391. ### check if we can run this test ###
  392. my $pgm_fail; my $mod_fail;
  393. for my $pgm ( @{$tmpl->{$archive}->{programs}} ) {
  394. ### no binary extract method
  395. $pgm_fail++, next unless $pgm;
  396.  
  397. ### we dont have the program
  398. $pgm_fail++ unless $Archive::Extract::PROGRAMS->{$pgm} &&
  399. $Archive::Extract::PROGRAMS->{$pgm};
  400.  
  401. }
  402.  
  403. for my $mod ( @{$tmpl->{$archive}->{modules}} ) {
  404. ### no module extract method
  405. $mod_fail++, next unless $mod;
  406.  
  407. ### we dont have the module
  408. $mod_fail++ unless check_install( module => $mod );
  409. }
  410.  
  411. ### where to extract to -- try both dir and file for gz files
  412. ### XXX test me!
  413. #my @outs = $ae->is_gz ? ($abs_path, $OutDir) : ($OutDir);
  414. my @outs = $ae->is_gz || $ae->is_bz2 || $ae->is_Z || $ae->is_lzma || $ae->is_xz
  415. ? ($abs_path)
  416. : ($OutDir);
  417.  
  418. ### 10 tests from here on down ###
  419. if( ($mod_fail && ($pgm_fail || !$Archive::Extract::_ALLOW_BIN))
  420. ||
  421. ($pgm_fail && ($mod_fail || !$Archive::Extract::_ALLOW_PURE_PERL))
  422. ) {
  423. skip "No binaries or modules to extract ".$archive,
  424. (10 * scalar @outs);
  425. }
  426.  
  427. ### we dont warnings spewed about missing modules, that might
  428. ### be a problem...
  429. local $IPC::Cmd::WARN = 0;
  430. local $IPC::Cmd::WARN = 0;
  431.  
  432. for my $use_buffer ( IPC::Cmd->can_capture_buffer , 0 ) {
  433.  
  434. ### test buffers ###
  435. my $turn_off = !$use_buffer && !$pgm_fail &&
  436. $Archive::Extract::_ALLOW_BIN;
  437.  
  438. ### whitebox test ###
  439. ### stupid warnings ###
  440. local $IPC::Cmd::USE_IPC_RUN = 0 if $turn_off;
  441. local $IPC::Cmd::USE_IPC_RUN = 0 if $turn_off;
  442. local $IPC::Cmd::USE_IPC_OPEN3 = 0 if $turn_off;
  443. local $IPC::Cmd::USE_IPC_OPEN3 = 0 if $turn_off;
  444.  
  445.  
  446. ### try extracting ###
  447. for my $to ( @outs ) {
  448.  
  449. diag("Extracting to: $to") if $Debug;
  450. diag("Buffers enabled: ".!$turn_off) if $Debug;
  451.  
  452. my $rv = $ae->extract( to => $to );
  453.  
  454. SKIP: {
  455. my $re = qr/^No buffer captured/;
  456. my $err = $ae->error || '';
  457.  
  458. ### skip buffer tests if we dont have buffers or
  459. ### explicitly turned them off
  460. skip "No buffers available", 8
  461. if ( $turn_off || !IPC::Cmd->can_capture_buffer)
  462. && $err =~ $re;
  463.  
  464. ### skip tests if we dont have an extractor
  465. skip "No extractor available", 8
  466. if $err =~ /Extract failed; no extractors available/;
  467.  
  468. ### win32 + bin utils is notorious, and none of them are
  469. ### officially supported by strawberry. So if we
  470. ### encounter an error while extracting while running
  471. ### with $PREFER_BIN on win32, just skip the tests.
  472. ### See rt#46948: unable to install install on win32
  473. ### for details on the pain
  474. skip "Binary tools on Win32 are very unreliable", 8
  475. if $err and $Archive::Extract::_ALLOW_BIN
  476. and IS_WIN32;
  477.  
  478. ok( $rv, "extract() for '$archive' reports success ($cfg)");
  479.  
  480. diag("Extractor was: " . $ae->_extractor) if $Debug;
  481.  
  482. ### if we /should/ have buffers, there should be
  483. ### no errors complaining we dont have them...
  484. unlike( $err, $re,
  485. "No errors capturing buffers" );
  486.  
  487. ### might be 1 or 2, depending whether we extracted
  488. ### a dir too
  489. my $files = $ae->files || [];
  490. my $file_cnt = grep { defined } $file, $dir;
  491. is( scalar @$files, $file_cnt,
  492. "Found correct number of output files (@$files)" );
  493.  
  494. ### due to prototypes on is(), if there's no -1 index on
  495. ### the array ref, it'll give a fatal exception:
  496. ### "Modification of non-creatable array value attempted,
  497. ### subscript -1 at -e line 1." So wrap it in do { }
  498. is( do { $files->[-1] }, $nix_path,
  499. "Found correct output file '$nix_path'" );
  500.  
  501. ok( -e $abs_path,
  502. "Output file '$abs_path' exists" );
  503. ok( $ae->extract_path,
  504. "Extract dir found" );
  505. ok( -d $ae->extract_path,
  506. "Extract dir exists" );
  507. is( $ae->extract_path, $abs_dir,
  508. "Extract dir is expected '$abs_dir'" );
  509. }
  510.  
  511. SKIP: {
  512. skip "Unlink tests are unreliable on Win32", 3 if IS_WIN32;
  513.  
  514. 1 while unlink $abs_path;
  515. ok( !(-e $abs_path), "Output file successfully removed" );
  516.  
  517. SKIP: {
  518. skip "No extract path captured, can't remove paths", 2
  519. unless $ae->extract_path;
  520.  
  521. ### if something went wrong with determining the out
  522. ### path, don't go deleting stuff.. might be Really Bad
  523. my $out_re = quotemeta( $OutDir );
  524.  
  525. ### VMS directory layout is different. Craig Berry
  526. ### explains:
  527. ### the test is trying to determine if C</disk1/foo/bar>
  528. ### is part of C</disk1/foo/bar/baz>. Except in VMS
  529. ### syntax, that would mean trying to determine whether
  530. ### C<disk1:[foo.bar]> is part of C<disk1:[foo.bar.baz]>
  531. ### Because we have both a directory delimiter
  532. ### (dot) and a directory spec terminator (right
  533. ### bracket), we have to trim the right bracket from
  534. ### the first one to make it successfully match the
  535. ### second one. Since we're asserting the same truth --
  536. ### that one path spec is the leading part of the other
  537. ### -- it seems to me ok to have this in the test only.
  538. ###
  539. ### so we strip the ']' of the back of the regex
  540. $out_re =~ s/\\\]// if IS_VMS;
  541.  
  542. if( $ae->extract_path !~ /^$out_re/ ) {
  543. ok( 0, "Extractpath WRONG (".$ae->extract_path.")");
  544. skip( "Unsafe operation -- skip cleanup!!!" ), 1;
  545. }
  546.  
  547. eval { rmtree( $ae->extract_path ) };
  548. ok( !$@, " rmtree gave no error" );
  549. ok( !(-d $ae->extract_path ),
  550. " Extract dir successfully removed" );
  551. }
  552. }
  553. }
  554. }
  555. } }
  556. }
  557. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement