Fugu
view release on metacpan or search on metacpan
t/conformance/mdns-imsg.t view on Meta::CPAN
#!/usr/bin/env perl
# ex:ts=8 sw=4:
# Conformance tests for spec/protocol/MDNS-Imsg.md
#
# The framing is Protocol::Imsg, so most sections drive the codec over
# bytes. Two predicates are not framing at all: an invalid len drops
# the connection, and EOF mid-message is an error. A codec with append
# and next_message has no concept of a connection or an EOF, so both
# keep their socketpair against Fugu::Imsg.
use v5.36;
use Test::More;
use FindBin qw($RealBin);
use lib "$RealBin/../../lib";
use Socket qw(AF_UNIX SOCK_STREAM PF_UNSPEC);
use_ok('Protocol::Imsg');
use_ok('Fugu::Imsg');
# pair(): a Fugu::Imsg endpoint and the raw peer handle. Thus a test
# can inject wire bytes that the transport would never produce.
sub pair ()
{
socketpair( my $a, my $b, AF_UNIX, SOCK_STREAM, PF_UNSPEC )
or die "socketpair: $!";
binmode $_ for $a, $b;
return ( Fugu::Imsg->new( fh => $a ), $b );
}
subtest '[MDNS-Imsg §1] header is four uint32 fields in order' => sub {
my $hdr = Protocol::Imsg::_encode_header( 0x11223344, 0x55667788,
0x99aabbcc, 0xddeeff00 );
is( length($hdr), 16, 'IMSG_HEADER_SIZE is 16' );
# Field layout, not byte order: each field is in its own 4-byte
# slot at the measured offset. The host byte order does not
# matter.
is( unpack( 'L', substr( $hdr, 0, 4 ) ),
0x11223344, 'type at offset 0' );
is( unpack( 'L', substr( $hdr, 4, 4 ) ),
0x55667788, 'len at offset 4' );
is( unpack( 'L', substr( $hdr, 8, 4 ) ),
0x99aabbcc, 'peerid at offset 8' );
is( unpack( 'L', substr( $hdr, 12, 4 ) ),
0xddeeff00, 'pid at offset 12' );
};
subtest '[MDNS-Imsg §2] len counts header plus payload' => sub {
my $wire =
Protocol::Imsg->new->encode( type => 8, data => 'x' x 240 );
is( length($wire), 256, 'whole message is header + payload' );
my ( $type, $len ) = unpack 'L2', $wire;
is( $len, 256, 'len field includes the 16-byte header' );
};
subtest '[MDNS-Imsg §2] payload bound is MAX_IMSGSIZE minus header' =>
sub {
my $codec = Protocol::Imsg->new;
ok( !defined $codec->encode( type => 1, data => 'x' x 16369 ),
'payload above 16368 bytes is refused, not truncated' );
ok( defined $codec->encode( type => 1, data => 'x' x 16368 ),
'payload of exactly 16368 bytes is accepted' );
};
subtest '[MDNS-Imsg §2] receiver masks the fd mark off len' => sub {
my $codec = Protocol::Imsg->new;
# A message whose len carries IMSG_FD_MARK still frames
# correctly after the receiver masks off the mark
$codec->append(
pack( 'L4', 7, ( 16 + 4 ) | 0x80000000, 0, 1 ) . 'data' );
my $msg = $codec->next_message;
ok( defined $msg, 'marked message received' );
is( $msg->{data}, 'data', 'payload length taken from masked len' );
};
# A dropped connection is a transport predicate: the codec records a
( run in 4.043 seconds using v1.01-cache-2.11-cpan-9789f410c06 )