How to test for the absence of an infinite loop?

2002-03-17 Thread Mark-Jason Dominus


I've just found a bug in my module.  The bug results in an
inappropriate infinite loop.

Before I fix the bug, I want to write up a test case.

I can reproduce the bug OK, but if I put that code into the module
tests, and the bug isn't fixed, or comes back for some reason, then
the test program will go into an infinite loop.

The test harness doesn't seem to notice that.  I don't want to go
sticking code into my test files that might cause an infinite loop and
hang up the test harness or the entire system.

If the module were for Unix only, I would stick an  'alarm 10' at the
top of the test program.  I'm told this won't work under Win32.

What's the right way to handle this?





Re: How to test for the absence of an infinite loop?

2002-03-18 Thread Mark-Jason Dominus


Michael The Schwern <[EMAIL PROTECTED]> says:
> Use alarm and skip the test if $Config{d_alarm} is false (see
> t/op/alarm.t for an example).  If you think the infinite loop is due
> to a programming glitch, as opposed to a cross-platform issue, this
> will be enough.

Thanks very much!

> The only other thing I can think of is to set up a parent process
> which forks off a child

ARRRGH.  NO FORK.

Actually that reminds me of another puzzle I have.  My module provides
an interface to 'flock'.  What is an easy way to check that the file
is actually being locked?  I put off writing the tests because i did
not want to fork.

Is this mailing list the right place to ask "how do I test for X"
questions?  Or would the module-authors list be more appropriate?






Re: How to test for the absence of an infinite loop?

2002-03-18 Thread Mark-Jason Dominus


> I just thought of a clever way to do it without alarm!  

So clever, it doesn't work!

> lock_file($foo);
> open(FH, $foo);
> ok( !flock(FH, LOCK_NB | LOCK_EX) );

Seriously, on most unix systems, the following:

flock(FH, LOCK_EX);
flock(FH, LOCK_EX|LOCK_NB) or die;

doe *not* die.  A process is allowed to ask for (and obtain) an
exclusive lock on a file if it already has a lock on that same file.
There's no deadlock at all.

I just checked this under linux and solaris with:

use Fcntl ':flock';

open F, "+< $0: or die $!;
flock F, LOCK_EX or die $!;
flock F, LOCK_EX|LOCK_NB or die $!;
print "OK\n";

and it OK's on both.  Similarly, 

use Fcntl ':flock';

open F, "+< $0" or die $!;
open G, "+< $0" or die $!;
flock F, LOCK_EX or die $!;
flock G, LOCK_EX|LOCK_NB or die $!;
print "OK\n";

This failus under Linux (which I think is wrong) but OK's on Solaris.
"OK" here means "What you suggested won't work."

> The traditional approaches require causing a deadlock and breaking it
> with alarm.

Perhaps the traditional approach doesn't work.  :)

> So here's the other way.  We cause a deadlock using another process
> which kills itself after a certain amount of time.
> 
> my $start = time;
> lock_file($foo);
> system($^X, '-e', 'use Whatever;  alarm 5;  lock_file($foo)');
> cmp_ok( time, '>', $start + 3, 'Locking works' );
> 
> again, these all rely on alarm().  

This on also relies on system creating a new process.  I wasn't sure
what this would do on Win32, VMS, OS390, etc.  Hence my original
question:

>> What is an easy way to check that the file is actually being locked?
>> I put off writing the tests because i did not want to fork.

Sorry to be so elliptical.  What I should have said was that I can
think of lots of ways to do it but they all involve starting a new
process, and I'm reluctant to start a new prcoess unless I have to,
because I have no idea what it does on Weird Platform X.




O_ACCMODE

2002-03-31 Thread Mark-Jason Dominus


Supposing that Fcntl and O_RDONLY are known to be available, how
likely is it that O_ACCMODE will also be available?  Are there any
platforms that have O_RDONLY but not O_ACCMODE?






Re: O_ACCMODE

2002-04-02 Thread Mark-Jason Dominus


> You probably already found out, but
> 
> HP-UX 10.20   Has it defined as 003
> HP-UX 11.00   Has it defined as 003
> AIX 4.3.3.0   Has it defined as 3
> AIX 4.2.1.0   Has it defined as 3

Thanks for the information.  It turns out some Win32 systems don't
have it at all, so I have to avoid it.

Instead, I'm doing:

use Fcntl 'O_RDONLY', 'O_RDWR', 'O_WRONLY';
sub O_ACCMODE () { O_RDONLY | O_WRONLY | O_RDWR }

which I think should work everywhere that defines O_((RD|WR)ONLY|RDWR),
whatever their values.