use Forks::Super ':test';
use Test::More tests => 22;
use POSIX ':sys_wait_h';
use strict;
use warnings;
##################################################################
# waitpid(target,flags,timeout)
my $t = Time::HiRes::time();
my $pid = fork { sub => sub { sleep 2 } };
my $u = Time::HiRes::time();
my $p = waitpid $pid, 0, 6;
my $h = Time::HiRes::time();
($t,$u) = ($h-$t,$h-$u);
okl($t >= 1.95 && $u <= 5.25, ### 1 ### was 3.0 obs 3.12,3.28,3.95
"waitpid with long timeout returns when job finishes ${t}s ${u}s "
. "expected ~2s");
ok($p == $pid, "waitpid returns pid on long timeout");
$t = Time::HiRes::time();
$p = waitpid $pid, 0, 4;
$t = Time::HiRes::time() - $t;
okl($t <= 1, "waitpid fast return ${t}s, expected <=1s");
ok($p == -1, "waitpid -1 when nothing to wait for");
$t = Time::HiRes::time();
$pid = fork { sub => sub { sleep 4 } };
$u = Time::HiRes::time();
$p = waitpid $pid, 0, 2;
$h = Time::HiRes::time();
($t,$u) = ($h-$t,$h-$u);
okl($u >= 1.95 && $u <= 3.05, ### 5 ###
"waitpid short timeout returns at end of timeout ${t}s ${u}s expected ~2s");
ok($p == &Forks::Super::Wait::TIMEOUT,
"waitpid short timeout returns TIMEOUT");
$t = Time::HiRes::time();
$p = waitpid $pid, WNOHANG, 2;
$t = Time::HiRes::time() - $t;
okl($t <= 1, "waitpid no hang fast return took ${t}s, expected <=1s");
# XXX waitpid WNOHANG should return 0 or -1 for active process???
ok($p == -1 || $p == 0, "waitpid no hang returns -1");
$t = Time::HiRes::time();
$p = waitpid $pid, 0, 10;
$t = Time::HiRes::time() - $t;
okl($t >= 0.99 && $t <= 4.15, ### 9 ### was 2.85 obs 3.30,4.58
"subsequent waitpid long timeout returned when job finished "
."${t}s expected ~2s");
ok($p == $pid, "subsequent waitpid long timeout returned pid");
# waitall;
##################################################################
# exercise OO-style $pid->waitpid, $pid->wait
$t = Time::HiRes::time();
$pid = fork { sub => sub { sleep 4 } };
$u = Time::HiRes::time();
$p = $pid->wait(8);
$h = Time::HiRes::time();
($t,$u) = ($h-$t,$h-$u);
okl($t >= 1.95 && $u <= 7.25,
"waitpid with long timeout returns when job finishes ${t}s ${u}s "
. "expected ~4s");
ok($p == $pid, "waitpid returns pid on long timeout");
$t = Time::HiRes::time();
$p = $pid->wait(5);
$t = Time::HiRes::time() - $t;
okl($t <= 1, "waitpid fast return ${t}s, expected <=1s");
ok($p == -1, "waitpid -1 when nothing to wait for");
$t = Time::HiRes::time();
$pid = fork { sub => sub { sleep 5 } };
$u = Time::HiRes::time();
$p = $pid->waitpid(0, 2);
$h = Time::HiRes::time();
($t,$u) = ($h-$t,$h-$u);
okl($u >= 1.95 && $u <= 3.50, ### 15 ### was 3.05, obs 3.48
"waitpid short timeout returns at end of timeout ${t}s ${u}s expected ~2s");
ok($p == &Forks::Super::Wait::TIMEOUT,
"waitpid short timeout returns TIMEOUT");
$t = Time::HiRes::time();
$p = $pid->waitpid(WNOHANG, 2);
$t = Time::HiRes::time() - $t;
okl($t <= 1, "waitpid no hang fast return took ${t}s, expected <=1s");
ok($p == -1 || $p == 0, "waitpid no hang returns -1 or 0");
$t = Time::HiRes::time();
$p = $pid->wait(0);
$t = Time::HiRes::time() - $t;
okl($t <= 1, "pid->wait(0) like WNOHANG fast return took ${t}s, expected <=1s");
ok($p == -1 || $p == 0, "pid->wait(0) returns -1 or 0");
$t = Time::HiRes::time();
$p = $pid->wait;
$t = Time::HiRes::time() - $t;
okl($t >= 1.79 && $t <= 5.15,
"pid->wait() waits for job to finish ${t}s expected ~3s"); ### 21 ###
ok($p == $pid, "subsequent waitpid long timeout returned pid");
waitall;