about summary refs log tree commit homepage
path: root/t/active-unix-socket.t
diff options
context:
space:
mode:
Diffstat (limited to 't/active-unix-socket.t')
-rw-r--r--t/active-unix-socket.t117
1 files changed, 117 insertions, 0 deletions
diff --git a/t/active-unix-socket.t b/t/active-unix-socket.t
new file mode 100644
index 0000000..ff731b5
--- /dev/null
+++ b/t/active-unix-socket.t
@@ -0,0 +1,117 @@
+#!perl -w
+# Copyright (C) unicorn hackers <unicorn-public@yhbt.net>
+# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
+
+use v5.14; BEGIN { require './t/lib.perl' };
+use IO::Socket::UNIX;
+use autodie;
+no autodie 'kill';
+my %to_kill;
+END { kill('TERM', values(%to_kill)) if keys %to_kill }
+my $u1 = "$tmpdir/u1.sock";
+my $u2 = "$tmpdir/u2.sock";
+{
+        open my $fh, '>', "$tmpdir/u1.conf.rb";
+        print $fh <<EOM;
+pid "$tmpdir/u.pid"
+listen "$u1"
+stderr_path "$err_log"
+EOM
+        close $fh;
+
+        open $fh, '>', "$tmpdir/u2.conf.rb";
+        print $fh <<EOM;
+pid "$tmpdir/u.pid"
+listen "$u2"
+stderr_path "$tmpdir/err2.log"
+EOM
+        close $fh;
+
+        open $fh, '>', "$tmpdir/u3.conf.rb";
+        print $fh <<EOM;
+pid "$tmpdir/u3.pid"
+listen "$u1"
+stderr_path "$tmpdir/err3.log"
+EOM
+        close $fh;
+}
+
+my @uarg = qw(-D -E none t/integration.ru);
+
+# this pipe will be used to notify us when all daemons die:
+pipe(my $p0, my $p1);
+fcntl($p1, POSIX::F_SETFD, 0);
+
+# start the first instance
+unicorn('-c', "$tmpdir/u1.conf.rb", @uarg)->join;
+is($?, 0, 'daemonized 1st process');
+chomp($to_kill{u1} = slurp("$tmpdir/u.pid"));
+like($to_kill{u1}, qr/\A\d+\z/s, 'read pid file');
+
+chomp(my $worker_pid = readline(unix_start($u1, 'GET /pid')));
+like($worker_pid, qr/\A\d+\z/s, 'captured worker pid');
+ok(kill(0, $worker_pid), 'worker is kill-able');
+
+
+# 2nd process conflicts on PID
+unicorn('-c', "$tmpdir/u2.conf.rb", @uarg)->join;
+isnt($?, 0, 'conflicting PID file fails to start');
+
+chomp(my $pidf = slurp("$tmpdir/u.pid"));
+is($pidf, $to_kill{u1}, 'pid file contents unchanged after start failure');
+
+chomp(my $pid2 = readline(unix_start($u1, 'GET /pid')));
+is($worker_pid, $pid2, 'worker PID unchanged');
+
+
+# 3rd process conflicts on socket
+unicorn('-c', "$tmpdir/u3.conf.rb", @uarg)->join;
+isnt($?, 0, 'conflicting UNIX socket fails to start');
+
+chomp($pid2 = readline(unix_start($u1, 'GET /pid')));
+is($worker_pid, $pid2, 'worker PID still unchanged');
+
+chomp($pidf = slurp("$tmpdir/u.pid"));
+is($pidf, $to_kill{u1}, 'pid file contents unchanged after 2nd start failure');
+
+{ # teardown initial process via SIGKILL
+        ok(kill('KILL', delete $to_kill{u1}), 'SIGKILL initial daemon');
+        close $p1;
+        vec(my $rvec = '', fileno($p0), 1) = 1;
+        is(select($rvec, undef, undef, 5), 1, 'timeout for pipe HUP');
+        is(my $undef = <$p0>, undef, 'process closed pipe writer at exit');
+        ok(-f "$tmpdir/u.pid", 'pid file stayed after SIGKILL');
+        ok(-S $u1, 'socket stayed after SIGKILL');
+        is(IO::Socket::UNIX->new(Peer => $u1, Type => SOCK_STREAM), undef,
+                'fail to connect to u1');
+        for (1..50) { # wait for init process to reap worker
+                kill(0, $worker_pid) or last;
+                sleep 0.011;
+        }
+        ok(!kill(0, $worker_pid), 'worker gone after parent dies');
+}
+
+# restart the first instance
+{
+        pipe($p0, $p1);
+        fcntl($p1, POSIX::F_SETFD, 0);
+        unicorn('-c', "$tmpdir/u1.conf.rb", @uarg)->join;
+        is($?, 0, 'daemonized 1st process');
+        chomp($to_kill{u1} = slurp("$tmpdir/u.pid"));
+        like($to_kill{u1}, qr/\A\d+\z/s, 'read pid file');
+
+        chomp($pid2 = readline(unix_start($u1, 'GET /pid')));
+        like($pid2, qr/\A\d+\z/, 'worker running');
+
+        ok(kill('TERM', delete $to_kill{u1}), 'SIGTERM restarted daemon');
+        close $p1;
+        vec(my $rvec = '', fileno($p0), 1) = 1;
+        is(select($rvec, undef, undef, 5), 1, 'timeout for pipe HUP');
+        is(my $undef = <$p0>, undef, 'process closed pipe writer at exit');
+        ok(!-f "$tmpdir/u.pid", 'pid file gone after SIGTERM');
+        ok(-S $u1, 'socket stays after SIGTERM');
+}
+
+check_stderr;
+undef $tmpdir;
+done_testing;