1start_server {tags {"pubsub network"}} { 2 if {$::singledb} { 3 set db 0 4 } else { 5 set db 9 6 } 7 8 test "Pub/Sub PING" { 9 set rd1 [redis_deferring_client] 10 subscribe $rd1 somechannel 11 # While subscribed to non-zero channels PING works in Pub/Sub mode. 12 $rd1 ping 13 $rd1 ping "foo" 14 set reply1 [$rd1 read] 15 set reply2 [$rd1 read] 16 unsubscribe $rd1 somechannel 17 # Now we are unsubscribed, PING should just return PONG. 18 $rd1 ping 19 set reply3 [$rd1 read] 20 $rd1 close 21 list $reply1 $reply2 $reply3 22 } {{pong {}} {pong foo} PONG} 23 24 test "PUBLISH/SUBSCRIBE basics" { 25 set rd1 [redis_deferring_client] 26 27 # subscribe to two channels 28 assert_equal {1 2} [subscribe $rd1 {chan1 chan2}] 29 assert_equal 1 [r publish chan1 hello] 30 assert_equal 1 [r publish chan2 world] 31 assert_equal {message chan1 hello} [$rd1 read] 32 assert_equal {message chan2 world} [$rd1 read] 33 34 # unsubscribe from one of the channels 35 unsubscribe $rd1 {chan1} 36 assert_equal 0 [r publish chan1 hello] 37 assert_equal 1 [r publish chan2 world] 38 assert_equal {message chan2 world} [$rd1 read] 39 40 # unsubscribe from the remaining channel 41 unsubscribe $rd1 {chan2} 42 assert_equal 0 [r publish chan1 hello] 43 assert_equal 0 [r publish chan2 world] 44 45 # clean up clients 46 $rd1 close 47 } 48 49 test "PUBLISH/SUBSCRIBE with two clients" { 50 set rd1 [redis_deferring_client] 51 set rd2 [redis_deferring_client] 52 53 assert_equal {1} [subscribe $rd1 {chan1}] 54 assert_equal {1} [subscribe $rd2 {chan1}] 55 assert_equal 2 [r publish chan1 hello] 56 assert_equal {message chan1 hello} [$rd1 read] 57 assert_equal {message chan1 hello} [$rd2 read] 58 59 # clean up clients 60 $rd1 close 61 $rd2 close 62 } 63 64 test "PUBLISH/SUBSCRIBE after UNSUBSCRIBE without arguments" { 65 set rd1 [redis_deferring_client] 66 assert_equal {1 2 3} [subscribe $rd1 {chan1 chan2 chan3}] 67 unsubscribe $rd1 68 assert_equal 0 [r publish chan1 hello] 69 assert_equal 0 [r publish chan2 hello] 70 assert_equal 0 [r publish chan3 hello] 71 72 # clean up clients 73 $rd1 close 74 } 75 76 test "SUBSCRIBE to one channel more than once" { 77 set rd1 [redis_deferring_client] 78 assert_equal {1 1 1} [subscribe $rd1 {chan1 chan1 chan1}] 79 assert_equal 1 [r publish chan1 hello] 80 assert_equal {message chan1 hello} [$rd1 read] 81 82 # clean up clients 83 $rd1 close 84 } 85 86 test "UNSUBSCRIBE from non-subscribed channels" { 87 set rd1 [redis_deferring_client] 88 assert_equal {0 0 0} [unsubscribe $rd1 {foo bar quux}] 89 90 # clean up clients 91 $rd1 close 92 } 93 94 test "PUBLISH/PSUBSCRIBE basics" { 95 set rd1 [redis_deferring_client] 96 97 # subscribe to two patterns 98 assert_equal {1 2} [psubscribe $rd1 {foo.* bar.*}] 99 assert_equal 1 [r publish foo.1 hello] 100 assert_equal 1 [r publish bar.1 hello] 101 assert_equal 0 [r publish foo1 hello] 102 assert_equal 0 [r publish barfoo.1 hello] 103 assert_equal 0 [r publish qux.1 hello] 104 assert_equal {pmessage foo.* foo.1 hello} [$rd1 read] 105 assert_equal {pmessage bar.* bar.1 hello} [$rd1 read] 106 107 # unsubscribe from one of the patterns 108 assert_equal {1} [punsubscribe $rd1 {foo.*}] 109 assert_equal 0 [r publish foo.1 hello] 110 assert_equal 1 [r publish bar.1 hello] 111 assert_equal {pmessage bar.* bar.1 hello} [$rd1 read] 112 113 # unsubscribe from the remaining pattern 114 assert_equal {0} [punsubscribe $rd1 {bar.*}] 115 assert_equal 0 [r publish foo.1 hello] 116 assert_equal 0 [r publish bar.1 hello] 117 118 # clean up clients 119 $rd1 close 120 } 121 122 test "PUBLISH/PSUBSCRIBE with two clients" { 123 set rd1 [redis_deferring_client] 124 set rd2 [redis_deferring_client] 125 126 assert_equal {1} [psubscribe $rd1 {chan.*}] 127 assert_equal {1} [psubscribe $rd2 {chan.*}] 128 assert_equal 2 [r publish chan.foo hello] 129 assert_equal {pmessage chan.* chan.foo hello} [$rd1 read] 130 assert_equal {pmessage chan.* chan.foo hello} [$rd2 read] 131 132 # clean up clients 133 $rd1 close 134 $rd2 close 135 } 136 137 test "PUBLISH/PSUBSCRIBE after PUNSUBSCRIBE without arguments" { 138 set rd1 [redis_deferring_client] 139 assert_equal {1 2 3} [psubscribe $rd1 {chan1.* chan2.* chan3.*}] 140 punsubscribe $rd1 141 assert_equal 0 [r publish chan1.hi hello] 142 assert_equal 0 [r publish chan2.hi hello] 143 assert_equal 0 [r publish chan3.hi hello] 144 145 # clean up clients 146 $rd1 close 147 } 148 149 test "PUNSUBSCRIBE from non-subscribed channels" { 150 set rd1 [redis_deferring_client] 151 assert_equal {0 0 0} [punsubscribe $rd1 {foo.* bar.* quux.*}] 152 153 # clean up clients 154 $rd1 close 155 } 156 157 test "NUMSUB returns numbers, not strings (#1561)" { 158 r pubsub numsub abc def 159 } {abc 0 def 0} 160 161 test "NUMPATs returns the number of unique patterns" { 162 set rd1 [redis_deferring_client] 163 set rd2 [redis_deferring_client] 164 165 # Three unique patterns and one that overlaps 166 psubscribe $rd1 "foo*" 167 psubscribe $rd2 "foo*" 168 psubscribe $rd1 "bar*" 169 psubscribe $rd2 "baz*" 170 171 set patterns [r pubsub numpat] 172 173 # clean up clients 174 punsubscribe $rd1 175 punsubscribe $rd2 176 assert_equal 3 $patterns 177 $rd1 close 178 $rd2 close 179 } 180 181 test "Mix SUBSCRIBE and PSUBSCRIBE" { 182 set rd1 [redis_deferring_client] 183 assert_equal {1} [subscribe $rd1 {foo.bar}] 184 assert_equal {2} [psubscribe $rd1 {foo.*}] 185 186 assert_equal 2 [r publish foo.bar hello] 187 assert_equal {message foo.bar hello} [$rd1 read] 188 assert_equal {pmessage foo.* foo.bar hello} [$rd1 read] 189 190 # clean up clients 191 $rd1 close 192 } 193 194 test "PUNSUBSCRIBE and UNSUBSCRIBE should always reply" { 195 # Make sure we are not subscribed to any channel at all. 196 r punsubscribe 197 r unsubscribe 198 # Now check if the commands still reply correctly. 199 set reply1 [r punsubscribe] 200 set reply2 [r unsubscribe] 201 concat $reply1 $reply2 202 } {punsubscribe {} 0 unsubscribe {} 0} 203 204 ### Keyspace events notification tests 205 206 test "Keyspace notifications: we receive keyspace notifications" { 207 r config set notify-keyspace-events KA 208 set rd1 [redis_deferring_client] 209 assert_equal {1} [psubscribe $rd1 *] 210 r set foo bar 211 assert_equal "pmessage * __keyspace@${db}__:foo set" [$rd1 read] 212 $rd1 close 213 } 214 215 test "Keyspace notifications: we receive keyevent notifications" { 216 r config set notify-keyspace-events EA 217 set rd1 [redis_deferring_client] 218 assert_equal {1} [psubscribe $rd1 *] 219 r set foo bar 220 assert_equal "pmessage * __keyevent@${db}__:set foo" [$rd1 read] 221 $rd1 close 222 } 223 224 test "Keyspace notifications: we can receive both kind of events" { 225 r config set notify-keyspace-events KEA 226 set rd1 [redis_deferring_client] 227 assert_equal {1} [psubscribe $rd1 *] 228 r set foo bar 229 assert_equal "pmessage * __keyspace@${db}__:foo set" [$rd1 read] 230 assert_equal "pmessage * __keyevent@${db}__:set foo" [$rd1 read] 231 $rd1 close 232 } 233 234 test "Keyspace notifications: we are able to mask events" { 235 r config set notify-keyspace-events KEl 236 r del mylist 237 set rd1 [redis_deferring_client] 238 assert_equal {1} [psubscribe $rd1 *] 239 r set foo bar 240 r lpush mylist a 241 # No notification for set, because only list commands are enabled. 242 assert_equal "pmessage * __keyspace@${db}__:mylist lpush" [$rd1 read] 243 assert_equal "pmessage * __keyevent@${db}__:lpush mylist" [$rd1 read] 244 $rd1 close 245 } 246 247 test "Keyspace notifications: general events test" { 248 r config set notify-keyspace-events KEg 249 set rd1 [redis_deferring_client] 250 assert_equal {1} [psubscribe $rd1 *] 251 r set foo bar 252 r expire foo 1 253 r del foo 254 assert_equal "pmessage * __keyspace@${db}__:foo expire" [$rd1 read] 255 assert_equal "pmessage * __keyevent@${db}__:expire foo" [$rd1 read] 256 assert_equal "pmessage * __keyspace@${db}__:foo del" [$rd1 read] 257 assert_equal "pmessage * __keyevent@${db}__:del foo" [$rd1 read] 258 $rd1 close 259 } 260 261 test "Keyspace notifications: list events test" { 262 r config set notify-keyspace-events KEl 263 r del mylist 264 set rd1 [redis_deferring_client] 265 assert_equal {1} [psubscribe $rd1 *] 266 r lpush mylist a 267 r rpush mylist a 268 r rpop mylist 269 assert_equal "pmessage * __keyspace@${db}__:mylist lpush" [$rd1 read] 270 assert_equal "pmessage * __keyevent@${db}__:lpush mylist" [$rd1 read] 271 assert_equal "pmessage * __keyspace@${db}__:mylist rpush" [$rd1 read] 272 assert_equal "pmessage * __keyevent@${db}__:rpush mylist" [$rd1 read] 273 assert_equal "pmessage * __keyspace@${db}__:mylist rpop" [$rd1 read] 274 assert_equal "pmessage * __keyevent@${db}__:rpop mylist" [$rd1 read] 275 $rd1 close 276 } 277 278 test "Keyspace notifications: set events test" { 279 r config set notify-keyspace-events Ks 280 r del myset 281 set rd1 [redis_deferring_client] 282 assert_equal {1} [psubscribe $rd1 *] 283 r sadd myset a b c d 284 r srem myset x 285 r sadd myset x y z 286 r srem myset x 287 assert_equal "pmessage * __keyspace@${db}__:myset sadd" [$rd1 read] 288 assert_equal "pmessage * __keyspace@${db}__:myset sadd" [$rd1 read] 289 assert_equal "pmessage * __keyspace@${db}__:myset srem" [$rd1 read] 290 $rd1 close 291 } 292 293 test "Keyspace notifications: zset events test" { 294 r config set notify-keyspace-events Kz 295 r del myzset 296 set rd1 [redis_deferring_client] 297 assert_equal {1} [psubscribe $rd1 *] 298 r zadd myzset 1 a 2 b 299 r zrem myzset x 300 r zadd myzset 3 x 4 y 5 z 301 r zrem myzset x 302 assert_equal "pmessage * __keyspace@${db}__:myzset zadd" [$rd1 read] 303 assert_equal "pmessage * __keyspace@${db}__:myzset zadd" [$rd1 read] 304 assert_equal "pmessage * __keyspace@${db}__:myzset zrem" [$rd1 read] 305 $rd1 close 306 } 307 308 test "Keyspace notifications: hash events test" { 309 r config set notify-keyspace-events Kh 310 r del myhash 311 set rd1 [redis_deferring_client] 312 assert_equal {1} [psubscribe $rd1 *] 313 r hmset myhash yes 1 no 0 314 r hincrby myhash yes 10 315 assert_equal "pmessage * __keyspace@${db}__:myhash hset" [$rd1 read] 316 assert_equal "pmessage * __keyspace@${db}__:myhash hincrby" [$rd1 read] 317 $rd1 close 318 } 319 320 test "Keyspace notifications: stream events test" { 321 r config set notify-keyspace-events Kt 322 r del mystream 323 set rd1 [redis_deferring_client] 324 assert_equal {1} [psubscribe $rd1 *] 325 r xgroup create mystream mygroup $ mkstream 326 r xgroup createconsumer mystream mygroup Bob 327 set id [r xadd mystream 1 field1 A] 328 r xreadgroup group mygroup Alice STREAMS mystream > 329 r xclaim mystream mygroup Mike 0 $id force 330 # Not notify because of "Lee" not exists. 331 r xgroup delconsumer mystream mygroup Lee 332 # Not notify because of "Bob" exists. 333 r xautoclaim mystream mygroup Bob 0 $id 334 r xgroup delconsumer mystream mygroup Bob 335 assert_equal "pmessage * __keyspace@${db}__:mystream xgroup-create" [$rd1 read] 336 assert_equal "pmessage * __keyspace@${db}__:mystream xgroup-createconsumer" [$rd1 read] 337 assert_equal "pmessage * __keyspace@${db}__:mystream xadd" [$rd1 read] 338 assert_equal "pmessage * __keyspace@${db}__:mystream xgroup-createconsumer" [$rd1 read] 339 assert_equal "pmessage * __keyspace@${db}__:mystream xgroup-createconsumer" [$rd1 read] 340 assert_equal "pmessage * __keyspace@${db}__:mystream xgroup-delconsumer" [$rd1 read] 341 $rd1 close 342 } 343 344 test "Keyspace notifications: expired events (triggered expire)" { 345 r config set notify-keyspace-events Ex 346 r del foo 347 set rd1 [redis_deferring_client] 348 assert_equal {1} [psubscribe $rd1 *] 349 r psetex foo 100 1 350 wait_for_condition 50 100 { 351 [r exists foo] == 0 352 } else { 353 fail "Key does not expire?!" 354 } 355 assert_equal "pmessage * __keyevent@${db}__:expired foo" [$rd1 read] 356 $rd1 close 357 } 358 359 test "Keyspace notifications: expired events (background expire)" { 360 r config set notify-keyspace-events Ex 361 r del foo 362 set rd1 [redis_deferring_client] 363 assert_equal {1} [psubscribe $rd1 *] 364 r psetex foo 100 1 365 assert_equal "pmessage * __keyevent@${db}__:expired foo" [$rd1 read] 366 $rd1 close 367 } 368 369 test "Keyspace notifications: evicted events" { 370 r config set notify-keyspace-events Ee 371 r config set maxmemory-policy allkeys-lru 372 r flushdb 373 set rd1 [redis_deferring_client] 374 assert_equal {1} [psubscribe $rd1 *] 375 r set foo bar 376 r config set maxmemory 1 377 assert_equal "pmessage * __keyevent@${db}__:evicted foo" [$rd1 read] 378 r config set maxmemory 0 379 $rd1 close 380 r config set maxmemory-policy noeviction 381 } {OK} {needs:config-maxmemory} 382 383 test "Keyspace notifications: test CONFIG GET/SET of event flags" { 384 r config set notify-keyspace-events gKE 385 assert_equal {gKE} [lindex [r config get notify-keyspace-events] 1] 386 r config set notify-keyspace-events {$lshzxeKE} 387 assert_equal {$lshzxeKE} [lindex [r config get notify-keyspace-events] 1] 388 r config set notify-keyspace-events KA 389 assert_equal {AK} [lindex [r config get notify-keyspace-events] 1] 390 r config set notify-keyspace-events EA 391 assert_equal {AE} [lindex [r config get notify-keyspace-events] 1] 392 } 393} 394