X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=t%2Fcmd_ipc.t;h=75697a1539e3e8b2b80bb4d1cfa80d685e7d57d5;hb=4eee5af6011cc8cdefb66c9729952c7eff5c0b0b;hp=22f73c1952b3c47288a744efea70402ad626f405;hpb=6cc0e6870cb4950c08646769f2a7e30729b7d409;p=public-inbox.git diff --git a/t/cmd_ipc.t b/t/cmd_ipc.t index 22f73c19..75697a15 100644 --- a/t/cmd_ipc.t +++ b/t/cmd_ipc.t @@ -1,5 +1,5 @@ #!perl -w -# Copyright (C) 2021 all contributors +# Copyright (C) all contributors # License: AGPL-3.0+ use strict; use v5.10.1; @@ -10,6 +10,7 @@ pipe(my ($r, $w)) or BAIL_OUT; my ($send, $recv); require_ok 'PublicInbox::Spawn'; my $SOCK_SEQPACKET = eval { Socket::SOCK_SEQPACKET() } // undef; +use Time::HiRes qw(usleep); my $do_test = sub { SKIP: { my ($type, $flag, $desc) = @_; @@ -45,11 +46,73 @@ my $do_test = sub { SKIP: { is($buf, (',' x 1023) . '-', 'silently truncated buf'); $opens->(); $r1 = $w1 = $s1a = undef; + + $s2->blocking(0); + @fds = $recv->($s2, $buf, length($src) + 1); + ok($!{EAGAIN}, "EAGAIN set by ($desc)"); + is_deeply(\@fds, [ undef ], "EAGAIN $desc"); + $s2->blocking(1); + + if ($ENV{TEST_ALRM}) { + my $alrm = 0; + local $SIG{ALRM} = sub { $alrm++ }; + my $tgt = $$; + my $pid = fork // xbail "fork: $!"; + if ($pid == 0) { + # need to loop since Perl signals are racy + # (the interpreter doesn't self-pipe) + while (usleep(1000)) { + kill 'ALRM', $tgt; + } + } + @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"); + 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 $!; + $s1->blocking(0); + my $nsent = 0; + while (defined(my $n = $send->($s1, $sfds, $src, $flag))) { + $nsent += $n; + fail "sent 0 bytes" if $n == 0; + } + ok($!{EAGAIN} || $!{ETOOMANYREFS}, + "hit EAGAIN || ETOOMANYREFS on send $desc") or + diag "send failed with: $!"; + ok($nsent > 0, 'sent some bytes'); + + socketpair($s1, $s2, AF_UNIX, $type, 0) or BAIL_OUT $!; + is($send->($s1, [], $src, $flag), length($src), 'sent w/o FDs'); + $buf = 'nope'; + @fds = $recv->($s2, $buf, length($src)); + is(scalar(@fds), 0, 'no FDs received'); + is($buf, $src, 'recv w/o FDs'); + + my $nr = 2 * 1024 * 1024; + while (1) { + vec(my $vec = '', $nr * 8 - 1, 1) = 1; + my $n = $send->($s1, [], $vec, $flag); + if (defined($n)) { + $n == length($vec) or + fail "short send: $n != ".length($vec); + diag "sent $nr, retrying with more"; + $nr += 2 * 1024 * 1024; + } else { + ok($!{EMSGSIZE} || $!{ENOBUFS}, + 'got EMSGSIZE or ENOBUFS') or + diag "$nr bytes fails with: $!"; + last; + } + } } } }; @@ -80,12 +143,14 @@ SKIP: { } SKIP: { - require_mods('IO::FDPass', 13); - require_ok 'PublicInbox::CmdIPC1'; - $send = PublicInbox::CmdIPC1->can('send_cmd1'); - $recv = PublicInbox::CmdIPC1->can('recv_cmd1'); - $do_test->(SOCK_STREAM, 0, 'IO::FDPass stream'); - $do_test->($SOCK_SEQPACKET, MSG_EOR, 'IO::FDPass seqpacket'); + 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'; + $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'); } done_testing;