aboutsummaryrefslogtreecommitdiff
path: root/examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl')
-rw-r--r--examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl310
1 files changed, 0 insertions, 310 deletions
diff --git a/examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl b/examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl
deleted file mode 100644
index 7dcc1d6..0000000
--- a/examples/redis-unstable/tests/unit/moduleapi/blockedclient.tcl
+++ /dev/null
@@ -1,310 +0,0 @@
1set testmodule [file normalize tests/modules/blockedclient.so]
2
3start_server {tags {"modules external:skip"}} {
4 r module load $testmodule
5
6 test {Locked GIL acquisition} {
7 assert_match "OK" [r acquire_gil]
8 }
9
10 test {Locked GIL acquisition during multi} {
11 r multi
12 r acquire_gil
13 assert_equal {{Blocked client is not supported inside multi}} [r exec]
14 }
15
16 test {Locked GIL acquisition from RM_Call} {
17 assert_equal {Blocked client is not allowed} [r do_rm_call acquire_gil]
18 }
19
20 test {Blocking command are not block the client on RM_Call} {
21 r lpush l test
22 assert_equal [r do_rm_call blpop l 0] {l test}
23
24 r lpush l test
25 assert_equal [r do_rm_call brpop l 0] {l test}
26
27 r lpush l1 test
28 assert_equal [r do_rm_call brpoplpush l1 l2 0] {test}
29 assert_equal [r do_rm_call brpop l2 0] {l2 test}
30
31 r lpush l1 test
32 assert_equal [r do_rm_call blmove l1 l2 LEFT LEFT 0] {test}
33 assert_equal [r do_rm_call brpop l2 0] {l2 test}
34
35 r ZADD zset1 0 a 1 b 2 c
36 assert_equal [r do_rm_call bzpopmin zset1 0] {zset1 a 0}
37 assert_equal [r do_rm_call bzpopmax zset1 0] {zset1 c 2}
38
39 r xgroup create s g $ MKSTREAM
40 r xadd s * foo bar
41 assert {[r do_rm_call xread BLOCK 0 STREAMS s 0-0] ne {}}
42 assert {[r do_rm_call xreadgroup group g c BLOCK 0 STREAMS s >] ne {}}
43
44 assert {[r do_rm_call blpop empty_list 0] eq {}}
45 assert {[r do_rm_call brpop empty_list 0] eq {}}
46 assert {[r do_rm_call brpoplpush empty_list1 empty_list2 0] eq {}}
47 assert {[r do_rm_call blmove empty_list1 empty_list2 LEFT LEFT 0] eq {}}
48
49 assert {[r do_rm_call bzpopmin empty_zset 0] eq {}}
50 assert {[r do_rm_call bzpopmax empty_zset 0] eq {}}
51
52 r xgroup create empty_stream g $ MKSTREAM
53 assert {[r do_rm_call xread BLOCK 0 STREAMS empty_stream $] eq {}}
54 assert {[r do_rm_call xreadgroup group g c BLOCK 0 STREAMS empty_stream >] eq {}}
55
56 }
57
58 test {Monitor disallow inside RM_Call} {
59 set e {}
60 catch {
61 r do_rm_call monitor
62 } e
63 set e
64 } {*ERR*DENY BLOCKING*}
65
66 test {subscribe disallow inside RM_Call} {
67 set e {}
68 catch {
69 r do_rm_call subscribe x
70 } e
71 set e
72 } {*ERR*DENY BLOCKING*}
73
74 test {RM_Call from blocked client} {
75 r hset hash foo bar
76 r do_bg_rm_call hgetall hash
77 } {foo bar}
78
79 test {RM_Call from blocked client with script mode} {
80 r do_bg_rm_call_format S hset k foo bar
81 } {1}
82
83 test {RM_Call from blocked client with oom mode} {
84 r config set maxmemory 1
85 # will set server.pre_command_oom_state to 1
86 assert_error {OOM command not allowed*} {r hset hash foo bar}
87 r config set maxmemory 0
88 # now its should be OK to call OOM commands
89 r do_bg_rm_call_format M hset k1 foo bar
90 } {1} {needs:config-maxmemory}
91
92 test {RESP version carries through to blocked client} {
93 for {set client_proto 2} {$client_proto <= 3} {incr client_proto} {
94 if {[lsearch $::denytags "resp3"] >= 0} {
95 if {$client_proto == 3} {continue}
96 } elseif {$::force_resp3} {
97 if {$client_proto == 2} {continue}
98 }
99 r hello $client_proto
100 r readraw 1
101 set ret [r do_fake_bg_true]
102 if {$client_proto == 2} {
103 assert_equal $ret {:1}
104 } else {
105 assert_equal $ret "#t"
106 }
107 r readraw 0
108 r hello 2
109 }
110 }
111
112foreach call_type {nested normal} {
113 test "Busy module command - $call_type" {
114 set busy_time_limit 50
115 set old_time_limit [lindex [r config get busy-reply-threshold] 1]
116 r config set busy-reply-threshold $busy_time_limit
117 set rd [redis_deferring_client]
118
119 # run command that blocks until released
120 set start [clock clicks -milliseconds]
121 if {$call_type == "nested"} {
122 $rd do_rm_call slow_fg_command 0
123 } else {
124 $rd slow_fg_command 0
125 }
126 $rd flush
127
128 # send another command after the blocked one, to make sure we don't attempt to process it
129 $rd ping
130 $rd flush
131
132 # make sure we get BUSY error, and that we didn't get it too early
133 wait_for_condition 50 100 {
134 ([catch {r ping} reply] == 1) &&
135 ([string match {*BUSY Slow module operation*} $reply])
136 } else {
137 fail "Failed waiting for busy slow response"
138 }
139 assert_morethan_equal [expr [clock clicks -milliseconds]-$start] $busy_time_limit
140
141 # abort the blocking operation
142 r stop_slow_fg_command
143 wait_for_condition 50 100 {
144 [catch {r ping} e] == 0
145 } else {
146 fail "Failed waiting for busy command to end"
147 }
148 assert_equal [$rd read] "1"
149 assert_equal [$rd read] "PONG"
150
151 # run command that blocks for 200ms
152 set start [clock clicks -milliseconds]
153 if {$call_type == "nested"} {
154 $rd do_rm_call slow_fg_command 200000
155 } else {
156 $rd slow_fg_command 200000
157 }
158 $rd flush
159 after 10 ;# try to make sure redis started running the command before we proceed
160
161 # make sure we didn't get BUSY error, it simply blocked till the command was done
162 r ping
163 # The command blocks for 200ms, allow 1-2ms clock skew (1%)
164 # to accommodate differences between using of monotonic timer and ustime
165 assert_morethan_equal [expr [clock clicks -milliseconds]-$start] 198
166 $rd read
167
168 $rd close
169 r config set busy-reply-threshold $old_time_limit
170 }
171}
172
173 test {RM_Call from blocked client} {
174 set busy_time_limit 50
175 set old_time_limit [lindex [r config get busy-reply-threshold] 1]
176 r config set busy-reply-threshold $busy_time_limit
177
178 # trigger slow operation
179 r set_slow_bg_operation 1
180 r hset hash foo bar
181 set rd [redis_deferring_client]
182 set start [clock clicks -milliseconds]
183 $rd do_bg_rm_call hgetall hash
184
185 # send another command after the blocked one, to make sure we don't attempt to process it
186 $rd ping
187 $rd flush
188
189 # wait till we know we're blocked inside the module
190 wait_for_condition 50 100 {
191 [r is_in_slow_bg_operation] eq 1
192 } else {
193 fail "Failed waiting for slow operation to start"
194 }
195
196 # make sure we get BUSY error, and that we didn't get here too early
197 assert_error {*BUSY Slow module operation*} {r ping}
198 assert_morethan_equal [expr [clock clicks -milliseconds]-$start] $busy_time_limit
199 # abort the blocking operation
200 r set_slow_bg_operation 0
201
202 wait_for_condition 50 100 {
203 [r is_in_slow_bg_operation] eq 0
204 } else {
205 fail "Failed waiting for slow operation to stop"
206 }
207 assert_equal [r ping] {PONG}
208
209 r config set busy-reply-threshold $old_time_limit
210 assert_equal [$rd read] {foo bar}
211 assert_equal [$rd read] {PONG}
212 $rd close
213 }
214
215 test {blocked client reaches client output buffer limit} {
216 r hset hash big [string repeat x 50000]
217 r hset hash bada [string repeat x 50000]
218 r hset hash boom [string repeat x 50000]
219 r config set client-output-buffer-limit {normal 100000 0 0}
220 r client setname myclient
221 catch {r do_bg_rm_call hgetall hash} e
222 assert_match "*I/O error*" $e
223 reconnect
224 set clients [r client list]
225 assert_no_match "*name=myclient*" $clients
226 }
227
228 test {module client error stats} {
229 r config resetstat
230
231 # simple module command that replies with string error
232 assert_error "ERR unknown command 'hgetalllll'" {r do_rm_call hgetalllll}
233 assert_equal [errorrstat ERR r] {count=1}
234
235 # simple module command that replies with string error
236 assert_error "ERR unknown subcommand 'bla'. Try CONFIG HELP." {r do_rm_call config bla}
237 assert_equal [errorrstat ERR r] {count=2}
238
239 # module command that replies with string error from bg thread
240 assert_error "NULL reply returned" {r do_bg_rm_call hgetalllll}
241 assert_equal [errorrstat NULL r] {count=1}
242
243 # module command that returns an arity error
244 r do_rm_call set x x
245 assert_error "ERR wrong number of arguments for 'do_rm_call' command" {r do_rm_call}
246 assert_equal [errorrstat ERR r] {count=3}
247
248 # RM_Call that propagates an error
249 assert_error "WRONGTYPE*" {r do_rm_call hgetall x}
250 assert_equal [errorrstat WRONGTYPE r] {count=1}
251 assert_match {*calls=1,*,rejected_calls=0,failed_calls=1} [cmdrstat hgetall r]
252
253 # RM_Call from bg thread that propagates an error
254 assert_error "WRONGTYPE*" {r do_bg_rm_call hgetall x}
255 assert_equal [errorrstat WRONGTYPE r] {count=2}
256 assert_match {*calls=2,*,rejected_calls=0,failed_calls=2} [cmdrstat hgetall r]
257
258 assert_equal [s total_error_replies] 6
259 assert_match {*calls=5,*,rejected_calls=0,failed_calls=4} [cmdrstat do_rm_call r]
260 assert_match {*calls=2,*,rejected_calls=0,failed_calls=2} [cmdrstat do_bg_rm_call r]
261 }
262
263 set master [srv 0 client]
264 set master_host [srv 0 host]
265 set master_port [srv 0 port]
266 start_server [list overrides [list loadmodule "$testmodule"] tags {"external:skip"}] {
267 set replica [srv 0 client]
268 set replica_host [srv 0 host]
269 set replica_port [srv 0 port]
270
271 # Start the replication process...
272 $replica replicaof $master_host $master_port
273 wait_for_sync $replica
274
275 test {WAIT command on module blocked client} {
276 pause_process [srv 0 pid]
277
278 $master do_bg_rm_call_format ! hset bk1 foo bar
279
280 assert_equal [$master wait 1 1000] 0
281 resume_process [srv 0 pid]
282 assert_equal [$master wait 1 1000] 1
283 assert_equal [$replica hget bk1 foo] bar
284 }
285 }
286
287 test {Unblock by timer} {
288 # When the client is unlock, we will get the OK reply.
289 assert_match "OK" [r unblock_by_timer 100 0]
290 }
291
292 test {block time is shorter than timer period} {
293 # This command does not have the reply.
294 set rd [redis_deferring_client]
295 $rd unblock_by_timer 100 10
296 # Wait for the client to unlock.
297 after 120
298 $rd close
299 }
300
301 test {block time is equal to timer period} {
302 # These time is equal, they will be unlocked in the same event loop,
303 # when the client is unlock, we will get the OK reply from timer.
304 assert_match "OK" [r unblock_by_timer 100 100]
305 }
306
307 test "Unload the module - blockedclient" {
308 assert_equal {OK} [r module unload blockedclient]
309 }
310}