X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=t%2Fhttpd-unix.t;h=b321c789f4f471d3525d76de8cf55e62e8fed9bf;hb=95bdac7f09c69036efed537a4d03d5bdd2ae4eb6;hp=627adfafe0cad8f58cc0aa4dd8532c406bbb357e;hpb=cd50d183273c105a7f08b1875ba6f7a51d9f8e9a;p=public-inbox.git diff --git a/t/httpd-unix.t b/t/httpd-unix.t index 627adfaf..b321c789 100644 --- a/t/httpd-unix.t +++ b/t/httpd-unix.t @@ -1,37 +1,24 @@ -# Copyright (C) 2016-2018 all contributors +# Copyright (C) 2016-2020 all contributors # License: AGPL-3.0+ # Tests for binding Unix domain sockets use strict; use warnings; use Test::More; - -foreach my $mod (qw(Plack::Util Plack::Builder PublicInbox::DS - HTTP::Date HTTP::Status)) { - eval "require $mod"; - plan skip_all => "$mod missing for httpd-unix.t" if $@; -} - -use File::Temp qw/tempdir/; +use PublicInbox::TestCommon; +use Errno qw(EADDRINUSE); +require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status)); use IO::Socket::UNIX; -use Cwd qw/getcwd/; -my $tmpdir = tempdir('httpd-unix-XXXXXX', TMPDIR => 1, CLEANUP => 1); +my ($tmpdir, $for_destroy) = tmpdir(); my $unix = "$tmpdir/unix.sock"; -my $httpd = 'blib/script/public-inbox-httpd'; -my $psgi = getcwd() . '/t/httpd-corner.psgi'; +my $psgi = './t/httpd-corner.psgi'; my $out = "$tmpdir/out.log"; my $err = "$tmpdir/err.log"; - -my $pid; -END { kill 'TERM', $pid if defined $pid }; +my $td; my $spawn_httpd = sub { my (@args) = @_; - $pid = fork; - if ($pid == 0) { - exec $httpd, @args, "--stdout=$out", "--stderr=$err", $psgi; - die "FAIL: $!\n"; - } - ok(defined $pid, 'forked httpd process successfully'); + my $cmd = [ '-httpd', @args, "--stdout=$out", "--stderr=$err", $psgi ]; + $td = start_script($cmd); }; { @@ -43,9 +30,10 @@ my $spawn_httpd = sub { } ok(!-S $unix, 'UNIX socket does not exist, yet'); -$spawn_httpd->("-l$unix"); +$spawn_httpd->("-l$unix", '-W0'); +my %o = (Peer => $unix, Type => SOCK_STREAM); for (1..1000) { - last if -S $unix; + last if -S $unix && IO::Socket::UNIX->new(%o); select undef, undef, undef, 0.02 } @@ -65,15 +53,18 @@ sub check_sock ($) { check_sock($unix); { # do not clobber existing socket - my $fpid = fork; - if ($fpid == 0) { - open STDOUT, '>>', "$tmpdir/1" or die "redirect failed: $!"; - open STDERR, '>>', "$tmpdir/2" or die "redirect failed: $!"; - exec $httpd, '-l', $unix, '-W0', $psgi; - die "FAIL: $!\n"; - } - is($fpid, waitpid($fpid, 0), 'second httpd exits'); - isnt($?, 0, 'httpd failed with failure to bind'); + my %err = ( 'linux' => EADDRINUSE, 'freebsd' => EADDRINUSE ); + open my $out, '>>', "$tmpdir/1" or die "redirect failed: $!"; + open my $err, '>>', "$tmpdir/2" or die "redirect failed: $!"; + my $cmd = ['-httpd', '-l', $unix, '-W0', $psgi]; + my $ftd = start_script($cmd, undef, { 1 => $out, 2 => $err }); + $ftd->join; + isnt($?, 0, 'httpd failure set $?'); + SKIP: { + my $ec = $err{$^O} or + skip("not sure if $^O fails with EADDRINUSE", 1); + is($? >> 8, $ec, 'httpd failed with EADDRINUSE'); + }; open my $fh, "$tmpdir/2" or die "failed to open $tmpdir/2: $!"; local $/; my $e = <$fh>; @@ -82,37 +73,35 @@ check_sock($unix); } { - my $kpid = $pid; - $pid = undef; - is(kill('TERM', $kpid), 1, 'terminate existing process'); - is(waitpid($kpid, 0), $kpid, 'existing httpd terminated'); + is($td->kill, 1, 'terminate existing process'); + $td->join; is($?, 0, 'existing httpd exited successfully'); ok(-S $unix, 'unix socket still exists'); } SKIP: { - eval 'require Net::Server::Daemonize'; - skip('Net::Server missing for pid-file/daemonization test', 10) if $@; - - # wait for daemonization - $spawn_httpd->("-l$unix", '-D', '-P', "$tmpdir/pid"); - my $kpid = $pid; - $pid = undef; - is(waitpid($kpid, 0), $kpid, 'existing httpd terminated'); - check_sock($unix); + require_mods('Net::Server::Daemonize', 20); + my $pid_file = "$tmpdir/pid"; + for my $w (qw(-W0 -W1)) { + # wait for daemonization + $spawn_httpd->("-l$unix", '-D', '-P', $pid_file, $w); + $td->join; + is($?, 0, "daemonized $w process"); + check_sock($unix); - ok(-f "$tmpdir/pid", 'pid file written'); - open my $fh, '<', "$tmpdir/pid" or die "open failed: $!"; - local $/ = "\n"; - my $rpid = <$fh>; - chomp $rpid; - like($rpid, qr/\A\d+\z/s, 'pid file looks like a pid'); - is(kill('TERM', $rpid), 1, 'signalled daemonized process'); - for (1..100) { - kill(0, $rpid) or last; - select undef, undef, undef, 0.02; + ok(-f $pid_file, "$w pid file written"); + open my $fh, '<', "$tmpdir/pid" or die "open failed: $!"; + my $rpid = do { local $/; <$fh> }; + chomp $rpid; + like($rpid, qr/\A\d+\z/s, "$w pid file looks like a pid"); + is(kill('TERM', $rpid), 1, "signaled daemonized $w process"); + for (1..100) { + kill(0, $rpid) or last; + select undef, undef, undef, 0.02; + } + is(kill(0, $rpid), 0, "daemonized $w process exited"); + ok(!-e $pid_file, "$w pid file unlinked at exit"); } - is(kill(0, $rpid), 0, 'daemonized process exited') } done_testing();