14

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 ファイルの最後でテスト ハーネスがハングします。 1つしかない場合。

最初は、サブプロセスを強制終了し、機能しないままにしていたためではないかと思いました。だから私は追加しました..

$SIG{CHLD} = \&REAPER;
sub REAPER {
   my $pid = wait;
   $SIG{CHLD} = \&REAPER;
}

コードに。しかし、それは役に立ちません。実際、閉じた検査では、私の perl テスト ファイルが終了し、現在は機能していないプロセスであり、その子を取得していない証明ラッパー スクリプトであることが判明しました。実際、テストスクリプトの最後に die() 呼び出しを追加すると...

# Looks like your test died just after 7.

私のスクリプトは終了しましたが、何らかの理由でハーネスが解けません。

テストが失敗し、ハーネスが正常に終了したときにサブプロセスを無効にしたときのように、それを混乱させているのは間違いなく私のサブプロセスであることを確認しました.

何らかの方法でハーネスを混乱させる可能性のあるプロセスを開始する方法に間違っていることはありますか?

4

2 に答える 2

12

fork()失敗したかどうかはテストしないことに注意してください。「false」が「子」を意味すると仮定する前に、 $pid定義されていることを確認する必要があります。

your$cmdにはシェルのメタ文字 (スペース) が含まれているため、Perl は を呼び出すときに実際にシェルを使用していますexec()。モニターが実行されている間、(1) Perl、(2) 子 Perl sh -c、および (3) 孫 Perl が実行されていmonitor_real.plます。これが特に意味することは、 を呼び出すときKillMonitor、シェルを強制終了するだけであり (それはあなたが持っている PID であるため)、モニターを強制終了しないということです。

また、デーモン プロセスをフォークするにはどうすればよいですか? にも興味があるかもしれません。Perl FAQ から。

于 2008-10-08T16:32:44.983 に答える
8

テストを終了する前に、すべての子供が終了したと思いますか? そうしないと、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";
于 2008-10-08T21:07:23.947 に答える