Some Perl-Related Bugs and How They Were Fixed.
In this entry, I'd like to tell about several Perl-related bugs I have run into, and how they were fixed. I know I have not been blogging a lot lately, but, on the bright side, I was busy coding.
XML-Grammar-Fortune-Synd Test Failures on Some Windows-based Testers
For a long time, I've been getting test failures such as
this
one for my
XML-Grammar-Fortune-Synd
module, from some Windows-based systems, which I was unable to reproduce on
my local Linux system. Per
Michael G. Schwern's advice,
I tried to convert all the path handling to use File::Spec for paths
portability, but it did not fix the problem. Then I tried it on a Windows XP
VM, but the tests passed there fine. Eventually, I had to install a Windows 7
VM, and run the tests there, and they failed. I originally suspected the
problem was with
File::Temp's
tempdir()
function,
but it turned out to be an inconsistency in the behaviour of
File::Copy across
the systems. On some systems, it copied a read only file to the temporary
directory, preserving its read-only status, which made
open()
throw an error when writing to it.
This was fixed by these two subroutines:
sub _my_copy { my ($src, $dest) = @_; open my $out_fh, '>', $dest; print {$out_fh} _slurp($src); close($out_fh); return; } sub _slurp { my $filename = shift; open my $in, "<", $filename or die "Cannot open '$filename' for slurping - $!"; local $/; my $contents = <$in>; close($in); return $contents; }
Where I used _my_copy()
to copy from one file location to another.
Since this was fixed, I didn't get any test failures for the module from Microsoft Windows machines or otherwise. Silence is golden.
Module-Build-Tiny Test Failures on Mageia Linux
I noticed that some of the tests of Module-Build-Tiny (which some CPAN distributions started using) failed to run on Mageia Linux, while they ran fine in a perl installed from perlbrew. The problem was that the file was partly writable while Module-Build-Tiny wanted it to be completely read-only. At first, we suspected a combination of the perl build-time flags caused it, but a perl I built from source with all the Mageia flags, passed all the tests. So it was likely caused by a Mageia patch.
By using the perl debugger, I realised that a downstream patch changed the permissions in the Perl ExtUtils::Install to 0644 instead of 0444, and after testing the package without this patch, the Module-Build-Tiny tests passed.
We ended up removing the patch permanently from the Mageia perl package.
Second Problem with Module-Build-Tiny: Double-Dash
Another problem I had with Module-Build-Tiny, after the previous
one was that it
appeared to have ignored the "destdir" and "installdirs" command line
arguments , but it turned out that we
needed to spell them --destdir=$FOO
instead of
destdir=$FOO
, and as --installdirs=vendor
instead
of installdirs=vendor
(with double-dash prefixes). This
was noted in the Mageia
Perl Policy, and I also sent
a pull
request for fixing it to CPANPLUS-Dist-Mageia.
Parallelising Time-Consuming Automated Tests Using prove -j
As I did some work on Freecell Solver, I was annoyed by the fact that the valgrind.t test script, which ran several tests for checking the programs for valgrind sanity, was too time consuming, despite the fact that I ran it first and ran the other test scripts in parallel to it using prove's "-j" flag.
Then it occurred to me that I can parallelise these tests inidividually. I decided to split them into an array of tests, each one with an ID, and then have a program write several tests scripts, with each one running an individual ID, and then run all the files generated by the generation program.
This seems to have improved performance, and I can now run the parallelised tests in 21 seconds.
I've been thinking that this could be a useful CPAN distribution, and am contemplating writing something like that for CPAN.
Thanks
Thanks to Altreus for reviewing this entry.
Hi
Thanx for the advice re copy. Just yesterday I got another CPAN Tester report on this, on a module (Tree::Persist) which I now maintain.
Originally it was using:
use File::Copy 'cp';
and the docs warn that cp() and copy() can do different things re permissions.
Now I have another target to investigate.
BTW, can anyone suggest an alternative to File::Copy? I'm thinking something that has features more on par with Unix's cp. File::Copy::Recursive is good, but they both lack the ability to copy permission/ownership attributes, or handle symlinks, etc.
Hi Steven
See File::Slurp:
write_file($file_name, @data, {perms => xxx});
That's one advantage over Perl6::Slurp.
Another advantage is that Damian has given Perl6::Slurp many, many ways to read things.
Arguably, this type of overloading is confusing in the same was (un-)smart match's ~~ was :-(.
Ron Savage: you're welcome - regarding the File::Copy thing.
Ron: I believe File::Slurp can only handle one file at a time, while Steven also wants something like “cp -R” - i.e: copying an entire directory tree recursively.
Shlomi
Ahhh. I didn't pick up on the 'cp -R' thingy.
Still, having a choice not to use File::Copy is in itself important....
I want to share a useful tip. If you are facing troubleshooting problem, then there is a need to view hidden files. If you feel like, Try these http://www.showhiddenfilesmac.com.