blob: 1f36a922ff12e495ea750e1fa405f7c8efe05c56 [file] [log] [blame]
# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
package TestAPRlib::finfo;
use strict;
use warnings FATAL => 'all';
use Apache::Test;
use Apache::TestUtil;
use Apache::TestTrace;
use Apache::TestConfig;
use File::Spec::Functions qw(catfile);
use Fcntl qw(:mode);
use APR::Finfo ();
use APR::Pool ();
use constant WIN32 => Apache::TestConfig::WIN32;
use constant OSX => Apache::TestConfig::OSX;
use constant APACHE_2_0_49_PLUS => have_min_apache_version('2.0.49');
use constant APACHE_2_2_PLUS => have_min_apache_version('2.2.0');
use APR::Const -compile => qw(SUCCESS FINFO_NORM FINFO_PROT FILETYPE_REG
FPROT_WREAD FPROT_WWRITE
FPROT_WEXECUTE);
sub num_of_tests {
return 27;
}
sub test {
# for the file to be tested, use the httpd.conf generated
# by testing, so that it has a ctime that won't (usually)
# encounter a bug in Win32's stat() function for files that
# span across DST season boundaries.
my $file = catfile Apache::Test::vars->{t_dir}, 'conf', 'httpd.conf';
my $pool = APR::Pool->new();
# populate the finfo struct first
my $wanted = APR::Const::FINFO_NORM;
if (WIN32) {
$wanted &= ~APR::Const::FINFO_PROT;
}
my $finfo = APR::Finfo::stat($file, $wanted, $pool);
ok $finfo->isa('APR::Finfo');
# now, get information from perl's stat()
my %stat;
@stat{qw(device inode protection nlink user group size atime mtime
ctime)} = (stat $file)[0..5, 7..10];
compare_with_perl($finfo, \%stat);
# tests for stuff not in perl's stat
{
# BACK_COMPAT_MARKER - fixed as of 2.0.49.
if (WIN32 && !APACHE_2_0_49_PLUS) {
skip "finfo.fname requires Apache 2.0.49 or later", 0;
}
else {
ok t_cmp($finfo->fname,
$file,
'$finfo->fname()');
}
ok t_cmp($finfo->filetype,
APR::Const::FILETYPE_REG,
'$finfo->filetype()');
}
# stat() on out-of-scope pools
{
my $finfo = APR::Finfo::stat($file, $wanted, APR::Pool->new);
# try to overwrite the temp pool data
require APR::Table;
my $table = APR::Table::make(APR::Pool->new, 50);
$table->set($_ => $_) for 'aa'..'za';
# now test that we are still OK
compare_with_perl($finfo, \%stat);
}
}
sub compare_with_perl {
my ($finfo, $stat) = @_;
# skip certain tests on Win32 and others
my %skip = ();
if (WIN32) {
# atime is wrong on NTFS, but OK on FAT32
%skip = map {$_ => 1} qw(device inode user group atime);
}
elsif (OSX) {
# XXX both apr and perl report incorrect group values. sometimes.
# XXX skip until we can really figure out what is going on.
%skip = (group => 1);
}
# compare stat fields between perl and apr_stat
{
foreach my $method (qw(device inode nlink user group
size atime mtime ctime)) {
if ($skip{$method}) {
skip "different file semantics", 0;
}
else {
ok t_cmp($finfo->$method(),
$stat->{$method},
"\$finfo->$method()");
}
}
}
# stat tests (same as perl's stat)
{
# XXX: untested
# ->name
# XXX: are there any platforms csize is available at all?
# We don't want to see the skipped message all the time if
# it's not really used anywhere
# if (my $csize = $finfo->csize) {
# # The storage size is at least as big as the file size
# # perl's stat() doesn't have the equivalent of csize
# t_debug "csize=$csize, size=$stat{size}";
# ok $csize >= $stat{size};
# }
# else {
# skip "csize is not available on this platform", 0;
# }
# match world bits
# on Win32, there's a bug in the apr library supplied
# with Apache/2.2 that causes the following two tests
# to fail. This is slated to be fixed after apr-1.2.7.
if (WIN32 and APACHE_2_2_PLUS) {
skip "broken apr stat on Win32", 0;
}
else {
ok t_cmp($finfo->protection & APR::Const::FPROT_WREAD,
$stat->{protection} & S_IROTH,
'$finfo->protection() & APR::Const::FPROT_WREAD');
}
if (WIN32 and APACHE_2_2_PLUS) {
skip "broken apr stat on Win32", 0;
}
else {
ok t_cmp($finfo->protection & APR::Const::FPROT_WWRITE,
$stat->{protection} & S_IWOTH,
'$finfo->protection() & APR::Const::FPROT_WWRITE');
}
if (WIN32) {
skip "different file semantics", 0;
}
else {
ok t_cmp($finfo->protection & APR::Const::FPROT_WEXECUTE,
$stat->{protection} & S_IXOTH,
'$finfo->protection() & APR::Const::FPROT_WEXECUTE');
}
}
}
1;