#!perl
my
$t
= Pinto::Tester->new;
subtest
'exclusive locking'
=>
sub
{
note
'Testing exclusive locking'
;
my
$pid
=
fork
;
die
"fork failed: $!"
unless
defined
$pid
;
if
(
$pid
) {
sleep
3;
print
"Starting parent: $$\n"
;
my
$lock_file
=
$t
->root->file(
'.lock'
);
file_exists_ok(
$lock_file
);
local
$Pinto::Locker::LOCKFILE_TIMEOUT
= 5;
$t
->run_throws_ok(
'Nop'
, {},
qr/currently in use/
,
'Operation denied when exclusive lock is in place'
);
my
$kid
=
wait
;
is(
$kid
,
$pid
,
"reaped correct child"
);
is( $?, 0,
"child finished succesfully"
);
file_not_exists_ok(
$lock_file
);
$t
->run_ok(
'Nop'
, {},
'Operation allowed after exclusive lock is removed'
);
}
else
{
print
"Starting child: $$\n"
;
no
warnings
qw(redefine once)
;
local
*Pinto::Action::Pull::execute
=
sub
{
sleep
12;
return
$_
[0]->result };
my
$result
=
$t
->pinto->run(
'Pull'
,
targets
=>
'whatever'
);
exit
$result
->exit_status;
}
};
subtest
'shared locking'
=>
sub
{
note
'Testing shared locking'
;
my
$pid
=
fork
;
die
"fork failed: $!"
unless
defined
$pid
;
if
(
$pid
) {
sleep
3;
print
"Starting parent: $$\n"
;
my
$lock_file
=
$t
->root->file(
'.lock'
);
file_exists_ok(
$lock_file
);
local
$Pinto::Locker::LOCKFILE_TIMEOUT
= 5;
$t
->run_ok(
'List'
, {},
'Non-excusive operation allowed with shared lock'
);
$t
->run_throws_ok(
'Pull'
,
{
targets
=>
'whatever'
},
qr/currently in use/
,
'Exclusive operation denied when shared lock is in place'
);
my
$kid
=
wait
;
is(
$kid
,
$pid
,
"reaped correct child"
);
is( $?, 0,
"child finished succesfully"
);
file_not_exists_ok(
$lock_file
);
}
else
{
print
"Starting child: $$\n"
;
no
warnings
qw(redefine once)
;
local
*Pinto::Action::List::execute
=
sub
{
sleep
15;
return
$_
[0]->result };
my
$result
=
$t
->pinto->run(
'List'
);
exit
$result
->exit_status;
}
};
subtest
'Test stale lock file'
=>
sub
{
my
$lockfile
=
$t
->root->file(
'.lock'
);
$lockfile
->touch;
$t
->path_exists_ok(
$lockfile
,
'dummy lockfile exists'
);
local
$Pinto::Locker::LOCKFILE_TIMEOUT
= 4;
local
$Pinto::Locker::STALE_LOCKFILE_TIMEOUT
= 0;
throws_ok {
$t
->pinto->repo->
lock
(
'EX'
) }
'Pinto::Exception'
,
'repo locked elsewhere'
;
local
$Pinto::Locker::STALE_LOCKFILE_TIMEOUT
= 2;
sleep
(
$Pinto::Locker::STALE_LOCKFILE_TIMEOUT
+ 1 );
isa_ok(
$t
->pinto->repo->
lock
(
'EX'
),
'Pinto::Locker'
,
'steal the repo lock'
);
ok(
$t
->pinto->repo->unlock,
'unlock repo'
);
$t
->path_not_exists_ok(
$lockfile
,
'confirm lockfile removed'
);
};
done_testing;