doc: various updates and disclaimers
[unicorn.git] / t / active-unix-socket.t
blobff731b5f5cedf228513980f44f23496acc8dcfa3
1 #!perl -w
2 # Copyright (C) unicorn hackers <unicorn-public@yhbt.net>
3 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
5 use v5.14; BEGIN { require './t/lib.perl' };
6 use IO::Socket::UNIX;
7 use autodie;
8 no autodie 'kill';
9 my %to_kill;
10 END { kill('TERM', values(%to_kill)) if keys %to_kill }
11 my $u1 = "$tmpdir/u1.sock";
12 my $u2 = "$tmpdir/u2.sock";
14         open my $fh, '>', "$tmpdir/u1.conf.rb";
15         print $fh <<EOM;
16 pid "$tmpdir/u.pid"
17 listen "$u1"
18 stderr_path "$err_log"
19 EOM
20         close $fh;
22         open $fh, '>', "$tmpdir/u2.conf.rb";
23         print $fh <<EOM;
24 pid "$tmpdir/u.pid"
25 listen "$u2"
26 stderr_path "$tmpdir/err2.log"
27 EOM
28         close $fh;
30         open $fh, '>', "$tmpdir/u3.conf.rb";
31         print $fh <<EOM;
32 pid "$tmpdir/u3.pid"
33 listen "$u1"
34 stderr_path "$tmpdir/err3.log"
35 EOM
36         close $fh;
39 my @uarg = qw(-D -E none t/integration.ru);
41 # this pipe will be used to notify us when all daemons die:
42 pipe(my $p0, my $p1);
43 fcntl($p1, POSIX::F_SETFD, 0);
45 # start the first instance
46 unicorn('-c', "$tmpdir/u1.conf.rb", @uarg)->join;
47 is($?, 0, 'daemonized 1st process');
48 chomp($to_kill{u1} = slurp("$tmpdir/u.pid"));
49 like($to_kill{u1}, qr/\A\d+\z/s, 'read pid file');
51 chomp(my $worker_pid = readline(unix_start($u1, 'GET /pid')));
52 like($worker_pid, qr/\A\d+\z/s, 'captured worker pid');
53 ok(kill(0, $worker_pid), 'worker is kill-able');
56 # 2nd process conflicts on PID
57 unicorn('-c', "$tmpdir/u2.conf.rb", @uarg)->join;
58 isnt($?, 0, 'conflicting PID file fails to start');
60 chomp(my $pidf = slurp("$tmpdir/u.pid"));
61 is($pidf, $to_kill{u1}, 'pid file contents unchanged after start failure');
63 chomp(my $pid2 = readline(unix_start($u1, 'GET /pid')));
64 is($worker_pid, $pid2, 'worker PID unchanged');
67 # 3rd process conflicts on socket
68 unicorn('-c', "$tmpdir/u3.conf.rb", @uarg)->join;
69 isnt($?, 0, 'conflicting UNIX socket fails to start');
71 chomp($pid2 = readline(unix_start($u1, 'GET /pid')));
72 is($worker_pid, $pid2, 'worker PID still unchanged');
74 chomp($pidf = slurp("$tmpdir/u.pid"));
75 is($pidf, $to_kill{u1}, 'pid file contents unchanged after 2nd start failure');
77 { # teardown initial process via SIGKILL
78         ok(kill('KILL', delete $to_kill{u1}), 'SIGKILL initial daemon');
79         close $p1;
80         vec(my $rvec = '', fileno($p0), 1) = 1;
81         is(select($rvec, undef, undef, 5), 1, 'timeout for pipe HUP');
82         is(my $undef = <$p0>, undef, 'process closed pipe writer at exit');
83         ok(-f "$tmpdir/u.pid", 'pid file stayed after SIGKILL');
84         ok(-S $u1, 'socket stayed after SIGKILL');
85         is(IO::Socket::UNIX->new(Peer => $u1, Type => SOCK_STREAM), undef,
86                 'fail to connect to u1');
87         for (1..50) { # wait for init process to reap worker
88                 kill(0, $worker_pid) or last;
89                 sleep 0.011;
90         }
91         ok(!kill(0, $worker_pid), 'worker gone after parent dies');
94 # restart the first instance
96         pipe($p0, $p1);
97         fcntl($p1, POSIX::F_SETFD, 0);
98         unicorn('-c', "$tmpdir/u1.conf.rb", @uarg)->join;
99         is($?, 0, 'daemonized 1st process');
100         chomp($to_kill{u1} = slurp("$tmpdir/u.pid"));
101         like($to_kill{u1}, qr/\A\d+\z/s, 'read pid file');
103         chomp($pid2 = readline(unix_start($u1, 'GET /pid')));
104         like($pid2, qr/\A\d+\z/, 'worker running');
106         ok(kill('TERM', delete $to_kill{u1}), 'SIGTERM restarted daemon');
107         close $p1;
108         vec(my $rvec = '', fileno($p0), 1) = 1;
109         is(select($rvec, undef, undef, 5), 1, 'timeout for pipe HUP');
110         is(my $undef = <$p0>, undef, 'process closed pipe writer at exit');
111         ok(!-f "$tmpdir/u.pid", 'pid file gone after SIGTERM');
112         ok(-S $u1, 'socket stays after SIGTERM');
115 check_stderr;
116 undef $tmpdir;
117 done_testing;