Perl単体テストでサブプロセスを分岐すると、証明が停止します。 Test :: Harnessの終了
-
06-07-2019 - |
質問
Perlユーティリティ/モジュール" prove"を使用しようとしました。一部の単体テストのテストハーネスとして。ユニットテストはもう少し「システム」です。 「単位」よりもテストの一環としていくつかのバックグラウンドプロセスを分岐する必要があるため、次を使用して...
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ファイルの最後でテストハーネスがハングします、または1つしかない場合は終了します。
最初は、サブプロセスを強制終了し、それらを無効にしていたためかどうか疑問に思いました。そこで追加しました。
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $pid = wait;
$SIG{CHLD} = \&REAPER;
}
コードへ。しかし、それは役に立ちません。実際、クローズド試験では、perlテストファイルが終了し、現在は無効なプロセスであり、子を取得していないのは実証済みのラッパースクリプトであることがわかりました。実際、テストスクリプトの最後にdie()呼び出しを追加すると、...
# Looks like your test died just after 7.
私のスクリプトは終了しましたが、何らかの理由でハーネスが解けていません。
テストが失敗してハーネスが正常に終了したときに無効にしたときのように、それが動揺しているのは間違いなく私のサブプロセスであることを確認しました。
何らかの方法でハーネスを混乱させる可能性のあるプロセスの起動方法で間違っていることはありますか?
ありがとう
ピーター
解決
テストを終了する前にすべての子供が退学したと仮定していますか?それ以外の場合は、STDERRに依存している可能性があるため、証明が混乱する可能性があります。 STDERRを閉じることができる場合、または少なくとも親プロセスのパイプにリダイレクトできる場合、それが問題の1つである可能性があります。
それに加えて、スラッシュをエスケープする必要がないことも指摘します。シェルメタキャラクターを使用していない場合(スペースは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
が定義であることを確認する必要がありますその" false" 「子」を意味します。
$ cmd
にはシェルメタキャラクター(スペース)が含まれているため、Perlは実際に exec()
を呼び出すときにシェルを使用しています。モニターの実行中、(1)Perl、(2)子 sh -c
、および(3) monitor_real.pl
を実行する孫Perlがあります。それが特に意味するのは、 KillMonitor
を呼び出したとき、モニターではなくシェル(これはあなたが持っているPIDであるため)だけを殺すことです。
デーモンプロセスをフォークするにはどうすればよいですか Perl FAQから。