85 lines
3.2 KiB
Ruby
85 lines
3.2 KiB
Ruby
# Tests for LISTEN/NOTIFY
|
|
|
|
# Most of these tests use only the "notifier" session and hence exercise only
|
|
# self-notifies, which are convenient because they minimize timing concerns.
|
|
# Note we assume that each step is delivered to the backend as a single Query
|
|
# message so it will run as one transaction.
|
|
|
|
session notifier
|
|
step listenc { LISTEN c1; LISTEN c2; }
|
|
step notify1 { NOTIFY c1; }
|
|
step notify2 { NOTIFY c2, 'payload'; }
|
|
step notify3 { NOTIFY c3, 'payload3'; } # not listening to c3
|
|
step notifyf { SELECT pg_notify('c2', NULL); }
|
|
step notifyd1 { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; }
|
|
step notifyd2 { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; }
|
|
step notifys1 {
|
|
BEGIN;
|
|
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
|
|
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
|
|
SAVEPOINT s1;
|
|
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
|
|
NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads';
|
|
NOTIFY c1, 'payload'; NOTIFY "c2", 'payload';
|
|
NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads';
|
|
RELEASE SAVEPOINT s1;
|
|
SAVEPOINT s2;
|
|
NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload';
|
|
NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads';
|
|
NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload';
|
|
NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads';
|
|
ROLLBACK TO SAVEPOINT s2;
|
|
COMMIT;
|
|
}
|
|
step usage { SELECT pg_notification_queue_usage() > 0 AS nonzero; }
|
|
step bignotify { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; }
|
|
teardown { UNLISTEN *; }
|
|
|
|
# The listener session is used for cross-backend notify checks.
|
|
|
|
session listener
|
|
step llisten { LISTEN c1; LISTEN c2; }
|
|
step lcheck { SELECT 1 AS x; }
|
|
step lbegin { BEGIN; }
|
|
step lbegins { BEGIN ISOLATION LEVEL SERIALIZABLE; }
|
|
step lcommit { COMMIT; }
|
|
teardown { UNLISTEN *; }
|
|
|
|
# In some tests we need a second listener, just to block the queue.
|
|
|
|
session listener2
|
|
step l2listen { LISTEN c1; }
|
|
step l2begin { BEGIN; }
|
|
step l2commit { COMMIT; }
|
|
step l2stop { UNLISTEN *; }
|
|
|
|
|
|
# Trivial cases.
|
|
permutation listenc notify1 notify2 notify3 notifyf
|
|
|
|
# Check simple and less-simple deduplication.
|
|
permutation listenc notifyd1 notifyd2 notifys1
|
|
|
|
# Cross-backend notification delivery. We use a "select 1" to force the
|
|
# listener session to check for notifies. In principle we could just wait
|
|
# for delivery, but that would require extra support in isolationtester
|
|
# and might have portability-of-timing issues.
|
|
permutation llisten notify1 notify2 notify3 notifyf lcheck
|
|
|
|
# Again, with local delivery too.
|
|
permutation listenc llisten notify1 notify2 notify3 notifyf lcheck
|
|
|
|
# Check for bug when initial listen is only action in a serializable xact,
|
|
# and notify queue is not empty
|
|
permutation l2listen l2begin notify1 lbegins llisten lcommit l2commit l2stop
|
|
|
|
# Verify that pg_notification_queue_usage correctly reports a non-zero result,
|
|
# after submitting notifications while another connection is listening for
|
|
# those notifications and waiting inside an active transaction. We have to
|
|
# fill a page of the notify SLRU to make this happen, which is a good deal
|
|
# of traffic. To not bloat the expected output, we intentionally don't
|
|
# commit the listener's transaction, so that it never reports these events.
|
|
# Hence, this should be the last test in this script.
|
|
|
|
permutation llisten lbegin usage bignotify usage
|