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.

6 Comments

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 :-(.

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....

Leave a comment

About Shlomi Fish

user-pic An Israeli software developer, essayist, and writer, and an enthusiast of open/free software and cultural works. I've been working with Perl since 1996.