Perl单元测试中的分叉子过程停止证明;测试::线束退出
-
06-07-2019 - |
题
我一直在尝试使用Perl实用程序/模块“证明”作为一些单元测试的测试工具。单元测试是更多的“系统”测试。而不是“单位”因为我需要将一些后台进程分解为测试的一部分,使用以下...
sub SpinupMonitor{
my $base_dir = shift;
my $config = shift;
my $pid = fork();
if($pid){
return $pid;
}else{
my $cmd = "$base_dir\/..\/bin\/monitor_real.pl -config $config -test";
close STDOUT;
exec ($cmd) or die "cannot exec test code [$cmd]\n";
}
}
sub KillMonitor{
my $pid = shift;
print "Killing monitor [$pid]\n";
kill(1,$pid);
}
但是出于某些原因,当我让我的.t文件启动一些额外的进程时,它会导致测试工具在所有测试完成后挂在第一个.t文件的末尾,而不是转到下一个文件,如果只有一个,则退出。
起初我想知道是否可能是因为我杀了我的子流程并让它们不复存在。所以我加了..
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $pid = wait;
$SIG{CHLD} = \&REAPER;
}
代码。但这没有用。事实上,在封闭式检查中,我发现我的perl测试文件已经退出并且现在已经不存在了,并且它是证明包装器脚本没有收到它的孩子。事实上,当我在测试脚本的末尾添加了一个die()调用时,我得到了......
# Looks like your test died just after 7.
所以我的脚本退出了,但由于某种原因,线束没有解开。
我确实确认我的子流程肯定会让我感到不安,因为当我在测试失败时正确地退出线圈时我会禁用它们。
我启动流程的方式是否有什么问题,可能会以某种方式扰乱线束?
由于
彼得
解决方案
我假设你的孩子在离开考试前已经退出了吗?因为否则,它可能会挂在STDERR上,这可能会混淆证明。如果您可以关闭STDERR,或者至少重定向到父进程中的管道,那么这可能是您遇到的一个问题。
除此之外,我还要指出你不需要转义正斜杠,如果你没有使用shell元字符(空格不是perl字符到perl - 想想“ *?{} ()
"),你应该明确并创建一个列表:
use File::Spec;
my @cmd = File::Spec->catfile($basedir,
File::Spec->updir(),
qw(bin monitor_real.pl)
),
-config => $config,
-test =>;
close STDOUT;
close STDERR;
exec (@cmd) or die "cannot exec test code [@cmd]\n";
其他提示
请注意,您不测试 fork()
是否失败。在假设之前,您需要确保 $ pid
已定义那个“假” “儿童”是指“儿童”。
因为 $ cmd
包含shell元字符(空格),所以当你调用 exec()
时,Perl实际上正在使用shell。在您的监视器运行时,有(1)Perl,(2)子 sh -c
,以及(3)运行 monitor_real.pl
的孙子Perl。特别是当你调用 KillMonitor
时,你只是杀死了shell(因为那是你拥有的PID),而不是监视器。
你可能也对如何从Perl FAQ中分叉守护进程?。