xref: /openbsd-src/gnu/usr.bin/perl/dist/Time-HiRes/t/stat.t (revision e068048151d29f2562a32185e21a8ba885482260)
1b8851fccSafresh1use strict;
2b8851fccSafresh1
3b8851fccSafresh1BEGIN {
4b8851fccSafresh1    require Time::HiRes;
5b8851fccSafresh1    unless(&Time::HiRes::d_hires_stat) {
6b8851fccSafresh1        require Test::More;
7b8851fccSafresh1        Test::More::plan(skip_all => "no hi-res stat");
8b8851fccSafresh1    }
9b8851fccSafresh1    if($^O =~ /\A(?:cygwin|MSWin)/) {
10b8851fccSafresh1        require Test::More;
11b8851fccSafresh1        Test::More::plan(skip_all =>
12b8851fccSafresh1                "$^O file timestamps not reliable enough for stat test");
13b8851fccSafresh1    }
14b8851fccSafresh1}
15b8851fccSafresh1
16014083a1Safresh1use Test::More tests => 43;
179f11ffb7Safresh1BEGIN { push @INC, '.' }
18b8851fccSafresh1use t::Watchdog;
19b8851fccSafresh1
20b8851fccSafresh1my @atime;
21b8851fccSafresh1my @mtime;
22b8851fccSafresh1for (1..5) {
23eac174f2Safresh1    note "cycle $_";
24b8851fccSafresh1    Time::HiRes::sleep(rand(0.1) + 0.1);
259f11ffb7Safresh1    open(X, '>', $$);
26b8851fccSafresh1    print X $$;
27b8851fccSafresh1    close(X);
28b8851fccSafresh1    my($a, $stat, $b) = ("a", [Time::HiRes::stat($$)], "b");
29eac174f2Safresh1    is $a, "a", "stat stack discipline";
30eac174f2Safresh1    is $b, "b", "stat stack discipline";
31eac174f2Safresh1    is ref($stat), "ARRAY", "stat returned array";
32b8851fccSafresh1    push @mtime, $stat->[9];
33b8851fccSafresh1    ($a, my $lstat, $b) = ("a", [Time::HiRes::lstat($$)], "b");
34eac174f2Safresh1    is $a, "a", "lstat stack discipline";
35eac174f2Safresh1    is $b, "b", "lstat stack discipline";
36eac174f2Safresh1    SKIP: {
37eac174f2Safresh1        if($^O eq "haiku") {
38eac174f2Safresh1            skip "testing stat access time on Haiku", 2;
39eac174f2Safresh1        }
40*e0680481Safresh1        if ($ENV{PERL_FILE_ATIME_CHANGES}) {
41*e0680481Safresh1            # something else might access the file, changing atime
42*e0680481Safresh1            $lstat->[8] = $stat->[8];
43*e0680481Safresh1        }
44eac174f2Safresh1        is_deeply $lstat, $stat, "write: stat and lstat returned same values";
45b8851fccSafresh1        Time::HiRes::sleep(rand(0.1) + 0.1);
469f11ffb7Safresh1        open(X, '<', $$);
47b8851fccSafresh1        <X>;
48b8851fccSafresh1        close(X);
49b8851fccSafresh1        $stat = [Time::HiRes::stat($$)];
50b8851fccSafresh1        push @atime, $stat->[8];
51b8851fccSafresh1        $lstat = [Time::HiRes::lstat($$)];
52eac174f2Safresh1        is_deeply $lstat, $stat, "read:  stat and lstat returned same values";
53eac174f2Safresh1    }
54b8851fccSafresh1}
55b8851fccSafresh11 while unlink $$;
56eac174f2Safresh1note ("mtime = @mtime");
57eac174f2Safresh1note ("atime = @atime");
58b8851fccSafresh1my $ai = 0;
59b8851fccSafresh1my $mi = 0;
60b8851fccSafresh1my $ss = 0;
61b8851fccSafresh1for (my $i = 1; $i < @atime; $i++) {
62b8851fccSafresh1    if ($atime[$i] >= $atime[$i-1]) {
63b8851fccSafresh1        $ai++;
64b8851fccSafresh1    }
65b8851fccSafresh1    if ($atime[$i] > int($atime[$i])) {
66b8851fccSafresh1        $ss++;
67b8851fccSafresh1    }
68b8851fccSafresh1}
69b8851fccSafresh1for (my $i = 1; $i < @mtime; $i++) {
70b8851fccSafresh1    if ($mtime[$i] >= $mtime[$i-1]) {
71b8851fccSafresh1        $mi++;
72b8851fccSafresh1    }
73b8851fccSafresh1    if ($mtime[$i] > int($mtime[$i])) {
74b8851fccSafresh1        $ss++;
75b8851fccSafresh1    }
76b8851fccSafresh1}
77eac174f2Safresh1note ("ai = $ai, mi = $mi, ss = $ss");
78b8851fccSafresh1# Need at least 75% of monotonical increase and
79b8851fccSafresh1# 20% of subsecond results. Yes, this is guessing.
80b8851fccSafresh1SKIP: {
81b8851fccSafresh1    skip "no subsecond timestamps detected", 1 if $ss == 0;
82eac174f2Safresh1    skip "testing stat access on Haiku", 1 if $^O eq "haiku";
83b8851fccSafresh1    ok $mi/(@mtime-1) >= 0.75 && $ai/(@atime-1) >= 0.75 &&
84eac174f2Safresh1             $ss/(@mtime+@atime) >= 0.2,
85eac174f2Safresh1        "monotonical increase and subsecond results within expected parameters";
86b8851fccSafresh1}
87b8851fccSafresh1
88b8851fccSafresh1my $targetname = "tgt$$";
89b8851fccSafresh1my $linkname = "link$$";
90b8851fccSafresh1SKIP: {
919f11ffb7Safresh1    open(X, '>', $targetname);
92b8851fccSafresh1    print X $$;
93b8851fccSafresh1    close(X);
94b8851fccSafresh1    eval { symlink $targetname, $linkname or die "can't symlink: $!"; };
95b8851fccSafresh1    skip "can't symlink", 7 if $@ ne "";
96eac174f2Safresh1    note "compare Time::HiRes::stat with ::lstat";
97b8851fccSafresh1    my @tgt_stat = Time::HiRes::stat($targetname);
98b8851fccSafresh1    my @tgt_lstat = Time::HiRes::lstat($targetname);
99b8851fccSafresh1    my @lnk_stat = Time::HiRes::stat($linkname);
100b8851fccSafresh1    my @lnk_lstat = Time::HiRes::lstat($linkname);
101eac174f2Safresh1    my $exp = 13;
102eac174f2Safresh1    is scalar(@tgt_stat), $exp,  "stat on target";
103eac174f2Safresh1    is scalar(@tgt_lstat), $exp, "lstat on target";
104eac174f2Safresh1    is scalar(@lnk_stat), $exp,  "stat on link";
105eac174f2Safresh1    is scalar(@lnk_lstat), $exp, "lstat on link";
106eac174f2Safresh1    skip "testing stat access on Haiku", 3 if $^O eq "haiku";
107eac174f2Safresh1    is_deeply \@tgt_stat, \@tgt_lstat, "stat and lstat return same values on target";
108eac174f2Safresh1    is_deeply \@tgt_stat, \@lnk_stat,  "stat and lstat return same values on link";
109eac174f2Safresh1    isnt $lnk_lstat[2], $tgt_stat[2],
110eac174f2Safresh1        "target stat mode value differs from link lstat mode value";
111b8851fccSafresh1}
112b8851fccSafresh11 while unlink $linkname;
113b8851fccSafresh11 while unlink $targetname;
114b8851fccSafresh1
115b8851fccSafresh11;
116