diff options
Diffstat (limited to 'src/test/isolation/specs/async-notify.spec')
-rw-r--r-- | src/test/isolation/specs/async-notify.spec | 76 |
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" |