start_server {tags {"pubsub network"}} { if {$::singledb} { set db 0 } else { set db 9 } test "Pub/Sub PING" { set rd1 [redis_deferring_client] subscribe $rd1 somechannel # While subscribed to non-zero channels PING works in Pub/Sub mode. $rd1 ping $rd1 ping "foo" set reply1 [$rd1 read] set reply2 [$rd1 read] unsubscribe $rd1 somechannel # Now we are unsubscribed, PING should just return PONG. $rd1 ping set reply3 [$rd1 read] $rd1 close list $reply1 $reply2 $reply3 } {{pong {}} {pong foo} PONG} test "PUBLISH/SUBSCRIBE basics" { set rd1 [redis_deferring_client] # subscribe to two channels assert_equal {1 2} [subscribe $rd1 {chan1 chan2}] assert_equal 1 [r publish chan1 hello] assert_equal 1 [r publish chan2 world] assert_equal {message chan1 hello} [$rd1 read] assert_equal {message chan2 world} [$rd1 read] # unsubscribe from one of the channels unsubscribe $rd1 {chan1} assert_equal 0 [r publish chan1 hello] assert_equal 1 [r publish chan2 world] assert_equal {message chan2 world} [$rd1 read] # unsubscribe from the remaining channel unsubscribe $rd1 {chan2} assert_equal 0 [r publish chan1 hello] assert_equal 0 [r publish chan2 world] # clean up clients $rd1 close } test "PUBLISH/SUBSCRIBE with two clients" { set rd1 [redis_deferring_client] set rd2 [redis_deferring_client] assert_equal {1} [subscribe $rd1 {chan1}] assert_equal {1} [subscribe $rd2 {chan1}] assert_equal 2 [r publish chan1 hello] assert_equal {message chan1 hello} [$rd1 read] assert_equal {message chan1 hello} [$rd2 read] # clean up clients $rd1 close $rd2 close } test "PUBLISH/SUBSCRIBE after UNSUBSCRIBE without arguments" { set rd1 [redis_deferring_client] assert_equal {1 2 3} [subscribe $rd1 {chan1 chan2 chan3}] unsubscribe $rd1 after 10 assert_equal 0 [r publish chan1 hello] assert_equal 0 [r publish chan2 hello] assert_equal 0 [r publish chan3 hello] # clean up clients $rd1 close } test "SUBSCRIBE to one channel more than once" { set rd1 [redis_deferring_client] assert_equal {1 1 1} [subscribe $rd1 {chan1 chan1 chan1}] assert_equal 1 [r publish chan1 hello] assert_equal {message chan1 hello} [$rd1 read] # clean up clients $rd1 close } test "UNSUBSCRIBE from non-subscribed channels" { set rd1 [redis_deferring_client] assert_equal {0 0 0} [unsubscribe $rd1 {foo bar quux}] # clean up clients $rd1 close } test "PUBLISH/PSUBSCRIBE basics" { set rd1 [redis_deferring_client] # subscribe to two patterns assert_equal {1 2} [psubscribe $rd1 {foo.* bar.*}] assert_equal 1 [r publish foo.1 hello] assert_equal 1 [r publish bar.1 hello] assert_equal 0 [r publish foo1 hello] assert_equal 0 [r publish barfoo.1 hello] assert_equal 0 [r publish qux.1 hello] assert_equal {pmessage foo.* foo.1 hello} [$rd1 read] assert_equal {pmessage bar.* bar.1 hello} [$rd1 read] # unsubscribe from one of the patterns assert_equal {1} [punsubscribe $rd1 {foo.*}] assert_equal 0 [r publish foo.1 hello] assert_equal 1 [r publish bar.1 hello] assert_equal {pmessage bar.* bar.1 hello} [$rd1 read] # unsubscribe from the remaining pattern assert_equal {0} [punsubscribe $rd1 {bar.*}] assert_equal 0 [r publish foo.1 hello] assert_equal 0 [r publish bar.1 hello] # clean up clients $rd1 close } test "PUBLISH/PSUBSCRIBE with two clients" { set rd1 [redis_deferring_client] set rd2 [redis_deferring_client] assert_equal {1} [psubscribe $rd1 {chan.*}] assert_equal {1} [psubscribe $rd2 {chan.*}] assert_equal 2 [r publish chan.foo hello] assert_equal {pmessage chan.* chan.foo hello} [$rd1 read] assert_equal {pmessage chan.* chan.foo hello} [$rd2 read] # clean up clients $rd1 close $rd2 close } test "PUBLISH/PSUBSCRIBE after PUNSUBSCRIBE without arguments" { set rd1 [redis_deferring_client] assert_equal {1 2 3} [psubscribe $rd1 {chan1.* chan2.* chan3.*}] punsubscribe $rd1 assert_equal 0 [r publish chan1.hi hello] assert_equal 0 [r publish chan2.hi hello] assert_equal 0 [r publish chan3.hi hello] # clean up clients $rd1 close } test "PUNSUBSCRIBE from non-subscribed channels" { set rd1 [redis_deferring_client] assert_equal {0 0 0} [punsubscribe $rd1 {foo.* bar.* quux.*}] # clean up clients $rd1 close } test "NUMSUB returns numbers, not strings (#1561)" { r pubsub numsub abc def } {abc 0 def 0} test "NUMPATs returns the number of unique patterns" { set rd1 [redis_deferring_client] set rd2 [redis_deferring_client] # Three unique patterns and one that overlaps psubscribe $rd1 "foo*" psubscribe $rd2 "foo*" psubscribe $rd1 "bar*" psubscribe $rd2 "baz*" set patterns [r pubsub numpat] # clean up clients punsubscribe $rd1 punsubscribe $rd2 assert_equal 3 $patterns } test "Mix SUBSCRIBE and PSUBSCRIBE" { set rd1 [redis_deferring_client] assert_equal {1} [subscribe $rd1 {foo.bar}] assert_equal {2} [psubscribe $rd1 {foo.*}] assert_equal 2 [r publish foo.bar hello] assert_equal {message foo.bar hello} [$rd1 read] assert_equal {pmessage foo.* foo.bar hello} [$rd1 read] # clean up clients $rd1 close } test "PUNSUBSCRIBE and UNSUBSCRIBE should always reply" { # Make sure we are not subscribed to any channel at all. r punsubscribe r unsubscribe # Now check if the commands still reply correctly. set reply1 [r punsubscribe] set reply2 [r unsubscribe] concat $reply1 $reply2 } {punsubscribe {} 0 unsubscribe {} 0} }