Pergunta

Eu tenho tentado usar o utilitário / módulo Perl "provar" como um equipamento de teste para alguns testes de unidade. Os testes unitários são um pouco mais "sistema" de "unidade" como eu preciso bifurcar fora de alguns processos em segundo plano, como parte do ensaio, utilizando o seguinte ...

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);
}

No entanto, por algum motivo, quando eu tenho minha rotação arquivo de .t-se alguns processos extra faz com que o equipamento de teste para pendurar no final do primeiro arquivo .t após todos os testes terminarem, ao invés de ir para o próximo arquivo , ou sair se houver apenas um.

No começo eu me perguntava se poderia ser porque eu estava matando de minhas sub-processos e deixando-os extinta. Então eu adicionei ..

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

Para o código. Mas isso não ajuda. Na verdade no exame fechado verifica-se que o meu arquivo de teste perl saiu e agora é um processo extinto e é a prova invólucro script que não colheu seu filho. Na verdade, quando eu adicionei uma chamada die () no final do meu script de teste eu tenho ...

# Looks like your test died just after 7.

Então, o meu script saiu, mas por algum motivo o cinto não está se desfazendo.

Eu fiz confirmar que ele é definitivamente o meu sub-processos que estão transformando-o como quando eu desativado-los enquanto os testes não o chicote saiu corretamente.

Existe algo que eu estou fazendo errado com a maneira que eu estou começando minhas processos que possam perturbar o arnês de alguma forma?

Graças

Peter

Foi útil?

Solução

Estou assumindo que todos os seus filhos tenham saído antes de deixar o seu teste? Porque caso contrário, ele pode ser pendurado em STDERR, que pode confundir provar. Se você pudesse fechar STDERR, ou pelo menos redirecionamento para um tubo em seu processo pai, que pode ser um problema que você está tendo.

Além disso, eu também apontam que você não precisa escapar barras, e se você não estiver usando metacaracteres shell (espaços não são metacaracteres para perl - pensar "*?{}()"), você deve ser explícito e criar uma lista:

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";

Outras dicas

Note que você não testar se fork() falhou. Você precisa ter certeza de $pid é definido antes de assumir que significa "falsos" "criança. "

Porque seu $cmd contém metacaracteres shell (espaços), Perl está realmente usando um shell quando você chamar exec(). Enquanto o monitor estiver funcionando, não há (1) Perl, (2) um sh -c criança, e monitor_real.pl execução (3) um neto Perl. O que isso significa, em particular, é quando você chamar KillMonitor, você está matando apenas o shell (porque esse é o PID que você tem) e não o monitor.

Você pode também estar interessado em Como eu bifurcar um processo daemon? do Perl FAQ.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top