From f67ab295d088f8cb1a3407d1b8c187a7187c7e95 Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sun, 12 May 2019 10:34:10 +0200 Subject: Add LISTEN/NOTIFY support This really is just a matter of reading out notifications when they're available. Also, we offer a way to explicitly wait for notifications. --- tests/run.scm | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'tests/run.scm') diff --git a/tests/run.scm b/tests/run.scm index 0469929..80cf799 100644 --- a/tests/run.scm +++ b/tests/run.scm @@ -4,7 +4,8 @@ test postgresql sql-null - srfi-4) + srfi-4 + srfi-18) (define-syntax test-error* (syntax-rules () @@ -942,7 +943,80 @@ (query conn "SELECT * FROM chicken_pgsql_test"))) isolation: 'serializable)) (disconnect conn2))) - ) +) + + +;; This testing code is pretty hairy +(test-group "LISTEN/NOTIFY" + (let ((received-channel #f) + (received-pid #f) + (received-message #f) + (pid1 (value-at (query conn "SELECT pg_backend_pid()")))) + + (define (reset-received-values!) + (set! received-channel #f) + (set! received-pid #f) + (set! received-message #f)) + + (query conn "LISTEN \"testing channel\"") + (query conn "LISTEN \"unused channel\"") + + (set-notify-handler! conn (lambda (channel pid message) + (set! received-channel channel) + (set! received-pid pid) + (set! received-message message))) + + (query conn "NOTIFY \"testing channel\", 'this is a test'") + + (test "Notification handler is immediately invoked for own connection" + `("testing channel" ,pid1 "this is a test") + (list received-channel pid1 received-message)) + + (reset-received-values!) + + (let* ((conn2 (connect '((dbname . test)))) + (pid2 (value-at (query conn2 "SELECT pg_backend_pid()")))) + (query conn2 "NOTIFY \"testing channel\", 'another test'") + + (test "Notification handler for connection 1 is not invoked when notifying from connection 2" + `(#f #f #f) + (list received-channel received-pid received-message)) + + (query conn "SELECT 1") + (test "Notification handler is invoked after performing next query" + `("testing channel" ,pid2 "another test") + (list received-channel received-pid received-message)) + + (reset-received-values!) + + ;; This sucks, we have to do this from another thread + (thread-start! + (lambda () + (thread-sleep! 0.1) + (query conn2 "NOTIFY \"testing channel\", 'hi'"))) + + (test "Waiting manually for a short while does nothing yet" + `(#f #f #f) + (begin (wait-for-notifications! conn 1) + (list received-channel received-pid received-message))) + + (test "Waiting long enough returns the notification" + `("testing channel" ,pid2 "hi") + (begin (wait-for-notifications! conn 5000) + (list received-channel received-pid received-message))) + + (reset-received-values!) + + ;; And once more + (thread-start! + (lambda () + (thread-sleep! 0.01) + (query conn2 "NOTIFY \"testing channel\", 'also hi'"))) + + (test "Waiting without timeout returns the notification" + `("testing channel" ,pid2 "also hi") + (begin (wait-for-notifications! conn #f) + (list received-channel received-pid received-message)))))) (test-end) -- cgit v1.2.3