Perl单元测试中的分叉子流程停止了证明;测试::线束退出



我一直在尝试使用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.

所以我的脚本退出了,但由于某种原因,安全带没有解开。

我确实确认,肯定是我的子流程让它感到不安,因为当我在测试失败时禁用它们时,安全带正确退出。

我启动流程的方式是否有任何错误,可能会在某种程度上打乱安全带?

请注意,您不会测试fork()是否失败。在假定"false"表示"child"之前,您需要确保定义了$pid

因为$cmd包含shell元字符(空格),所以当您调用exec()时,Perl实际上是在使用shell。当您的监视器正在运行时,有(1)Perl、(2)子级sh -c和(3)孙级Perl在运行monitor_real.pl。这特别意味着,当你调用KillMonitor时,你只杀死了shell(因为这是你的PID),而不是监视器。

您可能还对如何派生守护进程感兴趣?来自Perl常见问题解答。

我假设在你离开测试之前,你的所有孩子都已经退出了?因为否则,它可能会挂在STDERR上,这可能会混淆证明。如果您可以关闭STDERR,或者至少重定向到父进程中的管道,那么这可能是您遇到的一个问题。

除此之外,我还想指出,您不需要转义正斜杠,如果您不使用shell元字符(空格不是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";

相关内容

  • 没有找到相关文章

最新更新