about summary refs log tree commit homepage
path: root/t/cmd_ipc.t
diff options
context:
space:
mode:
Diffstat (limited to 't/cmd_ipc.t')
-rw-r--r--t/cmd_ipc.t65
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;