From 27ee629e6b583f60fea0ab78fb3ebd0d1d71d9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 3 Dec 2018 13:14:05 +0100 Subject: [PATCH] stop.pl - refactor --- bin/tests/system/stop.pl | 172 ++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 76 deletions(-) diff --git a/bin/tests/system/stop.pl b/bin/tests/system/stop.pl index e6079aed87..a0ebc95d7d 100644 --- a/bin/tests/system/stop.pl +++ b/bin/tests/system/stop.pl @@ -15,7 +15,10 @@ # If a server is specified, stop it. Otherwise, stop all servers for test. use strict; -use Cwd 'abs_path'; +use warnings; + +use Cwd ':DEFAULT', 'abs_path'; +use English '-no_match_vars'; use Getopt::Long; # Usage: @@ -35,61 +38,87 @@ my $usage = "usage: $0 [--use-rndc [--halt] [--port port]] test-directory [serve my $use_rndc = 0; my $halt = 0; -my $port = 9953; -GetOptions('use-rndc' => \$use_rndc, 'halt' => \$halt, 'port=i' => \$port) or die "$usage\n"; - +my $rndc_port = 9953; my $errors = 0; -my $test = $ARGV[0]; -my $server = $ARGV[1]; -die "$usage\n" unless defined($test); -die "No test directory: \"$test\"\n" unless (-d $test); -die "No server directory: \"$server\"\n" if (defined($server) && !-d "$test/$server"); +GetOptions( + 'use-rndc!' => \$use_rndc, + 'halt!' => \$halt, + 'port=i' => \$rndc_port + ) or die "$usage\n"; + +my ( $test, $server_arg ) = @ARGV; + +if (!$test) { + die "$usage\n"; +} # Global variables -my $testdir = abs_path($test); -my @servers; +my $topdir = abs_path($ENV{'SYSTEMTESTTOP'}); +my $testdir = abs_path($topdir . "/" . $test); +if (! -d $testdir) { + die "No test directory: \"$testdir\"\n"; +} -# Determine which servers need to be stopped. -if (defined $server) { - @servers = ($server); +if ($server_arg && ! -d "$testdir/$server_arg") { + die "No server directory: \"$testdir/$server_arg\"\n"; +} + +my $RNDC = $ENV{RNDC}; + +my @ns; +my @ans; + +if ($server_arg) { + if ($server_arg =~ /^ns/) { + push(@ns, $server_arg); + } elsif ($server_arg =~ /^ans/) { + push(@ans, $server_arg); + } else { + print "$0: ns or ans directory expected"; + print "I:$test:failed"; + } } else { - local *DIR; - opendir DIR, $testdir or die "$testdir: $!\n"; + # Determine which servers need to be stopped for this test. + opendir DIR, $testdir or die "unable to read test directory: \"$test\" ($OS_ERROR)\n"; my @files = sort readdir DIR; closedir DIR; - my @ns = grep /^ns[0-9]*$/, @files; - my @ans = grep /^ans[0-9]*$/, @files; - - push @servers, @ns, @ans; + @ns = grep /^ns[0-9]*$/, @files; + @ans = grep /^ans[0-9]*$/, @files; } - # Stop the server(s), pass 1: rndc. if ($use_rndc) { - foreach my $server (grep /^ns/, @servers) { - stop_rndc($server); + foreach my $name(@ns) { + stop_rndc($name, $rndc_port); } - wait_for_servers(30, grep /^ns/, @servers); + @ns = wait_for_servers(30, @ns); } - # Pass 2: SIGTERM -foreach my $server (@servers) { - stop_signal($server, "TERM"); +foreach my $name (@ns) { + stop_signal($name, "TERM"); } -wait_for_servers(60, @servers); +@ns = wait_for_servers(60, @ns); + +foreach my $name(@ans) { + stop_signal($name, "TERM"); +} + +@ans = wait_for_servers(60, @ans); # Pass 3: SIGABRT -foreach my $server (@servers) { - stop_signal($server, "ABRT"); +foreach my $name (@ns, @ans) { + print "I:$test:$name didn't die when sent a SIGTERM\n"; + stop_signal($name, "ABRT"); + $errors = 1; } -exit($errors ? 1 : 0); +exit($errors); # Subroutines @@ -97,26 +126,24 @@ exit($errors ? 1 : 0); sub server_pid_file { my($server) = @_; - my $pid_file; - if ($server =~ /^ns/) { - $pid_file = "named.pid"; - } elsif ($server =~ /^ans/) { - $pid_file = "ans.pid"; - } else { - print "I:Unknown server type $server\n"; - exit 1; - } - $pid_file = "$testdir/$server/$pid_file"; + return $testdir . "/" . $server . "/named.pid" if ($server =~ /^ns/); + return $testdir . "/" . $server . "/ans.pid" if ($server =~ /^ans/); + + die "Unknown server type $server\n"; } # Read a PID. sub read_pid { - my($pid_file) = @_; + my ( $server ) = @_; + + my $pid_file = server_pid_file($server); + + return unless -f $pid_file; local *FH; my $result = open FH, "< $pid_file"; if (!$result) { - print "I:$pid_file: $!\n"; + print "I:$test:$pid_file: $!\n"; unlink $pid_file; return; } @@ -128,47 +155,43 @@ sub read_pid { # Stop a named process with rndc. sub stop_rndc { - my($server) = @_; + my ( $server, $port ) = @_; + my $n; - return unless ($server =~ /^ns(\d+)$/); - my $ip = "10.53.0.$1"; + if ($server =~ /^ns(\d+)/) { + $n = $1; + } else { + die "unable to parse server number from name \"$server\"\n"; + } + + my $ip = "10.53.0.$n"; my $how = $halt ? "halt" : "stop"; # Ugly, but should work. - system("$ENV{RNDC} -c ../common/rndc.conf -s $ip -p $port $how | sed 's/^/I:$server /'"); + system("$RNDC -c ../common/rndc.conf -s $ip -p $port $how | sed 's/^/I:$test:$server /'"); return; } # Stop a server by sending a signal to it. sub stop_signal { - my($server, $sig) = @_; - - my $pid_file = server_pid_file($server); - return unless -f $pid_file; + my($server, $signal) = @_; - my $pid = read_pid($pid_file); + my $pid = read_pid($server); return unless defined($pid); - if ($sig eq 'ABRT') { - print "I:$server didn't die when sent a SIGTERM\n"; - $errors++; + my $result; + my $pid_file = server_pid_file($server); + + if ($^O eq 'cygwin') { + $result = !system("/bin/kill -f -$signal $pid"); + } else { + $result = kill $signal, $pid; } - my $result; - if ($^O eq 'cygwin') { - $result = system("/bin/kill -f -$sig $pid"); + if (!$result) { + print "I:$test:$server died before a SIG$signal was sent\n"; + $errors = 1; unlink $pid_file; - if ($result != 0) { - print "I:$test:$server died before a SIG$sig was sent\n"; - $errors++; - } - } else { - $result = kill $sig, $pid; - if (!$result) { - print "I:$test:$server died before a SIG$sig was sent\n"; - unlink $pid_file; - $errors++; - } } return; @@ -177,14 +200,11 @@ sub stop_signal { sub wait_for_servers { my($timeout, @servers) = @_; - my @pid_files = grep { defined($_) } - map { server_pid_file($_) } @servers; - - while ($timeout > 0 && @pid_files > 0) { - @pid_files = grep { -f $_ } @pid_files; - sleep 1 if (@pid_files > 0); + while ($timeout > 0 && @servers > 0) { + @servers = grep { -f server_pid_file($_) } @servers; + sleep 1 if (@servers > 0); $timeout--; } - return; + return @servers; }