mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00
300 lines
8.1 KiB
Perl
300 lines
8.1 KiB
Perl
#!/usr/bin/perl
|
|
|
|
BEGIN {
|
|
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
|
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
|
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
|
};
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
|
|
use Test::More;
|
|
use Time::HiRes qw(sleep);
|
|
use File::Temp qw(tempfile);
|
|
|
|
use Daemon;
|
|
use PerconaTest;
|
|
|
|
use constant PTDEVDEBUG => $ENV{PTDEVDEBUG} || 0;
|
|
|
|
my $cmd = "$trunk/t/lib/samples/daemonizes.pl";
|
|
my $pid_file = "/tmp/pt-daemon-test.pid.$PID";
|
|
my $log_file = "/tmp/pt-daemon-test.log.$PID";
|
|
sub rm_tmp_files() {
|
|
-f $pid_file && (unlink $pid_file || die "Error removing $pid_file");
|
|
-f $log_file && (unlink $log_file || die "Error removing $log_file");
|
|
}
|
|
|
|
# ############################################################################
|
|
# Test that it daemonizes, creates a PID file, and removes that PID file.
|
|
# ############################################################################
|
|
|
|
my $ret_val = system("$cmd 3 --daemonize --pid $pid_file --log $log_file");
|
|
die 'Cannot test Daemon.pm because t/daemonizes.pl is not working'
|
|
unless $ret_val == 0;
|
|
|
|
PerconaTest::wait_for_files($pid_file, $log_file)
|
|
or die "$cmd did not create $pid_file and $log_file";
|
|
|
|
my ($pid, $output) = PerconaTest::get_cmd_pid("$cmd 3");
|
|
|
|
like(
|
|
$output,
|
|
qr/$cmd/,
|
|
'Daemonizes'
|
|
);
|
|
|
|
ok(
|
|
-f $pid_file,
|
|
'Creates PID file'
|
|
);
|
|
|
|
$output = slurp_file($pid_file);
|
|
chomp($output) if $output;
|
|
|
|
is(
|
|
$output,
|
|
$pid,
|
|
'PID file has correct PID'
|
|
);
|
|
|
|
SKIP: {
|
|
skip "Previous tests failed", 1 unless $pid;
|
|
|
|
# Wait until the process goes away
|
|
PerconaTest::wait_until(sub { !kill(0, $pid) });
|
|
ok(
|
|
! -f $pid_file,
|
|
'Removes PID file upon exit'
|
|
);
|
|
}
|
|
|
|
# ############################################################################
|
|
# Check that STDOUT can be redirected
|
|
# ############################################################################
|
|
rm_tmp_files();
|
|
|
|
system("$cmd 0 --daemonize --log $log_file");
|
|
PerconaTest::wait_for_files($log_file);
|
|
|
|
ok(
|
|
-f $log_file,
|
|
'Log file exists'
|
|
);
|
|
|
|
$output = slurp_file($log_file);
|
|
|
|
like(
|
|
$output,
|
|
qr/STDOUT\nSTDERR\n/,
|
|
'STDOUT and STDERR went to log file'
|
|
);
|
|
|
|
my $log_size = -s $log_file;
|
|
PTDEVDEBUG && PerconaTest::_d('log size', $log_size);
|
|
|
|
# Check that the log file is appended to.
|
|
system("$cmd 0 --daemonize --log $log_file");
|
|
PerconaTest::wait_until(sub { -s $log_file > $log_size });
|
|
$output = slurp_file($log_file);
|
|
|
|
like(
|
|
$output,
|
|
qr/STDOUT\nSTDERR\nSTDOUT\nSTDERR\n/,
|
|
'Appends to log file'
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Issue 383: mk-deadlock-logger should die if --pid file specified exists
|
|
# ##########################################################################
|
|
rm_tmp_files();
|
|
diag(`touch $pid_file`);
|
|
|
|
ok(
|
|
-f $pid_file,
|
|
'PID file already exists'
|
|
);
|
|
|
|
$output = `$cmd 2 --daemonize --pid $pid_file 2>&1`;
|
|
like(
|
|
$output,
|
|
qr{PID file $pid_file exists},
|
|
'Dies if PID file already exists'
|
|
);
|
|
|
|
$output = `ps wx | grep '$cmd 0' | grep -v grep`;
|
|
unlike(
|
|
$output,
|
|
qr/$cmd/,
|
|
'Does not daemonizes'
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Issue 417: --daemonize doesn't let me log out of terminal cleanly
|
|
# ##########################################################################
|
|
rm_tmp_files();
|
|
SKIP: {
|
|
skip 'No /proc', 1 unless -d '/proc';
|
|
skip 'No fd in /proc', 1 unless -l "/proc/$PID/0" || -l "/proc/$PID/fd/0";
|
|
|
|
system("$cmd 15 --daemonize --pid $pid_file --log $log_file");
|
|
PerconaTest::wait_for_files($pid_file, $log_file)
|
|
or die "$cmd did not create $pid_file and $log_file";
|
|
my $pid = PerconaTest::get_cmd_pid("$cmd 15")
|
|
or die "Cannot get PID of $cmd 15\n" . `ps xww`;
|
|
my $proc_fd_0 = -l "/proc/$pid/0" ? "/proc/$pid/0"
|
|
: -l "/proc/$pid/fd/0" ? "/proc/$pid/fd/0"
|
|
: die "Cannot find fd 0 symlink in /proc/$pid";
|
|
PTDEVDEBUG && PerconaTest::_d('pid_file', $pid_file,
|
|
'pid', $pid, 'proc_fd_0', $proc_fd_0, `ls -l $proc_fd_0`);
|
|
my $stdin = readlink $proc_fd_0;
|
|
is(
|
|
$stdin,
|
|
'/dev/null',
|
|
'Reopens STDIN to /dev/null'
|
|
);
|
|
|
|
PerconaTest::kill_program(pid => $pid);
|
|
|
|
# SKIP: {
|
|
# skip "-t is not reliable", 1;
|
|
# rm_tmp_files();
|
|
# system("echo foo | $cmd 5 --daemonize --pid $pid_file --log $log_file");
|
|
# PerconaTest::wait_for_files($pid_file, $log_file);
|
|
# chomp($pid = slurp_file($pid_file));
|
|
# $proc_fd_0 = -l "/proc/$pid/0" ? "/proc/$pid/0"
|
|
# : -l "/proc/$pid/fd/0" ? "/proc/$pid/fd/0"
|
|
# : die "Cannot find fd 0 symlink in /proc/$pid";
|
|
# PTDEVDEBUG && PerconaTest::_d('pid_file', $pid_file,
|
|
# 'pid', $pid, 'proc_fd_0', $proc_fd_0, `ls -l $proc_fd_0`);
|
|
# $stdin = readlink $proc_fd_0;
|
|
# like(
|
|
# $stdin,
|
|
# qr/pipe/,
|
|
# 'Does not reopen STDIN to /dev/null when piped',
|
|
# );
|
|
# rm_tmp_files();
|
|
# }
|
|
}
|
|
|
|
# ##########################################################################
|
|
# Issue 419: Daemon should check wether process with pid obtained from
|
|
# pid-file is still running
|
|
# ##########################################################################
|
|
rm_tmp_files();
|
|
system("$cmd 7 --daemonize --pid $pid_file >/dev/null 2>&1");
|
|
PerconaTest::wait_for_files($pid_file);
|
|
$pid = PerconaTest::get_cmd_pid("$cmd 7")
|
|
or die "Cannot get PID of $cmd 7";
|
|
kill 9, $pid;
|
|
sleep 0.25;
|
|
(undef, $output) = PerconaTest::get_cmd_pid("$cmd 7");
|
|
unlike(
|
|
$output,
|
|
qr/daemonize/,
|
|
'Kill 9 daemonizes.pl (issue 419)'
|
|
);
|
|
ok(
|
|
-f $pid_file,
|
|
'PID file remains after kill 9 (issue 419)'
|
|
);
|
|
|
|
my (undef, $tempfile) = tempfile();
|
|
|
|
system("$cmd 6 --daemonize --log $log_file --pid $pid_file > $tempfile 2>&1");
|
|
PerconaTest::wait_for_files($log_file, $pid_file, $tempfile);
|
|
my $new_pid;
|
|
($new_pid, $output) = PerconaTest::get_cmd_pid("$cmd 6");
|
|
|
|
like(
|
|
$output,
|
|
qr/$cmd/,
|
|
'Runs when PID file exists but old process is dead (issue 419)'
|
|
);
|
|
|
|
like(
|
|
slurp_file($tempfile),
|
|
qr/Overwriting PID file $pid_file because PID $pid is not running/,
|
|
'Says that old PID is not running (issue 419)'
|
|
);
|
|
|
|
cmp_ok(
|
|
$pid,
|
|
'!=',
|
|
$new_pid,
|
|
'Overwrites PID file with new PID (issue 419)'
|
|
);
|
|
|
|
PerconaTest::wait_until(sub { !-f $pid_file });
|
|
ok(
|
|
!-f $pid_file,
|
|
'Re-used PID file still removed (issue 419)'
|
|
);
|
|
|
|
diag(`rm $tempfile >/dev/null`);
|
|
|
|
# ############################################################################
|
|
# Check that it actually checks the running process.
|
|
# ############################################################################
|
|
rm_tmp_files();
|
|
system("$cmd 10 --daemonize --log $log_file --pid $pid_file");
|
|
PerconaTest::wait_for_files($pid_file, $log_file);
|
|
chomp($pid = slurp_file($pid_file));
|
|
$output = `$cmd 1 --daemonize --pid $pid_file 2>&1`;
|
|
like(
|
|
$output,
|
|
qr/PID file $pid_file exists and PID $pid is running/,
|
|
'Says that PID is running (issue 419)'
|
|
);
|
|
|
|
PerconaTest::kill_program(pid => $pid);
|
|
rm_tmp_files();
|
|
|
|
# #############################################################################
|
|
# Test auto-PID file removal without having to daemonize (for issue 391).
|
|
# #############################################################################
|
|
my $pid_file2 = "/tmp/pt-daemon-test.pid2.$PID";
|
|
{
|
|
my $d2 = Daemon->new(
|
|
pid_file => $pid_file2,
|
|
);
|
|
$d2->run();
|
|
ok(
|
|
-f $pid_file2,
|
|
'PID file for non-daemon exists'
|
|
);
|
|
}
|
|
# Since $d2 was locally scoped, it should have been destoryed by now.
|
|
# This should have caused the PID file to be automatically removed.
|
|
ok(
|
|
!-f $pid_file2,
|
|
'PID file auto-removed for non-daemon'
|
|
);
|
|
|
|
# We should still die if the PID file already exists,
|
|
# even if we're not a daemon.
|
|
{
|
|
diag(`touch $pid_file2`);
|
|
eval {
|
|
my $d2 = Daemon->new(
|
|
pid_file => $pid_file2,
|
|
);
|
|
$d2->run();
|
|
};
|
|
like(
|
|
$EVAL_ERROR,
|
|
qr/PID file $pid_file2 exists/,
|
|
'Dies if PID file already exists for non-daemon'
|
|
);
|
|
|
|
unlink $pid_file2 if -f $pid_file2;
|
|
}
|
|
|
|
# #############################################################################
|
|
# Done.
|
|
# #############################################################################
|
|
rm_tmp_files();
|
|
done_testing;
|