Les sous-processus de forking dans les tests unitaires Perl s'arrêtent; Test :: harnais sortant

StackOverflow https://stackoverflow.com/questions/183560

Question

J'ai essayé d'utiliser l'utilitaire / module Perl "prouver". comme harnais de test pour certains tests unitaires. Les tests unitaires sont un peu plus " system " que " unité " car j'ai besoin de bifurquer certains processus d'arrière-plan dans le cadre du test, à l'aide des éléments suivants ...

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

Cependant, pour une raison quelconque, lorsque mon fichier .t est en train d’activer des processus supplémentaires, le faisceau de tests s’arrête à la fin du premier fichier .t une fois tous les tests terminés, au lieu de passer au fichier suivant. , ou en sortant s'il n'y en a qu'un.

Au début, je me demandais si c’était peut-être parce que j’étais en train de tuer mes sous-processus et de les laisser disparus. Alors j'ai ajouté ..

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

Au code. Mais ça n'aide pas. En fait, après un examen à huis clos, il s’avère que mon fichier de test perl est terminé et qu’il s’agit d’un processus obsolète et que c’est le script de preuve d’enveloppement qui n’a pas été exploité. En fait, lorsque j’ai ajouté un appel die () à la fin de mon script de test, j’ai ...

# Looks like your test died just after 7.

Donc, mon script s'est arrêté, mais pour une raison quelconque, le harnais ne s'est pas effondré.

J'ai confirmé que ce sont vraiment mes sous-processus qui le bouleversent, car lorsque je les ai désactivés alors que les tests échouaient, le harnais était sorti correctement.

Y a-t-il quelque chose que je ne fais pas correctement dans la façon dont je lance mes processus et qui pourrait perturber le harnais d'une manière ou d'une autre?

Merci

Peter

Était-ce utile?

La solution

Je suppose que tous vos enfants sont sortis avant que vous ne quittiez votre test? Parce que sinon, il peut être accroché à STDERR, ce qui peut prêter à confusion. Si vous pouviez fermer STDERR, ou au moins rediriger vers un canal de votre processus parent, vous rencontrerez peut-être un problème.

En outre, je ferais également remarquer que vous n'avez pas besoin d'échapper aux barres obliques, et si vous n'utilisez pas de métacaractères shell (les espaces ne sont pas des métacaractères à perl - pensez " *? {} () "), vous devez être explicite et créer une liste:

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

Autres conseils

Notez que vous ne testez pas si fork () a échoué. Vous devez vous assurer que $ pid est défini avant d'assumer que " faux " signifie "enfant".

Étant donné que votre $ cmd contient des métacaractères de shell (espaces), Perl utilise un shell lorsque vous appelez exec () . Pendant que votre moniteur est en cours d'exécution, il y a (1) Perl, (2) un enfant sh -c et (3) un petit-fils Perl exécutant monitor_real.pl . Cela signifie notamment que lorsque vous appelez KillMonitor , vous ne faites que tuer le shell (car c'est le PID que vous avez) et non le moniteur.

Vous pourriez également être intéressé par Comment créer un processus démon? dans la FAQ Perl.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top