Si dimostrano gli arresti dei fork dei sottoprocessi nelle prove unitarie Perl; Test :: Imbracatura in uscita

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

Domanda

Ho cercato di utilizzare l'utilità / modulo Perl "dimostrare" come cablaggio di prova per alcuni test unitari. I test unitari sono un po 'più di "sistema" di "unità" come ho bisogno di interrompere alcuni processi in background come parte del test, utilizzando il seguente ...

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

Tuttavia, per qualche motivo, quando ho il mio file .t che gira su alcuni processi extra, il cablaggio del test si blocca alla fine del primo file .t dopo che tutti i test sono terminati, piuttosto che passare al file successivo o uscire se ce n'è solo uno.

All'inizio mi chiedevo se potesse essere perché stavo uccidendo i miei sottoprocessi e li lasciavo defunti. Quindi ho aggiunto ..

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

Al codice. Ma questo non aiuta. In effetti ad un esame chiuso risulta che il mio file di test perl è uscito e ora è un processo defunto ed è lo script wrapper di prova che non ha raccolto suo figlio. In effetti quando ho aggiunto una chiamata die () alla fine del mio script di test ho ricevuto ...

# Looks like your test died just after 7.

Quindi la mia sceneggiatura è uscita, ma per qualche ragione l'imbracatura non si sta dipanando.

Ho confermato che sono sicuramente i miei sottoprocessi a sconvolgerlo come quando li ho disabilitati mentre i test fallivano l'imbracatura è uscita correttamente.

C'è qualcosa che sto facendo di sbagliato nel modo in cui sto avviando i miei processi che potrebbe sconvolgere il cablaggio in qualche modo?

Grazie

Peter

È stato utile?

Soluzione

Suppongo che tutti i tuoi figli siano usciti prima di lasciare il test? Perché altrimenti, potrebbe essere aggrappato a STDERR, il che potrebbe confondere la prova. Se potresti chiudere STDERR, o almeno reindirizzare a una pipe nel tuo processo genitore, questo potrebbe essere un problema che stai riscontrando.

Oltre a ciò, vorrei anche sottolineare che non è necessario sfuggire alle barre, e se non si utilizzano i metacaratteri della shell (gli spazi non sono metacaratteri perl - pensate " *? {} () "), dovresti essere esplicito e creare un elenco:

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

Altri suggerimenti

Notare che non si verifica se fork () non è riuscito. Devi assicurarti che $ pid sia definito prima di assumere che "falso" significa "bambino".

Poiché il tuo $ cmd contiene metacaratteri (spazi) della shell, Perl sta effettivamente usando una shell quando chiami exec () . Mentre il monitor è in esecuzione, c'è (1) Perl, (2) un figlio sh -c e (3) un nipote Perl che esegue monitor_real.pl . Ciò che significa in particolare è quando chiami KillMonitor , stai solo uccidendo la shell (perché è il PID che hai) e non il monitor.

Potresti anche essere interessato a Come faccio a fork un processo daemon? dalle FAQ Perl.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top