1b8851fccSafresh1#! /usr/bin/env perl 2b39c5158Smillert# Path.t -- tests for module File::Path 3b39c5158Smillert 4b39c5158Smillertuse strict; 5b39c5158Smillert 6*eac174f2Safresh1use Test::More tests => 167; 7b39c5158Smillertuse Config; 8b8851fccSafresh1use Fcntl ':mode'; 92e109fb9Safresh1use lib './t'; 102e109fb9Safresh1use FilePathTest qw( 112e109fb9Safresh1 _run_for_warning 122e109fb9Safresh1 _run_for_verbose 132e109fb9Safresh1 _cannot_delete_safe_mode 142e109fb9Safresh1 _verbose_expected 152e109fb9Safresh1 create_3_level_subdirs 162e109fb9Safresh1 cleanup_3_level_subdirs 172e109fb9Safresh1); 182e109fb9Safresh1use Errno qw(:POSIX); 192e109fb9Safresh1use Carp; 20b39c5158Smillert 21b39c5158SmillertBEGIN { 22b39c5158Smillert use_ok('Cwd'); 23b39c5158Smillert use_ok('File::Path', qw(rmtree mkpath make_path remove_tree)); 24b39c5158Smillert use_ok('File::Spec::Functions'); 25b39c5158Smillert} 26b39c5158Smillert 27b39c5158Smillertmy $Is_VMS = $^O eq 'VMS'; 28b39c5158Smillert 292e109fb9Safresh1my $fchmod_supported = 0; 302e109fb9Safresh1if (open my $fh, curdir()) { 312e109fb9Safresh1 my ($perm) = (stat($fh))[2]; 322e109fb9Safresh1 $perm &= 07777; 332e109fb9Safresh1 eval { $fchmod_supported = chmod( $perm, $fh); }; 342e109fb9Safresh1} 352e109fb9Safresh1 36b39c5158Smillert# first check for stupid permissions second for full, so we clean up 37b39c5158Smillert# behind ourselves 38b39c5158Smillertfor my $perm (0111,0777) { 39b39c5158Smillert my $path = catdir(curdir(), "mhx", "bar"); 40b39c5158Smillert mkpath($path); 41b39c5158Smillert chmod $perm, "mhx", $path; 42b39c5158Smillert 43b39c5158Smillert my $oct = sprintf('0%o', $perm); 44b8851fccSafresh1 45b39c5158Smillert ok(-d "mhx", "mkdir parent dir $oct"); 46b39c5158Smillert ok(-d $path, "mkdir child dir $oct"); 47b39c5158Smillert 48b39c5158Smillert rmtree("mhx"); 49b8851fccSafresh1 50b39c5158Smillert ok(! -e "mhx", "mhx does not exist $oct"); 51b39c5158Smillert} 52b39c5158Smillert 53b39c5158Smillert# find a place to work 54b39c5158Smillertmy ($error, $list, $file, $message); 55b39c5158Smillertmy $tmp_base = catdir( 56b39c5158Smillert curdir(), 57b39c5158Smillert sprintf( 'test-%x-%x-%x', time, $$, rand(99999) ), 58b39c5158Smillert); 59b39c5158Smillert 60b39c5158Smillert# invent some names 61b39c5158Smillertmy @dir = ( 62b39c5158Smillert catdir($tmp_base, qw(a b)), 63b39c5158Smillert catdir($tmp_base, qw(a c)), 64b39c5158Smillert catdir($tmp_base, qw(z b)), 65b39c5158Smillert catdir($tmp_base, qw(z c)), 66b39c5158Smillert); 67b39c5158Smillert 68b39c5158Smillert# create them 69b39c5158Smillertmy @created = mkpath([@dir]); 70b39c5158Smillert 71b39c5158Smillertis(scalar(@created), 7, "created list of directories"); 72b39c5158Smillert 73b39c5158Smillert# pray for no race conditions blowing them out from under us 74b39c5158Smillert@created = mkpath([$tmp_base]); 75b39c5158Smillertis(scalar(@created), 0, "skipped making existing directory") 76b39c5158Smillert or diag("unexpectedly recreated @created"); 77b39c5158Smillert 78b39c5158Smillert# create a file 79b39c5158Smillertmy $file_name = catfile( $tmp_base, 'a', 'delete.me' ); 80b39c5158Smillertmy $file_count = 0; 81b39c5158Smillertif (open OUT, "> $file_name") { 82b39c5158Smillert print OUT "this file may be deleted\n"; 83b39c5158Smillert close OUT; 84b39c5158Smillert ++$file_count; 85b39c5158Smillert} 86b39c5158Smillertelse { 87b39c5158Smillert diag( "Failed to create file $file_name: $!" ); 88b39c5158Smillert} 89b39c5158Smillert 90b39c5158SmillertSKIP: { 91b39c5158Smillert skip "cannot remove a file we failed to create", 1 92b39c5158Smillert unless $file_count == 1; 93b39c5158Smillert my $count = rmtree($file_name); 94b39c5158Smillert is($count, 1, "rmtree'ed a file"); 95b39c5158Smillert} 96b39c5158Smillert 97b39c5158Smillert@created = mkpath(''); 98b39c5158Smillertis(scalar(@created), 0, "Can't create a directory named ''"); 99b39c5158Smillert 100b39c5158Smillertmy $dir; 101b39c5158Smillertmy $dir2; 102b39c5158Smillert 103b39c5158Smillertsub gisle { 104b39c5158Smillert # background info: @_ = 1; !shift # gives '' not 0 105b39c5158Smillert # Message-Id: <3C820CE6-4400-4E91-AF43-A3D19B356E68@activestate.com> 106b39c5158Smillert # http://www.nntp.perl.org/group/perl.perl5.porters/2008/05/msg136625.html 107b39c5158Smillert mkpath(shift, !shift, 0755); 108b39c5158Smillert} 109b39c5158Smillert 110b39c5158Smillertsub count { 111b39c5158Smillert opendir D, shift or return -1; 112b39c5158Smillert my $count = () = readdir D; 113b39c5158Smillert closedir D or return -1; 114b39c5158Smillert return $count; 115b39c5158Smillert} 116b39c5158Smillert 117b39c5158Smillert{ 118b39c5158Smillert mkdir 'solo', 0755; 119b39c5158Smillert chdir 'solo'; 120b39c5158Smillert open my $f, '>', 'foo.dat'; 121b39c5158Smillert close $f; 122b39c5158Smillert my $before = count(curdir()); 123b39c5158Smillert cmp_ok($before, '>', 0, "baseline $before"); 124b39c5158Smillert 125b39c5158Smillert gisle('1st', 1); 126b39c5158Smillert is(count(curdir()), $before + 1, "first after $before"); 127b39c5158Smillert 128b39c5158Smillert $before = count(curdir()); 129b39c5158Smillert gisle('2nd', 1); 130b8851fccSafresh1 131b39c5158Smillert is(count(curdir()), $before + 1, "second after $before"); 132b39c5158Smillert 133b39c5158Smillert chdir updir(); 134b39c5158Smillert rmtree 'solo'; 135b39c5158Smillert} 136b39c5158Smillert 137b39c5158Smillert{ 138b39c5158Smillert mkdir 'solo', 0755; 139b39c5158Smillert chdir 'solo'; 140b39c5158Smillert open my $f, '>', 'foo.dat'; 141b39c5158Smillert close $f; 142b39c5158Smillert my $before = count(curdir()); 143b8851fccSafresh1 144b39c5158Smillert cmp_ok($before, '>', 0, "ARGV $before"); 145b39c5158Smillert { 146b39c5158Smillert local @ARGV = (1); 147b39c5158Smillert mkpath('3rd', !shift, 0755); 148b39c5158Smillert } 149b8851fccSafresh1 150b39c5158Smillert is(count(curdir()), $before + 1, "third after $before"); 151b39c5158Smillert 152b39c5158Smillert $before = count(curdir()); 153b39c5158Smillert { 154b39c5158Smillert local @ARGV = (1); 155b39c5158Smillert mkpath('4th', !shift, 0755); 156b39c5158Smillert } 157b8851fccSafresh1 158b39c5158Smillert is(count(curdir()), $before + 1, "fourth after $before"); 159b39c5158Smillert 160b39c5158Smillert chdir updir(); 161b39c5158Smillert rmtree 'solo'; 162b39c5158Smillert} 163b39c5158Smillert 164b39c5158SmillertSKIP: { 165b39c5158Smillert # tests for rmtree() of ancestor directory 166b39c5158Smillert my $nr_tests = 6; 167b39c5158Smillert my $cwd = getcwd() or skip "failed to getcwd: $!", $nr_tests; 168b39c5158Smillert my $dir = catdir($cwd, 'remove'); 169b39c5158Smillert my $dir2 = catdir($cwd, 'remove', 'this', 'dir'); 170b39c5158Smillert 171b39c5158Smillert skip "failed to mkpath '$dir2': $!", $nr_tests 172b39c5158Smillert unless mkpath($dir2, {verbose => 0}); 173b39c5158Smillert skip "failed to chdir dir '$dir2': $!", $nr_tests 174b39c5158Smillert unless chdir($dir2); 175b39c5158Smillert 176b39c5158Smillert rmtree($dir, {error => \$error}); 177b39c5158Smillert my $nr_err = @$error; 178b8851fccSafresh1 179b39c5158Smillert is($nr_err, 1, "ancestor error"); 180b39c5158Smillert 181b39c5158Smillert if ($nr_err) { 182b39c5158Smillert my ($file, $message) = each %{$error->[0]}; 183b8851fccSafresh1 184b39c5158Smillert is($file, $dir, "ancestor named"); 185b39c5158Smillert my $ortho_dir = $^O eq 'MSWin32' ? File::Path::_slash_lc($dir2) : $dir2; 186b39c5158Smillert $^O eq 'MSWin32' and $message 187b39c5158Smillert =~ s/\A(cannot remove path when cwd is )(.*)\Z/$1 . File::Path::_slash_lc($2)/e; 188b8851fccSafresh1 189b39c5158Smillert is($message, "cannot remove path when cwd is $ortho_dir", "ancestor reason"); 190b8851fccSafresh1 191b39c5158Smillert ok(-d $dir2, "child not removed"); 192b8851fccSafresh1 193b39c5158Smillert ok(-d $dir, "ancestor not removed"); 194b39c5158Smillert } 195b39c5158Smillert else { 196b39c5158Smillert fail( "ancestor 1"); 197b39c5158Smillert fail( "ancestor 2"); 198b39c5158Smillert fail( "ancestor 3"); 199b39c5158Smillert fail( "ancestor 4"); 200b39c5158Smillert } 201b39c5158Smillert chdir $cwd; 202b39c5158Smillert rmtree($dir); 203b8851fccSafresh1 204b39c5158Smillert ok(!(-d $dir), "ancestor now removed"); 205b39c5158Smillert}; 206b39c5158Smillert 207b39c5158Smillertmy $count = rmtree({error => \$error}); 208b8851fccSafresh1 209b39c5158Smillertis( $count, 0, 'rmtree of nothing, count of zero' ); 210b8851fccSafresh1 211b39c5158Smillertis( scalar(@$error), 0, 'no diagnostic captured' ); 212b39c5158Smillert 213b39c5158Smillert@created = mkpath($tmp_base, 0); 214b8851fccSafresh1 215b39c5158Smillertis(scalar(@created), 0, "skipped making existing directories (old style 1)") 216b39c5158Smillert or diag("unexpectedly recreated @created"); 217b39c5158Smillert 218b39c5158Smillert$dir = catdir($tmp_base,'C'); 219b39c5158Smillert# mkpath returns unix syntax filespecs on VMS 220b39c5158Smillert$dir = VMS::Filespec::unixify($dir) if $Is_VMS; 221b39c5158Smillert@created = make_path($tmp_base, $dir); 222b8851fccSafresh1 223b39c5158Smillertis(scalar(@created), 1, "created directory (new style 1)"); 224b8851fccSafresh1 225b39c5158Smillertis($created[0], $dir, "created directory (new style 1) cross-check"); 226b39c5158Smillert 227b39c5158Smillert@created = mkpath($tmp_base, 0, 0700); 228b8851fccSafresh1 229b39c5158Smillertis(scalar(@created), 0, "skipped making existing directories (old style 2)") 230b39c5158Smillert or diag("unexpectedly recreated @created"); 231b39c5158Smillert 232b39c5158Smillert$dir2 = catdir($tmp_base,'D'); 233b39c5158Smillert# mkpath returns unix syntax filespecs on VMS 234b39c5158Smillert$dir2 = VMS::Filespec::unixify($dir2) if $Is_VMS; 235b39c5158Smillert@created = make_path($tmp_base, $dir, $dir2); 236b8851fccSafresh1 237b39c5158Smillertis(scalar(@created), 1, "created directory (new style 2)"); 238b8851fccSafresh1 239b39c5158Smillertis($created[0], $dir2, "created directory (new style 2) cross-check"); 240b39c5158Smillert 241b39c5158Smillert$count = rmtree($dir, 0); 242b8851fccSafresh1 243b39c5158Smillertis($count, 1, "removed directory unsafe mode"); 244b39c5158Smillert 245b8851fccSafresh1my $expected_count = _cannot_delete_safe_mode($dir2) ? 0 : 1; 246b8851fccSafresh1 247b39c5158Smillert$count = rmtree($dir2, 0, 1); 248b8851fccSafresh1 249b8851fccSafresh1is($count, $expected_count, "removed directory safe mode"); 250b39c5158Smillert 251b39c5158Smillert# mkdir foo ./E/../Y 252b39c5158Smillert# Y should exist 253b39c5158Smillert# existence of E is neither here nor there 254b39c5158Smillert$dir = catdir($tmp_base, 'E', updir(), 'Y'); 255b39c5158Smillert@created =mkpath($dir); 256b8851fccSafresh1 257b39c5158Smillertcmp_ok(scalar(@created), '>=', 1, "made one or more dirs because of .."); 258b8851fccSafresh1 259b39c5158Smillertcmp_ok(scalar(@created), '<=', 2, "made less than two dirs because of .."); 260b8851fccSafresh1 261b39c5158Smillertok( -d catdir($tmp_base, 'Y'), "directory after parent" ); 262b39c5158Smillert 263b39c5158Smillert@created = make_path(catdir(curdir(), $tmp_base)); 264b8851fccSafresh1 265b39c5158Smillertis(scalar(@created), 0, "nothing created") 266b39c5158Smillert or diag(@created); 267b39c5158Smillert 268b39c5158Smillert$dir = catdir($tmp_base, 'a'); 269b39c5158Smillert$dir2 = catdir($tmp_base, 'z'); 270b39c5158Smillert 271b39c5158Smillertrmtree( $dir, $dir2, 272b39c5158Smillert { 273b39c5158Smillert error => \$error, 274b39c5158Smillert result => \$list, 275b39c5158Smillert keep_root => 1, 276b39c5158Smillert } 277b39c5158Smillert); 278b39c5158Smillert 279b8851fccSafresh1 280b39c5158Smillertis(scalar(@$error), 0, "no errors unlinking a and z"); 281b8851fccSafresh1 282b39c5158Smillertis(scalar(@$list), 4, "list contains 4 elements") 283b39c5158Smillert or diag("@$list"); 284b39c5158Smillert 285b39c5158Smillertok(-d $dir, "dir a still exists"); 286b8851fccSafresh1 287b39c5158Smillertok(-d $dir2, "dir z still exists"); 288b39c5158Smillert 289b39c5158Smillert$dir = catdir($tmp_base,'F'); 290b39c5158Smillert# mkpath returns unix syntax filespecs on VMS 291b39c5158Smillert$dir = VMS::Filespec::unixify($dir) if $Is_VMS; 292b39c5158Smillert 293b39c5158Smillert@created = mkpath($dir, undef, 0770); 294b8851fccSafresh1 295b39c5158Smillertis(scalar(@created), 1, "created directory (old style 2 verbose undef)"); 296b8851fccSafresh1 297b39c5158Smillertis($created[0], $dir, "created directory (old style 2 verbose undef) cross-check"); 298b8851fccSafresh1 299b39c5158Smillertis(rmtree($dir, undef, 0), 1, "removed directory 2 verbose undef"); 300b39c5158Smillert 301b39c5158Smillert@created = mkpath($dir, undef); 302b8851fccSafresh1 303b39c5158Smillertis(scalar(@created), 1, "created directory (old style 2a verbose undef)"); 304b8851fccSafresh1 305b39c5158Smillertis($created[0], $dir, "created directory (old style 2a verbose undef) cross-check"); 306b8851fccSafresh1 307b39c5158Smillertis(rmtree($dir, undef), 1, "removed directory 2a verbose undef"); 308b39c5158Smillert 309b39c5158Smillert@created = mkpath($dir, 0, undef); 310b8851fccSafresh1 311b39c5158Smillertis(scalar(@created), 1, "created directory (old style 3 mode undef)"); 312b8851fccSafresh1 313b39c5158Smillertis($created[0], $dir, "created directory (old style 3 mode undef) cross-check"); 314b8851fccSafresh1 315b39c5158Smillertis(rmtree($dir, 0, undef), 1, "removed directory 3 verbose undef"); 316b39c5158Smillert 3172e109fb9Safresh1SKIP: { 3182e109fb9Safresh1 skip "fchmod of directories not supported on this platform", 3 unless $fchmod_supported; 319b39c5158Smillert $dir = catdir($tmp_base,'G'); 320b39c5158Smillert $dir = VMS::Filespec::unixify($dir) if $Is_VMS; 321b39c5158Smillert 3222e109fb9Safresh1 @created = mkpath($dir, undef, 0400); 323b8851fccSafresh1 3242e109fb9Safresh1 is(scalar(@created), 1, "created read-only dir"); 325b8851fccSafresh1 3262e109fb9Safresh1 is($created[0], $dir, "created read-only directory cross-check"); 327b8851fccSafresh1 3282e109fb9Safresh1 is(rmtree($dir), 1, "removed read-only dir"); 3292e109fb9Safresh1} 330b39c5158Smillert 331b39c5158Smillert# borderline new-style heuristics 332b39c5158Smillertif (chdir $tmp_base) { 333b39c5158Smillert pass("chdir to temp dir"); 334b39c5158Smillert} 335b39c5158Smillertelse { 336b39c5158Smillert fail("chdir to temp dir: $!"); 337b39c5158Smillert} 338b39c5158Smillert 339b39c5158Smillert$dir = catdir('a', 'd1'); 340b39c5158Smillert$dir2 = catdir('a', 'd2'); 341b39c5158Smillert 342b39c5158Smillert@created = make_path( $dir, 0, $dir2 ); 343b8851fccSafresh1 344b39c5158Smillertis(scalar @created, 3, 'new-style 3 dirs created'); 345b39c5158Smillert 346b39c5158Smillert$count = remove_tree( $dir, 0, $dir2, ); 347b8851fccSafresh1 348b39c5158Smillertis($count, 3, 'new-style 3 dirs removed'); 349b39c5158Smillert 350b39c5158Smillert@created = make_path( $dir, $dir2, 1 ); 351b8851fccSafresh1 352b39c5158Smillertis(scalar @created, 3, 'new-style 3 dirs created (redux)'); 353b39c5158Smillert 354b39c5158Smillert$count = remove_tree( $dir, $dir2, 1 ); 355b8851fccSafresh1 356b39c5158Smillertis($count, 3, 'new-style 3 dirs removed (redux)'); 357b39c5158Smillert 358b39c5158Smillert@created = make_path( $dir, $dir2 ); 359b8851fccSafresh1 360b39c5158Smillertis(scalar @created, 2, 'new-style 2 dirs created'); 361b39c5158Smillert 362b39c5158Smillert$count = remove_tree( $dir, $dir2 ); 363b8851fccSafresh1 364b39c5158Smillertis($count, 2, 'new-style 2 dirs removed'); 365b39c5158Smillert 366b8851fccSafresh1$dir = catdir("a\nb", 'd1'); 367b8851fccSafresh1$dir2 = catdir("a\nb", 'd2'); 368b8851fccSafresh1 369b8851fccSafresh1SKIP: { 370b8851fccSafresh1 # Better to search for *nix derivatives? 371b8851fccSafresh1 # Not sure what else doesn't support newline in paths 372b8851fccSafresh1 skip "$^O doesn't allow newline in paths", 2 373b8851fccSafresh1 if $^O =~ m/^(MSWin32|VMS)$/; 374b8851fccSafresh1 375b8851fccSafresh1 @created = make_path( $dir, $dir2 ); 376b8851fccSafresh1 377b8851fccSafresh1 is(scalar @created, 3, 'new-style 3 dirs created in parent with newline'); 378b8851fccSafresh1 379b8851fccSafresh1 $count = remove_tree( $dir, $dir2 ); 380b8851fccSafresh1 381b8851fccSafresh1 is($count, 2, 'new-style 2 dirs removed in parent with newline'); 382b8851fccSafresh1} 383b8851fccSafresh1 384b39c5158Smillertif (chdir updir()) { 385b39c5158Smillert pass("chdir parent"); 386b39c5158Smillert} 387b39c5158Smillertelse { 388b39c5158Smillert fail("chdir parent: $!"); 389b39c5158Smillert} 390b39c5158Smillert 391b39c5158SmillertSKIP: { 392b39c5158Smillert # test bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=487319 393b8851fccSafresh1 skip "Don't need Force_Writeable semantics on $^O", 6 394b39c5158Smillert if grep {$^O eq $_} qw(amigaos dos epoc MSWin32 MacOS os2); 395b8851fccSafresh1 skip "Symlinks not available", 6 unless $Config{d_symlink}; 396b39c5158Smillert $dir = 'bug487319'; 397b39c5158Smillert $dir2 = 'bug487319-symlink'; 398b39c5158Smillert @created = make_path($dir, {mask => 0700}); 399b8851fccSafresh1 400b39c5158Smillert is( scalar @created, 1, 'bug 487319 setup' ); 401b39c5158Smillert symlink($dir, $dir2); 402b8851fccSafresh1 403b39c5158Smillert ok(-e $dir2, "debian bug 487319 setup symlink") or diag($dir2); 404b39c5158Smillert 405b39c5158Smillert chmod 0500, $dir; 406b39c5158Smillert my $mask_initial = (stat $dir)[2]; 407b39c5158Smillert remove_tree($dir2); 408b39c5158Smillert 409b39c5158Smillert my $mask = (stat $dir)[2]; 410b8851fccSafresh1 411b39c5158Smillert is( $mask, $mask_initial, 'mask of symlink target dir unchanged (debian bug 487319)'); 412b39c5158Smillert 413b39c5158Smillert # now try a file 414b8851fccSafresh1 #my $file = catfile($dir, 'file'); 415b8851fccSafresh1 my $file = 'bug487319-file'; 416b8851fccSafresh1 my $file2 = 'bug487319-file-symlink'; 417b39c5158Smillert open my $out, '>', $file; 418b39c5158Smillert close $out; 419b39c5158Smillert 420b8851fccSafresh1 ok(-e $file, 'file exists'); 421b8851fccSafresh1 422b39c5158Smillert chmod 0500, $file; 423b39c5158Smillert $mask_initial = (stat $file)[2]; 424b39c5158Smillert 425b39c5158Smillert symlink($file, $file2); 426b8851fccSafresh1 427b8851fccSafresh1 ok(-e $file2, 'file2 exists'); 428b39c5158Smillert remove_tree($file2); 429b39c5158Smillert 430b39c5158Smillert $mask = (stat $file)[2]; 431b8851fccSafresh1 432b39c5158Smillert is( $mask, $mask_initial, 'mask of symlink target file unchanged (debian bug 487319)'); 433b39c5158Smillert 434b39c5158Smillert remove_tree($dir); 435b8851fccSafresh1 remove_tree($file); 436b39c5158Smillert} 437b39c5158Smillert 438b39c5158Smillert# see what happens if a file exists where we want a directory 439b39c5158SmillertSKIP: { 440b8851fccSafresh1 my $entry = catfile($tmp_base, "file"); 441b8851fccSafresh1 skip "VMS can have a file and a directory with the same name.", 4 442b8851fccSafresh1 if $Is_VMS; 443b39c5158Smillert skip "Cannot create $entry", 4 unless open OUT, "> $entry"; 444b39c5158Smillert print OUT "test file, safe to delete\n", scalar(localtime), "\n"; 445b39c5158Smillert close OUT; 446b39c5158Smillert ok(-e $entry, "file exists in place of directory"); 447b39c5158Smillert 448b39c5158Smillert mkpath( $entry, {error => \$error} ); 449b39c5158Smillert is( scalar(@$error), 1, "caught error condition" ); 450b39c5158Smillert ($file, $message) = each %{$error->[0]}; 451b39c5158Smillert is( $entry, $file, "and the message is: $message"); 452b39c5158Smillert 453b39c5158Smillert eval {@created = mkpath($entry, 0, 0700)}; 454b39c5158Smillert $error = $@; 455b39c5158Smillert chomp $error; # just to remove silly # in TAP output 456b39c5158Smillert cmp_ok( $error, 'ne', "", "no directory created (old-style) err=$error" ) 457b39c5158Smillert or diag(@created); 458b39c5158Smillert} 459b39c5158Smillert 460b39c5158Smillert{ 461b39c5158Smillert $dir = catdir($tmp_base, 'ZZ'); 462b39c5158Smillert @created = mkpath($dir); 463b39c5158Smillert is(scalar(@created), 1, "create a ZZ directory"); 464b39c5158Smillert 465b39c5158Smillert local @ARGV = ($dir); 466b39c5158Smillert rmtree( [grep -e $_, @ARGV], 0, 0 ); 467b39c5158Smillert ok(!-e $dir, "blow it away via \@ARGV"); 468b39c5158Smillert} 469b39c5158Smillert 470b39c5158SmillertSKIP : { 4712e109fb9Safresh1 my $skip_count = 18; 472b8851fccSafresh1 # this test will fail on Windows, as per: 473b8851fccSafresh1 # http://perldoc.perl.org/perlport.html#chmod 474b39c5158Smillert 475b8851fccSafresh1 skip "Windows chmod test skipped", $skip_count 476b8851fccSafresh1 if $^O eq 'MSWin32'; 4772e109fb9Safresh1 skip "fchmod() on directories is not supported on this platform", $skip_count 4782e109fb9Safresh1 unless $fchmod_supported; 479b8851fccSafresh1 my $mode; 480b8851fccSafresh1 my $octal_mode; 481b8851fccSafresh1 my @inputs = ( 4822e109fb9Safresh1 0777, 0700, 0470, 0407, 4832e109fb9Safresh1 0433, 0400, 0430, 0403, 4842e109fb9Safresh1 0111, 0100, 0110, 0101, 4852e109fb9Safresh1 0731, 0713, 0317, 0371, 4862e109fb9Safresh1 0173, 0137); 487b8851fccSafresh1 my $input; 488b8851fccSafresh1 my $octal_input; 489b39c5158Smillert 490b8851fccSafresh1 foreach (@inputs) { 491b8851fccSafresh1 $input = $_; 4922e109fb9Safresh1 $dir = catdir($tmp_base, sprintf("chmod_test%04o", $input)); 493b8851fccSafresh1 # We can skip from here because 0 is last in the list. 494b8851fccSafresh1 skip "Mode of 0 means assume user defaults on VMS", 1 495b8851fccSafresh1 if ($input == 0 && $Is_VMS); 496b8851fccSafresh1 @created = mkpath($dir, {chmod => $input}); 497b8851fccSafresh1 $mode = (stat($dir))[2]; 498b8851fccSafresh1 $octal_mode = S_IMODE($mode); 499b8851fccSafresh1 $octal_input = sprintf "%04o", S_IMODE($input); 5002e109fb9Safresh1 SKIP: { 5012e109fb9Safresh1 skip "permissions are not fully supported by the filesystem", 1 5022e109fb9Safresh1 if (($^O eq 'MSWin32' || $^O eq 'cygwin') && ((Win32::FsType())[1] & 8) == 0); 503b8851fccSafresh1 is($octal_mode,$input, "create a new directory with chmod $input ($octal_input)"); 5042e109fb9Safresh1 } 505b8851fccSafresh1 rmtree( $dir ); 506b39c5158Smillert } 507b39c5158Smillert} 508b39c5158Smillert 509b8851fccSafresh1my $dir_base = catdir($tmp_base,'output'); 510b8851fccSafresh1my $dir_a = catdir($dir_base, 'A'); 511b8851fccSafresh1my $dir_b = catdir($dir_base, 'B'); 512b39c5158Smillert 513b8851fccSafresh1is(_run_for_verbose(sub {@created = mkpath($dir_a, 1)}), 514b8851fccSafresh1 _verbose_expected('mkpath', $dir_base, 0, 1) 515b8851fccSafresh1 . _verbose_expected('mkpath', $dir_a, 0), 516b39c5158Smillert 'mkpath verbose (old style 1)' 517b39c5158Smillert); 518b39c5158Smillert 519b8851fccSafresh1is(_run_for_verbose(sub {@created = mkpath([$dir_b], 1)}), 520b8851fccSafresh1 _verbose_expected('mkpath', $dir_b, 0), 521b39c5158Smillert 'mkpath verbose (old style 2)' 522b39c5158Smillert); 523b39c5158Smillert 524b8851fccSafresh1my $verbose_expected; 525b8851fccSafresh1 526b8851fccSafresh1# Must determine expectations while directories still exist. 527b8851fccSafresh1$verbose_expected = _verbose_expected('rmtree', $dir_a, 1) 528b8851fccSafresh1 . _verbose_expected('rmtree', $dir_b, 1); 529b8851fccSafresh1 530b8851fccSafresh1is(_run_for_verbose(sub {$count = rmtree([$dir_a, $dir_b], 1, 1)}), 531b8851fccSafresh1 $verbose_expected, 532b39c5158Smillert 'rmtree verbose (old style)' 533b39c5158Smillert); 534b39c5158Smillert 535b8851fccSafresh1# In case we didn't delete them in safe mode. 536b8851fccSafresh1rmtree($dir_a) if -d $dir_a; 537b8851fccSafresh1rmtree($dir_b) if -d $dir_b; 538b8851fccSafresh1 539b8851fccSafresh1is(_run_for_verbose(sub {@created = mkpath( $dir_a, 540b8851fccSafresh1 {verbose => 1, mask => 0750})}), 541b8851fccSafresh1 _verbose_expected('mkpath', $dir_a, 0), 542b39c5158Smillert 'mkpath verbose (new style 1)' 543b39c5158Smillert); 544b39c5158Smillert 545b8851fccSafresh1is(_run_for_verbose(sub {@created = mkpath($dir_b, 1, 0771)}), 546b8851fccSafresh1 _verbose_expected('mkpath', $dir_b, 0), 547b39c5158Smillert 'mkpath verbose (new style 2)' 548b39c5158Smillert); 549b39c5158Smillert 550b8851fccSafresh1$verbose_expected = _verbose_expected('rmtree', $dir_a, 1) 551b8851fccSafresh1 . _verbose_expected('rmtree', $dir_b, 1); 552b8851fccSafresh1 553b8851fccSafresh1is(_run_for_verbose(sub {$count = rmtree([$dir_a, $dir_b], 1, 1)}), 554b8851fccSafresh1 $verbose_expected, 555b8851fccSafresh1 'again: rmtree verbose (old style)' 556b8851fccSafresh1); 557b8851fccSafresh1 558b8851fccSafresh1rmtree($dir_a) if -d $dir_a; 559b8851fccSafresh1rmtree($dir_b) if -d $dir_b; 560b8851fccSafresh1 561b8851fccSafresh1is(_run_for_verbose(sub {@created = make_path( $dir_a, $dir_b, 562b8851fccSafresh1 {verbose => 1, mode => 0711});}), 563b8851fccSafresh1 _verbose_expected('make_path', $dir_a, 1) 564b8851fccSafresh1 . _verbose_expected('make_path', $dir_b, 1), 565b8851fccSafresh1 'make_path verbose with final hashref' 566b8851fccSafresh1); 567b8851fccSafresh1 568b8851fccSafresh1$verbose_expected = _verbose_expected('remove_tree', $dir_a, 0) 569b8851fccSafresh1 . _verbose_expected('remove_tree', $dir_b, 0); 570b8851fccSafresh1 571b8851fccSafresh1is(_run_for_verbose(sub {@created = remove_tree( $dir_a, $dir_b, 572b8851fccSafresh1 {verbose => 1});}), 573b8851fccSafresh1 $verbose_expected, 574b8851fccSafresh1 'remove_tree verbose with final hashref' 575b8851fccSafresh1); 576b8851fccSafresh1 577b8851fccSafresh1rmtree($dir_a) if -d $dir_a; 578b8851fccSafresh1rmtree($dir_b) if -d $dir_b; 579b8851fccSafresh1 580b8851fccSafresh1# Have to re-create these 2 directories so that next block is not skipped. 581b8851fccSafresh1@created = make_path( 582b8851fccSafresh1 $dir_a, 583b8851fccSafresh1 $dir_b, 584b8851fccSafresh1 { mode => 0711 } 585b8851fccSafresh1); 586b8851fccSafresh1is(@created, 2, "2 directories created"); 587b8851fccSafresh1 588b39c5158SmillertSKIP: { 589b8851fccSafresh1 $file = catfile($dir_b, "file"); 590b39c5158Smillert skip "Cannot create $file", 2 unless open OUT, "> $file"; 591b39c5158Smillert print OUT "test file, safe to delete\n", scalar(localtime), "\n"; 592b39c5158Smillert close OUT; 593b39c5158Smillert 594b8851fccSafresh1 $verbose_expected = _verbose_expected('rmtree', $dir_a, 1) 595b8851fccSafresh1 . _verbose_expected('unlink', $file, 0) 596b8851fccSafresh1 . _verbose_expected('rmtree', $dir_b, 1); 597b8851fccSafresh1 598b39c5158Smillert ok(-e $file, "file created in directory"); 599b39c5158Smillert 600b8851fccSafresh1 is(_run_for_verbose(sub {$count = rmtree( $dir_a, $dir_b, 601b8851fccSafresh1 {verbose => 1, safe => 1})}), 602b8851fccSafresh1 $verbose_expected, 603b39c5158Smillert 'rmtree safe verbose (new style)' 604b39c5158Smillert ); 605b8851fccSafresh1 rmtree($dir_a) if -d $dir_a; 606b8851fccSafresh1 rmtree($dir_b) if -d $dir_b; 607b39c5158Smillert} 608b39c5158Smillert 609b8851fccSafresh1{ 610b8851fccSafresh1 my $base = catdir( $tmp_base, 'output2'); 611b8851fccSafresh1 my $dir = catdir( $base, 'A'); 612b8851fccSafresh1 my $dir2 = catdir( $base, 'B'); 613b39c5158Smillert 614b8851fccSafresh1 { 6152e109fb9Safresh1 my $warn = _run_for_warning( sub { 616b8851fccSafresh1 my @created = make_path( 617b8851fccSafresh1 $dir, 618b8851fccSafresh1 $dir2, 619b8851fccSafresh1 { mode => 0711, foo => 1, bar => 1 } 620b8851fccSafresh1 ); 6212e109fb9Safresh1 } ); 622b8851fccSafresh1 like($warn, 6232e109fb9Safresh1 qr/Unrecognized option\(s\) passed to mkpath\(\) or make_path\(\):.*?bar.*?foo/, 624b8851fccSafresh1 'make_path with final hashref warned due to unrecognized options' 625b8851fccSafresh1 ); 626b39c5158Smillert } 627b8851fccSafresh1 628b8851fccSafresh1 { 6292e109fb9Safresh1 my $warn = _run_for_warning( sub { 630b8851fccSafresh1 my @created = remove_tree( 631b8851fccSafresh1 $dir, 632b8851fccSafresh1 $dir2, 633b8851fccSafresh1 { foo => 1, bar => 1 } 634b8851fccSafresh1 ); 6352e109fb9Safresh1 } ); 636b8851fccSafresh1 like($warn, 637b8851fccSafresh1 qr/Unrecognized option\(s\) passed to remove_tree\(\):.*?bar.*?foo/, 638b8851fccSafresh1 'remove_tree with final hashref failed due to unrecognized options' 639b8851fccSafresh1 ); 640b39c5158Smillert } 641b39c5158Smillert} 642b39c5158Smillert 643b39c5158SmillertSKIP: { 644b39c5158Smillert my $nr_tests = 6; 645b39c5158Smillert my $cwd = getcwd() or skip "failed to getcwd: $!", $nr_tests; 646b39c5158Smillert rmtree($tmp_base, {result => \$list} ); 647b39c5158Smillert is(ref($list), 'ARRAY', "received a final list of results"); 648b39c5158Smillert ok( !(-d $tmp_base), "test base directory gone" ); 649b39c5158Smillert 650b39c5158Smillert my $p = getcwd(); 651b39c5158Smillert my $x = "x$$"; 652b39c5158Smillert my $xx = $x . "x"; 653b39c5158Smillert 654b39c5158Smillert # setup 655b39c5158Smillert ok(mkpath($xx), "make $xx"); 656b39c5158Smillert ok(chdir($xx), "... and chdir $xx"); 657b39c5158Smillert END { 658b8851fccSafresh1# ok(chdir($p), "... now chdir $p"); 659b8851fccSafresh1# ok(rmtree($xx), "... and finally rmtree $xx"); 660b8851fccSafresh1 chdir($p); 661b8851fccSafresh1 rmtree($xx); 662b39c5158Smillert } 663b39c5158Smillert 664b39c5158Smillert # create and delete directory 665b39c5158Smillert my $px = catdir($p, $x); 666b39c5158Smillert ok(mkpath($px), 'create and delete directory 2.07'); 667b39c5158Smillert ok(rmtree($px), '.. rmtree fails in File-Path-2.07'); 668b8851fccSafresh1 chdir updir(); 669b8851fccSafresh1} 670b8851fccSafresh1 671b8851fccSafresh1my $windows_dir = 'C:\Path\To\Dir'; 672b8851fccSafresh1my $expect = 'c:/path/to/dir'; 673b8851fccSafresh1is( 674b8851fccSafresh1 File::Path::_slash_lc($windows_dir), 675b8851fccSafresh1 $expect, 676b8851fccSafresh1 "Windows path unixified as expected" 677b8851fccSafresh1); 678b8851fccSafresh1 679b8851fccSafresh1{ 680b8851fccSafresh1 my ($x, $message, $object, $expect, $rv, $arg, $error); 681b8851fccSafresh1 my ($k, $v, $second_error, $third_error); 6822e109fb9Safresh1 local $! = ENOENT; 683b8851fccSafresh1 $x = $!; 684b8851fccSafresh1 685b8851fccSafresh1 $message = 'message in a bottle'; 686b8851fccSafresh1 $object = '/path/to/glory'; 687b8851fccSafresh1 $expect = "$message for $object: $x"; 688b8851fccSafresh1 $rv = _run_for_warning( sub { 689b8851fccSafresh1 File::Path::_error( 690b8851fccSafresh1 {}, 691b8851fccSafresh1 $message, 692b8851fccSafresh1 $object 693b8851fccSafresh1 ); 694b8851fccSafresh1 } ); 695b8851fccSafresh1 like($rv, qr/^$expect/, 696b8851fccSafresh1 "no \$arg->{error}: defined 2nd and 3rd args: got expected error message"); 697b8851fccSafresh1 698b8851fccSafresh1 $object = undef; 699b8851fccSafresh1 $expect = "$message: $x"; 700b8851fccSafresh1 $rv = _run_for_warning( sub { 701b8851fccSafresh1 File::Path::_error( 702b8851fccSafresh1 {}, 703b8851fccSafresh1 $message, 704b8851fccSafresh1 $object 705b8851fccSafresh1 ); 706b8851fccSafresh1 } ); 707b8851fccSafresh1 like($rv, qr/^$expect/, 708b8851fccSafresh1 "no \$arg->{error}: defined 2nd arg; undefined 3rd arg: got expected error message"); 709b8851fccSafresh1 710b8851fccSafresh1 $message = 'message in a bottle'; 711b8851fccSafresh1 $object = undef; 712b8851fccSafresh1 $expect = "$message: $x"; 713b8851fccSafresh1 $arg = { error => \$error }; 714b8851fccSafresh1 File::Path::_error( 715b8851fccSafresh1 $arg, 716b8851fccSafresh1 $message, 717b8851fccSafresh1 $object 718b8851fccSafresh1 ); 719b8851fccSafresh1 is(ref($error->[0]), 'HASH', 720b8851fccSafresh1 "first element of array inside \$error is hashref"); 721b8851fccSafresh1 ($k, $v) = %{$error->[0]}; 722b8851fccSafresh1 is($k, '', 'key of hash is empty string, since 3rd arg was undef'); 723b8851fccSafresh1 is($v, $expect, "value of hash is 2nd arg: $message"); 724b8851fccSafresh1 725b8851fccSafresh1 $message = ''; 726b8851fccSafresh1 $object = '/path/to/glory'; 727b8851fccSafresh1 $expect = "$message: $x"; 728b8851fccSafresh1 $arg = { error => \$second_error }; 729b8851fccSafresh1 File::Path::_error( 730b8851fccSafresh1 $arg, 731b8851fccSafresh1 $message, 732b8851fccSafresh1 $object 733b8851fccSafresh1 ); 734b8851fccSafresh1 is(ref($second_error->[0]), 'HASH', 735b8851fccSafresh1 "first element of array inside \$second_error is hashref"); 736b8851fccSafresh1 ($k, $v) = %{$second_error->[0]}; 737b8851fccSafresh1 is($k, $object, "key of hash is '$object', since 3rd arg was defined"); 738b8851fccSafresh1 is($v, $expect, "value of hash is 2nd arg: $message"); 739b8851fccSafresh1 740b8851fccSafresh1 $message = ''; 741b8851fccSafresh1 $object = undef; 742b8851fccSafresh1 $expect = "$message: $x"; 743b8851fccSafresh1 $arg = { error => \$third_error }; 744b8851fccSafresh1 File::Path::_error( 745b8851fccSafresh1 $arg, 746b8851fccSafresh1 $message, 747b8851fccSafresh1 $object 748b8851fccSafresh1 ); 749b8851fccSafresh1 is(ref($third_error->[0]), 'HASH', 750b8851fccSafresh1 "first element of array inside \$third_error is hashref"); 751b8851fccSafresh1 ($k, $v) = %{$third_error->[0]}; 752b8851fccSafresh1 is($k, '', "key of hash is empty string, since 3rd arg was undef"); 753b8851fccSafresh1 is($v, $expect, "value of hash is 2nd arg: $message"); 754b39c5158Smillert} 7552e109fb9Safresh1 7562e109fb9Safresh1{ 7572e109fb9Safresh1 # https://rt.cpan.org/Ticket/Display.html?id=117019 7582e109fb9Safresh1 # remove_tree(): Permit re-use of options hash without issuing a warning 7592e109fb9Safresh1 7602e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 7619f11ffb7Safresh1 create_3_level_subdirs( qw| ZoYhvc6RmGnl S2CrQ0lju0o7 lvOqVYWpfhcP | ); 7622e109fb9Safresh1 my @created; 7632e109fb9Safresh1 @created = File::Path::make_path($deepest, { mode => 0711 }); 7642e109fb9Safresh1 is(scalar(@created), 3, "Created 3 subdirectories"); 7652e109fb9Safresh1 7662e109fb9Safresh1 my $x = ''; 7672e109fb9Safresh1 my $opts = { error => \$x }; 7682e109fb9Safresh1 File::Path::remove_tree($deepest, $opts); 7692e109fb9Safresh1 ok(! -d $deepest, "directory '$deepest' removed, as expected"); 7702e109fb9Safresh1 7712e109fb9Safresh1 my $warn; 7722e109fb9Safresh1 $warn = _run_for_warning( sub { File::Path::remove_tree($next_deepest, $opts); } ); 7732e109fb9Safresh1 ok(! $warn, "CPAN 117019: No warning thrown when re-using \$opts"); 7742e109fb9Safresh1 ok(! -d $next_deepest, "directory '$next_deepest' removed, as expected"); 7752e109fb9Safresh1 7762e109fb9Safresh1 $warn = _run_for_warning( sub { File::Path::remove_tree($least_deep, $opts); } ); 7772e109fb9Safresh1 ok(! $warn, "CPAN 117019: No warning thrown when re-using \$opts"); 7782e109fb9Safresh1 ok(! -d $least_deep, "directory '$least_deep' removed, as expected"); 7792e109fb9Safresh1} 7802e109fb9Safresh1 7812e109fb9Safresh1{ 7822e109fb9Safresh1 # Corner cases with respect to arguments provided to functions 7832e109fb9Safresh1 my $count; 7842e109fb9Safresh1 7852e109fb9Safresh1 $count = remove_tree(); 7862e109fb9Safresh1 is($count, 0, 7872e109fb9Safresh1 "If not provided with any paths, remove_tree() will return a count of 0 things deleted"); 7882e109fb9Safresh1 7892e109fb9Safresh1 $count = remove_tree(''); 7902e109fb9Safresh1 is($count, 0, 7912e109fb9Safresh1 "If not provided with any paths, remove_tree() will return a count of 0 things deleted"); 7922e109fb9Safresh1 7932e109fb9Safresh1 my $warn; 7942e109fb9Safresh1 $warn = _run_for_warning( sub { $count = rmtree(); } ); 7952e109fb9Safresh1 like($warn, qr/No root path\(s\) specified/s, "Got expected carp"); 7962e109fb9Safresh1 is($count, 0, 7972e109fb9Safresh1 "If not provided with any paths, remove_tree() will return a count of 0 things deleted"); 7982e109fb9Safresh1 7992e109fb9Safresh1 $warn = _run_for_warning( sub {$count = rmtree(undef); } ); 8002e109fb9Safresh1 like($warn, qr/No root path\(s\) specified/s, "Got expected carp"); 8012e109fb9Safresh1 is($count, 0, 8022e109fb9Safresh1 "If provided only with an undefined value, remove_tree() will return a count of 0 things deleted"); 8032e109fb9Safresh1 8042e109fb9Safresh1 $warn = _run_for_warning( sub {$count = rmtree(''); } ); 8052e109fb9Safresh1 like($warn, qr/No root path\(s\) specified/s, "Got expected carp"); 8062e109fb9Safresh1 is($count, 0, 8072e109fb9Safresh1 "If provided with an empty string for a path, remove_tree() will return a count of 0 things deleted"); 8082e109fb9Safresh1 8092e109fb9Safresh1 $count = make_path(); 8102e109fb9Safresh1 is($count, 0, 8112e109fb9Safresh1 "If not provided with any paths, make_path() will return a count of 0 things created"); 8122e109fb9Safresh1 8132e109fb9Safresh1 $count = mkpath(); 8142e109fb9Safresh1 is($count, 0, 8152e109fb9Safresh1 "If not provided with any paths, make_path() will return a count of 0 things created"); 8162e109fb9Safresh1} 8172e109fb9Safresh1 8182e109fb9Safresh1SKIP: { 8199f11ffb7Safresh1 my $skip_count = 3; 8202e109fb9Safresh1 skip "Windows will not set this error condition", $skip_count 8212e109fb9Safresh1 if $^O eq 'MSWin32'; 8222e109fb9Safresh1 8232e109fb9Safresh1 # mkpath() with hashref: case of phony user 8242e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 8259f11ffb7Safresh1 create_3_level_subdirs( qw| Hhu1KpF4EVAV vUj5k37bih8v Vkdw02POXJxj | ); 8262e109fb9Safresh1 my (@created, $error); 8272e109fb9Safresh1 my $user = join('_' => 'foobar', $$); 8282e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, user => $user, error => \$error }); 8299f11ffb7Safresh1# TODO: { 8309f11ffb7Safresh1# local $TODO = "Notwithstanding the phony 'user', mkpath will actually create subdirectories; should it?"; 8319f11ffb7Safresh1# is(scalar(@created), 0, "No subdirectories created"); 8329f11ffb7Safresh1# } 8332e109fb9Safresh1 is(scalar(@$error), 1, "caught error condition" ); 8342e109fb9Safresh1 my ($file, $message) = each %{$error->[0]}; 8352e109fb9Safresh1 like($message, 8362e109fb9Safresh1 qr/unable to map $user to a uid, ownership not changed/s, 8372e109fb9Safresh1 "Got expected error message for phony user", 8382e109fb9Safresh1 ); 8392e109fb9Safresh1 8402e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 8412e109fb9Safresh1} 8422e109fb9Safresh1 8432e109fb9Safresh1{ 8442e109fb9Safresh1 # mkpath() with hashref: case of valid uid 8452e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 8469f11ffb7Safresh1 create_3_level_subdirs( qw| b5wj8CJcc7gl XTJe2C3WGLg5 VZ_y2T0XfKu3 | ); 8472e109fb9Safresh1 my (@created, $error); 848*eac174f2Safresh1 my $warn; 849*eac174f2Safresh1 local $SIG{__WARN__} = sub { $warn = shift }; 8502e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, uid => $>, error => \$error }); 851*eac174f2Safresh1 SKIP: { 852*eac174f2Safresh1 my $skip_count = 1; 853*eac174f2Safresh1 skip "Warning should only appear on Windows", $skip_count 854*eac174f2Safresh1 unless $^O eq 'MSWin32'; 855*eac174f2Safresh1 like($warn, 856*eac174f2Safresh1 qr/Option\(s\) implausible on Win32 passed to mkpath\(\) or make_path\(\)/, 857*eac174f2Safresh1 'make_path with final hashref warned due to options implausible on Win32' 858*eac174f2Safresh1 ); 859*eac174f2Safresh1 } 8602e109fb9Safresh1 is(scalar(@created), 3, "Provide valid 'uid' argument: 3 subdirectories created"); 8612e109fb9Safresh1 8622e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 8632e109fb9Safresh1} 8642e109fb9Safresh1 8652e109fb9Safresh1SKIP: { 8662e109fb9Safresh1 my $skip_count = 3; 8672e109fb9Safresh1 skip "getpwuid() and getgrgid() not implemented on Windows", $skip_count 8682e109fb9Safresh1 if $^O eq 'MSWin32'; 8692e109fb9Safresh1 8702e109fb9Safresh1 # mkpath() with hashref: case of valid owner 8712e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 8729f11ffb7Safresh1 create_3_level_subdirs( qw| aiJEDKaAEH25 nqhXsBM_7_bv qfRj4cur4Jrs | ); 8732e109fb9Safresh1 my (@created, $error); 8742e109fb9Safresh1 my $name = getpwuid($>); 8752e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, owner => $name, error => \$error }); 8762e109fb9Safresh1 is(scalar(@created), 3, "Provide valid 'owner' argument: 3 subdirectories created"); 8772e109fb9Safresh1 8782e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 8792e109fb9Safresh1} 8802e109fb9Safresh1 8812e109fb9Safresh1SKIP: { 8822e109fb9Safresh1 my $skip_count = 5; 8832e109fb9Safresh1 skip "Windows will not set this error condition", $skip_count 8842e109fb9Safresh1 if $^O eq 'MSWin32'; 8852e109fb9Safresh1 8862e109fb9Safresh1 # mkpath() with hashref: case of phony group 8872e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 8889f11ffb7Safresh1 create_3_level_subdirs( qw| nOR4lGRMdLvz NnwkEHEVL5li _3f1Kv6q77yA | ); 8892e109fb9Safresh1 my (@created, $error); 8902e109fb9Safresh1 my $bad_group = join('_' => 'foobarbaz', $$); 8912e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, group => $bad_group, error => \$error }); 8929f11ffb7Safresh1# TODO: { 8939f11ffb7Safresh1# local $TODO = "Notwithstanding the phony 'group', mkpath will actually create subdirectories; should it?"; 8949f11ffb7Safresh1# is(scalar(@created), 0, "No subdirectories created"); 8959f11ffb7Safresh1# } 8962e109fb9Safresh1 is(scalar(@$error), 1, "caught error condition" ); 8972e109fb9Safresh1 my ($file, $message) = each %{$error->[0]}; 8982e109fb9Safresh1 like($message, 8992e109fb9Safresh1 qr/unable to map $bad_group to a gid, group ownership not changed/s, 9002e109fb9Safresh1 "Got expected error message for phony user", 9012e109fb9Safresh1 ); 9022e109fb9Safresh1 9032e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 9042e109fb9Safresh1} 9052e109fb9Safresh1 9062e109fb9Safresh1{ 9072e109fb9Safresh1 # mkpath() with hashref: case of valid group 9082e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 9099f11ffb7Safresh1 create_3_level_subdirs( qw| BEcigvaBNisY rd4lJ1iZRyeS OyQnDPIBxP2K | ); 9102e109fb9Safresh1 my (@created, $error); 911*eac174f2Safresh1 my $warn; 912*eac174f2Safresh1 local $SIG{__WARN__} = sub { $warn = shift }; 9132e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, group => $(, error => \$error }); 914*eac174f2Safresh1 SKIP: { 915*eac174f2Safresh1 my $skip_count = 1; 916*eac174f2Safresh1 skip "Warning should only appear on Windows", $skip_count 917*eac174f2Safresh1 unless $^O eq 'MSWin32'; 918*eac174f2Safresh1 like($warn, 919*eac174f2Safresh1 qr/Option\(s\) implausible on Win32 passed to mkpath\(\) or make_path\(\)/, 920*eac174f2Safresh1 'make_path with final hashref warned due to options implausible on Win32' 921*eac174f2Safresh1 ); 922*eac174f2Safresh1 } 9232e109fb9Safresh1 is(scalar(@created), 3, "Provide valid 'group' argument: 3 subdirectories created"); 9242e109fb9Safresh1 9252e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 9262e109fb9Safresh1} 9272e109fb9Safresh1 9282e109fb9Safresh1SKIP: { 9292e109fb9Safresh1 my $skip_count = 3; 9302e109fb9Safresh1 skip "getpwuid() and getgrgid() not implemented on Windows", $skip_count 9312e109fb9Safresh1 if $^O eq 'MSWin32'; 9322e109fb9Safresh1 9332e109fb9Safresh1 # mkpath() with hashref: case of valid group 9342e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 9359f11ffb7Safresh1 create_3_level_subdirs( qw| IayhWFDvys8X gTd6gaeuFzmV VVI6UWLJCOEC | ); 9362e109fb9Safresh1 my (@created, $error); 9372e109fb9Safresh1 my $group_name = (getgrgid($())[0]; 9382e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, group => $group_name, error => \$error }); 9392e109fb9Safresh1 is(scalar(@created), 3, "Provide valid 'group' argument: 3 subdirectories created"); 9402e109fb9Safresh1 9412e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 9422e109fb9Safresh1} 9432e109fb9Safresh1 9442e109fb9Safresh1SKIP: { 9452e109fb9Safresh1 my $skip_count = 3; 9462e109fb9Safresh1 skip "getpwuid() and getgrgid() not implemented on Windows", $skip_count 9472e109fb9Safresh1 if $^O eq 'MSWin32'; 9482e109fb9Safresh1 9492e109fb9Safresh1 # mkpath() with hashref: case of valid owner and group 9502e109fb9Safresh1 my ($least_deep, $next_deepest, $deepest) = 9519f11ffb7Safresh1 create_3_level_subdirs( qw| xsmOvlnxOqJc olsGlBSoVUpp tDuRilkD35rd | ); 9522e109fb9Safresh1 my (@created, $error); 9532e109fb9Safresh1 my $name = getpwuid($>); 9542e109fb9Safresh1 my $group_name = (getgrgid($())[0]; 9552e109fb9Safresh1 @created = mkpath($deepest, { mode => 0711, owner => $name, group => $group_name, error => \$error }); 9562e109fb9Safresh1 is(scalar(@created), 3, "Provide valid 'owner' and 'group' 'group' arguments: 3 subdirectories created"); 9572e109fb9Safresh1 9582e109fb9Safresh1 cleanup_3_level_subdirs($least_deep); 9592e109fb9Safresh1} 960