xref: /openbsd-src/gnu/usr.bin/perl/cpan/File-Path/t/Path_root.t (revision eac174f2741a08d8deb8aae59a7f778ef9b5d770)
1b8851fccSafresh1use strict;
2b8851fccSafresh1use Test::More;
3b8851fccSafresh1use Config;
42e109fb9Safresh1use lib './t';
52e109fb9Safresh1use FilePathTest qw(
62e109fb9Safresh1    _run_for_warning
72e109fb9Safresh1);
8b8851fccSafresh1use File::Path qw(rmtree mkpath make_path remove_tree);
9b8851fccSafresh1use File::Spec::Functions;
10b8851fccSafresh1
11b8851fccSafresh1
12b8851fccSafresh1my $prereq = prereq();
13b8851fccSafresh1plan skip_all  => $prereq if defined $prereq;
142e109fb9Safresh1plan tests     => 11;
15b8851fccSafresh1
16b8851fccSafresh1my $pwent = max_u();
17b8851fccSafresh1my $grent = max_g();
18b8851fccSafresh1my ( $max_uid, $max_user ) = @{ $pwent };
19b8851fccSafresh1my ( $max_gid, $max_group ) = @{ $grent };
20b8851fccSafresh1
21b8851fccSafresh1my $tmp_base = catdir(
22b8851fccSafresh1    curdir(),
23b8851fccSafresh1    sprintf( 'test-%x-%x-%x', time, $$, rand(99999) ),
24b8851fccSafresh1);
25b8851fccSafresh1
26b8851fccSafresh1# invent some names
27b8851fccSafresh1my @dir = (
28b8851fccSafresh1    catdir($tmp_base, qw(a b)),
29b8851fccSafresh1    catdir($tmp_base, qw(a c)),
30b8851fccSafresh1    catdir($tmp_base, qw(z b)),
31b8851fccSafresh1    catdir($tmp_base, qw(z c)),
32b8851fccSafresh1);
33b8851fccSafresh1
34b8851fccSafresh1# create them
35b8851fccSafresh1my @created = mkpath([@dir]);
36b8851fccSafresh1
37b8851fccSafresh1my $dir;
38b8851fccSafresh1my $dir2;
39b8851fccSafresh1
40b8851fccSafresh1my $dir_stem = $dir = catdir($tmp_base, 'owned-by');
41b8851fccSafresh1
42b8851fccSafresh1$dir = catdir($dir_stem, 'aaa');
43b8851fccSafresh1@created = make_path($dir, {owner => $max_user});
44b8851fccSafresh1is(scalar(@created), 2, "created a directory owned by $max_user...");
45b8851fccSafresh1
46b8851fccSafresh1my $dir_uid = (stat $created[0])[4];
47b8851fccSafresh1is($dir_uid, $max_uid, "... owned by $max_uid");
48b8851fccSafresh1
49b8851fccSafresh1$dir = catdir($dir_stem, 'aab');
50b8851fccSafresh1@created = make_path($dir, {group => $max_group});
51b8851fccSafresh1is(scalar(@created), 1, "created a directory owned by group $max_group...");
52b8851fccSafresh1
53b8851fccSafresh1my $dir_gid = (stat $created[0])[5];
54b8851fccSafresh1is($dir_gid, $max_gid, "... owned by group $max_gid");
55b8851fccSafresh1
56b8851fccSafresh1$dir = catdir($dir_stem, 'aac');
57b8851fccSafresh1@created = make_path( $dir, { user => $max_user,
58b8851fccSafresh1                              group => $max_group});
59b8851fccSafresh1is(scalar(@created), 1, "created a directory owned by $max_user:$max_group...");
60b8851fccSafresh1
61b8851fccSafresh1($dir_uid, $dir_gid) = (stat $created[0])[4,5];
62b8851fccSafresh1is($dir_uid, $max_uid, "... owned by $max_uid");
63b8851fccSafresh1is($dir_gid, $max_gid, "... owned by group $max_gid");
64b8851fccSafresh1
652e109fb9Safresh1{
66b8851fccSafresh1  # invent a user and group that don't exist
67*b46d8ef2Safresh1  my $phony_user = get_phony_user();
68*b46d8ef2Safresh1  my $phony_group = get_phony_group();
69b8851fccSafresh1
70b8851fccSafresh1  $dir = catdir($dir_stem, 'aad');
712e109fb9Safresh1  my $rv = _run_for_warning( sub {
722e109fb9Safresh1      make_path(
732e109fb9Safresh1          $dir,
74*b46d8ef2Safresh1          { user => $phony_user, group => $phony_group }
752e109fb9Safresh1      )
762e109fb9Safresh1  } );
77b8851fccSafresh1  like( $rv,
78*b46d8ef2Safresh1    qr{unable to map $phony_user to a uid, ownership not changed:}s,
79*b46d8ef2Safresh1    "created a directory not owned by $phony_user:$phony_group...",
80b8851fccSafresh1  );
812e109fb9Safresh1  like( $rv,
82*b46d8ef2Safresh1    qr{unable to map $phony_group to a gid, group ownership not changed:}s,
83*b46d8ef2Safresh1    "created a directory not owned by $phony_user:$phony_group...",
842e109fb9Safresh1  );
852e109fb9Safresh1}
862e109fb9Safresh1
872e109fb9Safresh1{
882e109fb9Safresh1    # cleanup
892e109fb9Safresh1    my $x;
902e109fb9Safresh1    my $opts = { error => \$x };
912e109fb9Safresh1    remove_tree($tmp_base, $opts);
922e109fb9Safresh1    ok(! -d $tmp_base, "directory '$tmp_base' removed, as expected");
932e109fb9Safresh1    is(scalar(@{$x}), 0, "no error messages using remove_tree() with \$opts");
94b8851fccSafresh1}
95b8851fccSafresh1
96b8851fccSafresh1sub max_u {
97b8851fccSafresh1  # find the highest uid ('nobody' or similar)
98b8851fccSafresh1  my $max_uid   = 0;
99b8851fccSafresh1  my $max_user = undef;
100b8851fccSafresh1  while (my @u = getpwent()) {
101b8851fccSafresh1    if ($max_uid < $u[2]) {
102b8851fccSafresh1      $max_uid  = $u[2];
103b8851fccSafresh1      $max_user = $u[0];
104b8851fccSafresh1    }
105b8851fccSafresh1  }
106b8851fccSafresh1  setpwent(); # in case we want to run again later
107b8851fccSafresh1  return [ $max_uid, $max_user ];
108b8851fccSafresh1}
109b8851fccSafresh1
110b8851fccSafresh1sub max_g {
111b8851fccSafresh1  # find the highest gid ('nogroup' or similar)
112b8851fccSafresh1  my $max_gid   = 0;
113b8851fccSafresh1  my $max_group = undef;
114b8851fccSafresh1  while ( my @g = getgrent() ) {
115b8851fccSafresh1    if ($max_gid < $g[2]) {
116b8851fccSafresh1      $max_gid = $g[2];
117b8851fccSafresh1      $max_group = $g[0];
118b8851fccSafresh1    }
119b8851fccSafresh1  }
120b8851fccSafresh1  setgrent(); # in case we want to run again later
121b8851fccSafresh1  return [ $max_gid, $max_group ];
122b8851fccSafresh1}
123b8851fccSafresh1
124b8851fccSafresh1sub prereq {
125b8851fccSafresh1  return "getpwent() not implemented on $^O" unless $Config{d_getpwent};
126b8851fccSafresh1  return "getgrent() not implemented on $^O" unless $Config{d_getgrent};
127b8851fccSafresh1  return "not running as root" unless $< == 0;
128b8851fccSafresh1  return "darwin's nobody and nogroup are -1 or -2" if $^O eq 'darwin';
129b8851fccSafresh1
130b8851fccSafresh1  my $pwent = max_u();
131b8851fccSafresh1  my $grent = max_g();
132b8851fccSafresh1  my ( $max_uid, $max_user ) = @{ $pwent };
133b8851fccSafresh1  my ( $max_gid, $max_group ) = @{ $grent };
134b8851fccSafresh1
135b8851fccSafresh1  return "getpwent() appears to be insane" unless $max_uid > 0;
136b8851fccSafresh1  return "getgrent() appears to be insane" unless $max_gid > 0;
137b8851fccSafresh1  return undef;
138b8851fccSafresh1}
139*b46d8ef2Safresh1
140*b46d8ef2Safresh1sub get_phony_user {
141*b46d8ef2Safresh1    return "getpwent() not implemented on $^O" unless $Config{d_getpwent};
142*b46d8ef2Safresh1    return "not running as root" unless $< == 0;
143*b46d8ef2Safresh1    my %real_users = ();
144*b46d8ef2Safresh1    while(my @a=getpwent()) {
145*b46d8ef2Safresh1        $real_users{$a[0]}++;
146*b46d8ef2Safresh1    }
147*b46d8ef2Safresh1    my $phony_stem = 'phonyuser';
148*b46d8ef2Safresh1    my $phony = '';
149*b46d8ef2Safresh1    do { $phony = $phony_stem . int(rand(10000)); } until (! $real_users{$phony});
150*b46d8ef2Safresh1    return $phony;
151*b46d8ef2Safresh1}
152*b46d8ef2Safresh1
153*b46d8ef2Safresh1sub get_phony_group {
154*b46d8ef2Safresh1    return "getgrent() not implemented on $^O" unless $Config{d_getgrent};
155*b46d8ef2Safresh1    return "not running as root" unless $< == 0;
156*b46d8ef2Safresh1    my %real_groups = ();
157*b46d8ef2Safresh1    while(my @a=getgrent()) {
158*b46d8ef2Safresh1        $real_groups{$a[0]}++;
159*b46d8ef2Safresh1    }
160*b46d8ef2Safresh1    my $phony_stem = 'phonygroup';
161*b46d8ef2Safresh1    my $phony = '';
162*b46d8ef2Safresh1    do { $phony = $phony_stem . int(rand(10000)); } until (! $real_groups{$phony});
163*b46d8ef2Safresh1    return $phony;
164*b46d8ef2Safresh1}
165*b46d8ef2Safresh1
166