mschilli / log4perl

Log4j Implementation For Perl
http://log4perl.com
Other
116 stars 66 forks source link

t/013Bench.t fails if Time::HiRes is not available #102

Closed ppisar closed 4 years ago

ppisar commented 4 years ago

If Time::HiRes is not available, t/013Bench.t fails:

t/012Deeper.t ............. ok
Can't locate Time/HiRes.pm in @INC (you may need to install the Time::HiRes module) (@INC contains: /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib /builddir/build/BUILD/Log-Log4perl-1.52/blib/arch /usr/local/lib64/perl5/5.32 /usr/local/share/perl5/5.32 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Util/TimeTracker.pm line 19.
BEGIN failed--compilation aborted at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Util/TimeTracker.pm line 22.
Compilation failed in require at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Layout/PatternLayout.pm line 17.
BEGIN failed--compilation aborted at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Layout/PatternLayout.pm line 17.
Compilation failed in require at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Layout.pm line 5.
BEGIN failed--compilation aborted at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Layout.pm line 5.
Compilation failed in require at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Logger.pm line 11.
BEGIN failed--compilation aborted at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl/Logger.pm line 11.
Compilation failed in require at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl.pm line 14.
BEGIN failed--compilation aborted at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl.pm line 14.
Compilation failed in require at t/013Bench.t line 10.
BEGIN failed--compilation aborted at t/013Bench.t line 10.
t/013Bench.t .............. 
Dubious, test returned 22 (wstat 5632, 0x1600)
No subtests run 
Undefined subroutine &Log::Log4perl::Logger::cleanup called at /builddir/build/BUILD/Log-Log4perl-1.52/blib/lib/Log/Log4perl.pm line 5.
END failed--call queue aborted at t/013Bench.t line 10.

I can see that lib/Log/Log4perl/Util/TimeTracker.pm loads Time::HiRes only if Log::Log4perl::Util::module_available returns true. Compiling TimeTracker.pm indeed succeeds. But Benchmark in the t/013Bench.t does something strange that confuses module_available():

$ perl -Ilib -e 'use Log::Log4perl;'
$ perl -Ilib -e 'use Benchmark; use Log::Log4perl;'
Can't locate Time/HiRes.pm in @INC (you may need to install the Time::HiRes module) (@INC contains: lib /usr/local/lib64/perl5/5.32 /usr/local/share/perl5/5.32 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at lib/Log/Log4perl/Util/TimeTracker.pm line 19.
[...]
ppisar commented 4 years ago

It can be reduced to:

$ cat /tmp/test
if (eval 0) {
    \&Time::HiRes::time;
}
require Log::Log4perl::Util;
if (Log::Log4perl::Util::module_available("Time::HiRes")) {
    print "BUG\n";
}
[test@fedora-34 Log-Log4perl-1.52]$ perl -Ilib /tmp/test
BUG

It seems that \&Time::HiRes::time autovivifies %{'Time::HiRes::'} and hence Log::Log4perl::Util::module_available("Time::HiRes") thinks that Time::HiRes has already been loaded.

If I replace "eval 0" condition with "0", perl optimizes out the block with the vivification.

Benchmark.pm basically does:

if (eval 'require Time::HiRes;') {
    \&Time::HiRes::time;
}
mohawk2 commented 4 years ago

Thanks for the report. I think the module_available change was wrong, and needs changing. Things that define a package inline will just have to set a %INC entry so require does the right thing.

mohawk2 commented 4 years ago

The change in #61 has been (I believe) fixed. Could you try again with the just-released 1.53? Please reopen if it's not actually fixed!

ppisar commented 4 years ago

Thank you for the quick fix. I confirm that 1.53 passes without Time::HiRes.