# Connects with a nonexistent role, waits DELAY ms before reading, and
# checks whether the server's FATAL ErrorResponse survives.
use strict; use warnings; use IO::Socket::INET; use Time::HiRes qw(usleep);
my ($port, $iters, $delay_ms) = @ARGV;
my ($ok, $lost) = (0, 0); my %errs;
for (1..$iters) {
    my $s = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $port, Proto => 'tcp') or die "connect: $!";
    my $body = pack('N', 196608) . "user\0nosuchrole\0database\0postgres\0\0";
    print $s pack('N', length($body) + 4) . $body; $s->flush;
    usleep($delay_ms * 1000);
    my $buf = ''; my $r;
    while (($r = sysread($s, my $chunk, 8192))) { $buf .= $chunk }
    if ($buf =~ /does not exist/) { $ok++ } else { $lost++; $errs{defined $r ? "EOF, got ".length($buf)." bytes" : "$!"}++ }
    close $s;
}
print "delay=${delay_ms}ms: FATAL received $ok/$iters, lost $lost\n";
print "  lost reason: $_ x$errs{$_}\n" for sort keys %errs;
