]> git.saurik.com Git - redis.git/blob - tests/unit/pubsub.tcl
master branch merged into scripting.
[redis.git] / tests / unit / pubsub.tcl
1 start_server {tags {"pubsub"}} {
2 proc __consume_subscribe_messages {client type channels} {
3 set numsub -1
4 set counts {}
5
6 for {set i [llength $channels]} {$i > 0} {incr i -1} {
7 set msg [$client read]
8 assert_equal $type [lindex $msg 0]
9
10 # when receiving subscribe messages the channels names
11 # are ordered. when receiving unsubscribe messages
12 # they are unordered
13 set idx [lsearch -exact $channels [lindex $msg 1]]
14 if {[string match "*unsubscribe" $type]} {
15 assert {$idx >= 0}
16 } else {
17 assert {$idx == 0}
18 }
19 set channels [lreplace $channels $idx $idx]
20
21 # aggregate the subscription count to return to the caller
22 lappend counts [lindex $msg 2]
23 }
24
25 # we should have received messages for channels
26 assert {[llength $channels] == 0}
27 return $counts
28 }
29
30 proc subscribe {client channels} {
31 $client subscribe {*}$channels
32 __consume_subscribe_messages $client subscribe $channels
33 }
34
35 proc unsubscribe {client {channels {}}} {
36 $client unsubscribe {*}$channels
37 __consume_subscribe_messages $client unsubscribe $channels
38 }
39
40 proc psubscribe {client channels} {
41 $client psubscribe {*}$channels
42 __consume_subscribe_messages $client psubscribe $channels
43 }
44
45 proc punsubscribe {client {channels {}}} {
46 $client punsubscribe {*}$channels
47 __consume_subscribe_messages $client punsubscribe $channels
48 }
49
50 test "PUBLISH/SUBSCRIBE basics" {
51 set rd1 [redis_deferring_client]
52
53 # subscribe to two channels
54 assert_equal {1 2} [subscribe $rd1 {chan1 chan2}]
55 assert_equal 1 [r publish chan1 hello]
56 assert_equal 1 [r publish chan2 world]
57 assert_equal {message chan1 hello} [$rd1 read]
58 assert_equal {message chan2 world} [$rd1 read]
59
60 # unsubscribe from one of the channels
61 unsubscribe $rd1 {chan1}
62 assert_equal 0 [r publish chan1 hello]
63 assert_equal 1 [r publish chan2 world]
64 assert_equal {message chan2 world} [$rd1 read]
65
66 # unsubscribe from the remaining channel
67 unsubscribe $rd1 {chan2}
68 assert_equal 0 [r publish chan1 hello]
69 assert_equal 0 [r publish chan2 world]
70
71 # clean up clients
72 $rd1 close
73 }
74
75 test "PUBLISH/SUBSCRIBE with two clients" {
76 set rd1 [redis_deferring_client]
77 set rd2 [redis_deferring_client]
78
79 assert_equal {1} [subscribe $rd1 {chan1}]
80 assert_equal {1} [subscribe $rd2 {chan1}]
81 assert_equal 2 [r publish chan1 hello]
82 assert_equal {message chan1 hello} [$rd1 read]
83 assert_equal {message chan1 hello} [$rd2 read]
84
85 # clean up clients
86 $rd1 close
87 $rd2 close
88 }
89
90 test "PUBLISH/SUBSCRIBE after UNSUBSCRIBE without arguments" {
91 set rd1 [redis_deferring_client]
92 assert_equal {1 2 3} [subscribe $rd1 {chan1 chan2 chan3}]
93 unsubscribe $rd1
94 assert_equal 0 [r publish chan1 hello]
95 assert_equal 0 [r publish chan2 hello]
96 assert_equal 0 [r publish chan3 hello]
97
98 # clean up clients
99 $rd1 close
100 }
101
102 test "SUBSCRIBE to one channel more than once" {
103 set rd1 [redis_deferring_client]
104 assert_equal {1 1 1} [subscribe $rd1 {chan1 chan1 chan1}]
105 assert_equal 1 [r publish chan1 hello]
106 assert_equal {message chan1 hello} [$rd1 read]
107
108 # clean up clients
109 $rd1 close
110 }
111
112 test "UNSUBSCRIBE from non-subscribed channels" {
113 set rd1 [redis_deferring_client]
114 assert_equal {0 0 0} [unsubscribe $rd1 {foo bar quux}]
115
116 # clean up clients
117 $rd1 close
118 }
119
120 test "PUBLISH/PSUBSCRIBE basics" {
121 set rd1 [redis_deferring_client]
122
123 # subscribe to two patterns
124 assert_equal {1 2} [psubscribe $rd1 {foo.* bar.*}]
125 assert_equal 1 [r publish foo.1 hello]
126 assert_equal 1 [r publish bar.1 hello]
127 assert_equal 0 [r publish foo1 hello]
128 assert_equal 0 [r publish barfoo.1 hello]
129 assert_equal 0 [r publish qux.1 hello]
130 assert_equal {pmessage foo.* foo.1 hello} [$rd1 read]
131 assert_equal {pmessage bar.* bar.1 hello} [$rd1 read]
132
133 # unsubscribe from one of the patterns
134 assert_equal {1} [punsubscribe $rd1 {foo.*}]
135 assert_equal 0 [r publish foo.1 hello]
136 assert_equal 1 [r publish bar.1 hello]
137 assert_equal {pmessage bar.* bar.1 hello} [$rd1 read]
138
139 # unsubscribe from the remaining pattern
140 assert_equal {0} [punsubscribe $rd1 {bar.*}]
141 assert_equal 0 [r publish foo.1 hello]
142 assert_equal 0 [r publish bar.1 hello]
143
144 # clean up clients
145 $rd1 close
146 }
147
148 test "PUBLISH/PSUBSCRIBE with two clients" {
149 set rd1 [redis_deferring_client]
150 set rd2 [redis_deferring_client]
151
152 assert_equal {1} [psubscribe $rd1 {chan.*}]
153 assert_equal {1} [psubscribe $rd2 {chan.*}]
154 assert_equal 2 [r publish chan.foo hello]
155 assert_equal {pmessage chan.* chan.foo hello} [$rd1 read]
156 assert_equal {pmessage chan.* chan.foo hello} [$rd2 read]
157
158 # clean up clients
159 $rd1 close
160 $rd2 close
161 }
162
163 test "PUBLISH/PSUBSCRIBE after PUNSUBSCRIBE without arguments" {
164 set rd1 [redis_deferring_client]
165 assert_equal {1 2 3} [psubscribe $rd1 {chan1.* chan2.* chan3.*}]
166 punsubscribe $rd1
167 assert_equal 0 [r publish chan1.hi hello]
168 assert_equal 0 [r publish chan2.hi hello]
169 assert_equal 0 [r publish chan3.hi hello]
170
171 # clean up clients
172 $rd1 close
173 }
174
175 test "PUNSUBSCRIBE from non-subscribed channels" {
176 set rd1 [redis_deferring_client]
177 assert_equal {0 0 0} [punsubscribe $rd1 {foo.* bar.* quux.*}]
178
179 # clean up clients
180 $rd1 close
181 }
182
183 test "Mix SUBSCRIBE and PSUBSCRIBE" {
184 set rd1 [redis_deferring_client]
185 assert_equal {1} [subscribe $rd1 {foo.bar}]
186 assert_equal {2} [psubscribe $rd1 {foo.*}]
187
188 assert_equal 2 [r publish foo.bar hello]
189 assert_equal {message foo.bar hello} [$rd1 read]
190 assert_equal {pmessage foo.* foo.bar hello} [$rd1 read]
191
192 # clean up clients
193 $rd1 close
194 }
195 }