diff options
Diffstat (limited to 't/cmd_ipc.t')
-rw-r--r-- | t/cmd_ipc.t | 65 |
1 files changed, 32 insertions, 33 deletions
diff --git a/t/cmd_ipc.t b/t/cmd_ipc.t index 75697a15..c973c6f0 100644 --- a/t/cmd_ipc.t +++ b/t/cmd_ipc.t @@ -1,23 +1,20 @@ #!perl -w # Copyright (C) all contributors <meta@public-inbox.org> # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> -use strict; -use v5.10.1; -use Test::More; +use v5.12; use PublicInbox::TestCommon; -use Socket qw(AF_UNIX SOCK_STREAM MSG_EOR); -pipe(my ($r, $w)) or BAIL_OUT; +use autodie; +use Socket qw(AF_UNIX SOCK_STREAM SOCK_SEQPACKET); +pipe(my $r, my $w); my ($send, $recv); require_ok 'PublicInbox::Spawn'; -my $SOCK_SEQPACKET = eval { Socket::SOCK_SEQPACKET() } // undef; -use Time::HiRes qw(usleep); +require POSIX; my $do_test = sub { SKIP: { my ($type, $flag, $desc) = @_; - defined $type or skip 'SOCK_SEQPACKET missing', 7; my ($s1, $s2); my $src = 'some payload' x 40; - socketpair($s1, $s2, AF_UNIX, $type, 0) or BAIL_OUT $!; + socketpair($s1, $s2, AF_UNIX, $type, 0); my $sfds = [ fileno($r), fileno($w), fileno($s1) ]; $send->($s1, $sfds, $src, $flag); my (@fds) = $recv->($s2, my $buf, length($src) + 1); @@ -38,7 +35,7 @@ my $do_test = sub { SKIP: { @exp = stat $s1; @cur = stat $s1a; is("$exp[0]\0$exp[1]", "$cur[0]\0$cur[1]", '$s1 dev/ino matches'); - if (defined($SOCK_SEQPACKET) && $type == $SOCK_SEQPACKET) { + if ($type == SOCK_SEQPACKET) { $r1 = $w1 = $s1a = undef; $src = (',' x 1023) . '-' .('.' x 1024); $send->($s1, $sfds, $src, $flag); @@ -50,47 +47,50 @@ my $do_test = sub { SKIP: { $s2->blocking(0); @fds = $recv->($s2, $buf, length($src) + 1); ok($!{EAGAIN}, "EAGAIN set by ($desc)"); + is($buf, '', "recv buffer emptied on EAGAIN ($desc)"); is_deeply(\@fds, [ undef ], "EAGAIN $desc"); $s2->blocking(1); - if ($ENV{TEST_ALRM}) { + if ('test ALRM') { my $alrm = 0; local $SIG{ALRM} = sub { $alrm++ }; my $tgt = $$; - my $pid = fork // xbail "fork: $!"; + my $pid = fork; if ($pid == 0) { # need to loop since Perl signals are racy # (the interpreter doesn't self-pipe) - while (usleep(1000)) { - kill 'ALRM', $tgt; + my $n = 3; + while (tick(0.01 * $n) && --$n) { + kill('ALRM', $tgt) } + close $s1; + POSIX::_exit(1); } + close $s1; @fds = $recv->($s2, $buf, length($src) + 1); - ok($!{EINTR}, "EINTR set by ($desc)"); - kill('KILL', $pid); waitpid($pid, 0); - is_deeply(\@fds, [ undef ], "EINTR $desc"); + is_deeply(\@fds, [], "EINTR->EOF $desc"); ok($alrm, 'SIGALRM hit'); } - close $s1; @fds = $recv->($s2, $buf, length($src) + 1); is_deeply(\@fds, [], "no FDs on EOF $desc"); is($buf, '', "buffer cleared on EOF ($desc)"); - socketpair($s1, $s2, AF_UNIX, $type, 0) or BAIL_OUT $!; + socketpair($s1, $s2, AF_UNIX, $type, 0); $s1->blocking(0); my $nsent = 0; + my $srclen = length($src); while (defined(my $n = $send->($s1, $sfds, $src, $flag))) { $nsent += $n; - fail "sent 0 bytes" if $n == 0; + fail "sent $n bytes of $srclen" if $srclen != $n; } - ok($!{EAGAIN} || $!{ETOOMANYREFS}, - "hit EAGAIN || ETOOMANYREFS on send $desc") or - diag "send failed with: $!"; + ok($!{EAGAIN} || $!{ETOOMANYREFS} || $!{EMSGSIZE}, + "hit EAGAIN || ETOOMANYREFS || EMSGSIZE on send $desc") + or diag "send failed with: $! (nsent=$nsent)"; ok($nsent > 0, 'sent some bytes'); - socketpair($s1, $s2, AF_UNIX, $type, 0) or BAIL_OUT $!; + socketpair($s1, $s2, AF_UNIX, $type, 0); is($send->($s1, [], $src, $flag), length($src), 'sent w/o FDs'); $buf = 'nope'; @fds = $recv->($s2, $buf, length($src)); @@ -99,7 +99,7 @@ my $do_test = sub { SKIP: { my $nr = 2 * 1024 * 1024; while (1) { - vec(my $vec = '', $nr * 8 - 1, 1) = 1; + vec(my $vec = '', $nr - 1, 8) = 1; my $n = $send->($s1, [], $vec, $flag); if (defined($n)) { $n == length($vec) or @@ -123,7 +123,7 @@ SKIP: { $send = $send_ic; $recv = $recv_ic; $do_test->(SOCK_STREAM, 0, 'Inline::C stream'); - $do_test->($SOCK_SEQPACKET, MSG_EOR, 'Inline::C seqpacket'); + $do_test->(SOCK_SEQPACKET, 0, 'Inline::C seqpacket'); } SKIP: { @@ -132,25 +132,24 @@ SKIP: { $send = PublicInbox::CmdIPC4->can('send_cmd4'); $recv = PublicInbox::CmdIPC4->can('recv_cmd4'); $do_test->(SOCK_STREAM, 0, 'MsgHdr stream'); - $do_test->($SOCK_SEQPACKET, MSG_EOR, 'MsgHdr seqpacket'); + $do_test->(SOCK_SEQPACKET, 0, 'MsgHdr seqpacket'); SKIP: { ($send_ic && $recv_ic) or skip 'Inline::C not installed/enabled', 12; $recv = $recv_ic; $do_test->(SOCK_STREAM, 0, 'Inline::C -> MsgHdr stream'); - $do_test->($SOCK_SEQPACKET, 0, 'Inline::C -> MsgHdr seqpacket'); + $do_test->(SOCK_SEQPACKET, 0, 'Inline::C -> MsgHdr seqpacket'); } } SKIP: { - skip 'not Linux', 1 if $^O ne 'linux'; require_ok 'PublicInbox::Syscall'; $send = PublicInbox::Syscall->can('send_cmd4') or - skip 'send_cmd4 not defined for arch'; + skip "send_cmd4 not defined for $^O arch", 1; $recv = PublicInbox::Syscall->can('recv_cmd4') or - skip 'recv_cmd4 not defined for arch'; - $do_test->(SOCK_STREAM, 0, 'PP Linux stream'); - $do_test->($SOCK_SEQPACKET, MSG_EOR, 'PP Linux seqpacket'); + skip "recv_cmd4 not defined for $^O arch", 1; + $do_test->(SOCK_STREAM, 0, 'pure Perl stream'); + $do_test->(SOCK_SEQPACKET, 0, 'pure Perl seqpacket'); } done_testing; |