hydra/t/PostgresListener.t
Graham Christensen 5027003285 Abstract over postgres' LISTEN/NOTIFY
This lets us test the event loop if we wanted, and lets us
test the listening behavior in isolation.
2021-08-12 13:54:05 -04:00

79 lines
2.1 KiB
Perl

use strict;
use Setup;
my %ctx = test_init();
require Hydra::Model::DB;
use Hydra::PostgresListener;
use Test2::V0;
my $db = Hydra::Model::DB->new;
my $dbh = $db->storage->dbh;
my $listener = Hydra::PostgresListener->new($dbh);
$listener->subscribe("foo");
$listener->subscribe("bar");
is(undef, $listener->block_for_messages(0)->(), "There is no message");
is(undef, $listener->block_for_messages(0)->(), "There is no message");
is(undef, $listener->block_for_messages(0)->(), "There is no message");
$dbh->do("notify foo, ?", undef, "hi");
my $event = $listener->block_for_messages(0)->();
is($event->{'channel'}, "foo", "The channel matches");
isnt($event->{'pid'}, undef, "The pid is set");
is($event->{'payload'}, "hi", "The payload matches");
is(undef, $listener->block_for_messages(0)->(), "There is no message");
like(
dies {
local $SIG{ALRM} = sub { die "timeout" };
alarm 1;
$listener->block_for_messages->();
alarm 0;
},
qr/timeout/,
"An unspecified block should block forever"
);
like(
dies {
local $SIG{ALRM} = sub { die "timeout" };
alarm 1;
$listener->block_for_messages(2)->();
alarm 0;
},
qr/timeout/,
"A 2-second block goes longer than 1 second"
);
ok(
lives {
local $SIG{ALRM} = sub { die "timeout" };
alarm 2;
is(undef, $listener->block_for_messages(1)->(), "A one second block returns undef data after timeout");
alarm 0;
},
"A 1-second block expires within 2 seconds"
);
subtest "with wacky channel names" => sub {
my $channel = "foo! very weird channel names...; select * from t where 1 = 1";
my $escapedChannel = $dbh->quote_identifier($channel);
$listener->subscribe($channel);
is(undef, $listener->block_for_messages(0)->(), "There is no message");
$dbh->do("notify $escapedChannel, ?", undef, "hi");
my $event = $listener->block_for_messages(0)->();
is($event->{'channel'}, $channel, "The channel matches");
isnt($event->{'pid'}, undef, "The pid is set");
is($event->{'payload'}, "hi", "The payload matches");
};
done_testing;