aboutsummaryrefslogtreecommitdiff
path: root/src/test/isolation/specs/async-notify.spec
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/isolation/specs/async-notify.spec')
-rw-r--r--src/test/isolation/specs/async-notify.spec76
1 files changed, 66 insertions, 10 deletions
diff --git a/src/test/isolation/specs/async-notify.spec b/src/test/isolation/specs/async-notify.spec
index 8adad42c7c8..daf7bef903c 100644
--- a/src/test/isolation/specs/async-notify.spec
+++ b/src/test/isolation/specs/async-notify.spec
@@ -1,14 +1,70 @@
-# 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.
+# Tests for LISTEN/NOTIFY
-session "listener"
-step "listen" { LISTEN a; }
-step "begin" { BEGIN; }
-teardown { ROLLBACK; UNLISTEN *; }
+# 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 "check" { SELECT pg_notification_queue_usage() > 0 AS nonzero; }
-step "notify" { SELECT count(pg_notify('a', s::text)) FROM generate_series(1, 1000) s; }
+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; }
+teardown { 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"
+
+# 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 "listen" "begin" "check" "notify" "check"
+permutation "llisten" "lbegin" "usage" "bignotify" "usage"