summaryrefslogtreecommitdiff
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 @@
-set testmodule [file normalize tests/modules/blockedclient.so]
-
-start_server {tags {"modules external:skip"}} {
- r module load $testmodule
-
- test {Locked GIL acquisition} {
- assert_match "OK" [r acquire_gil]
- }
-
- test {Locked GIL acquisition during multi} {
- r multi
- r acquire_gil
- assert_equal {{Blocked client is not supported inside multi}} [r exec]
- }
-
- test {Locked GIL acquisition from RM_Call} {
- assert_equal {Blocked client is not allowed} [r do_rm_call acquire_gil]
- }
-
- test {Blocking command are not block the client on RM_Call} {
- r lpush l test
- assert_equal [r do_rm_call blpop l 0] {l test}
-
- r lpush l test
- assert_equal [r do_rm_call brpop l 0] {l test}
-
- r lpush l1 test
- assert_equal [r do_rm_call brpoplpush l1 l2 0] {test}
- assert_equal [r do_rm_call brpop l2 0] {l2 test}
-
- r lpush l1 test
- assert_equal [r do_rm_call blmove l1 l2 LEFT LEFT 0] {test}
- assert_equal [r do_rm_call brpop l2 0] {l2 test}
-
- r ZADD zset1 0 a 1 b 2 c
- assert_equal [r do_rm_call bzpopmin zset1 0] {zset1 a 0}
- assert_equal [r do_rm_call bzpopmax zset1 0] {zset1 c 2}
-
- r xgroup create s g $ MKSTREAM
- r xadd s * foo bar
- assert {[r do_rm_call xread BLOCK 0 STREAMS s 0-0] ne {}}
- assert {[r do_rm_call xreadgroup group g c BLOCK 0 STREAMS s >] ne {}}
-
- assert {[r do_rm_call blpop empty_list 0] eq {}}
- assert {[r do_rm_call brpop empty_list 0] eq {}}
- assert {[r do_rm_call brpoplpush empty_list1 empty_list2 0] eq {}}
- assert {[r do_rm_call blmove empty_list1 empty_list2 LEFT LEFT 0] eq {}}
-
- assert {[r do_rm_call bzpopmin empty_zset 0] eq {}}
- assert {[r do_rm_call bzpopmax empty_zset 0] eq {}}
-
- r xgroup create empty_stream g $ MKSTREAM
- assert {[r do_rm_call xread BLOCK 0 STREAMS empty_stream $] eq {}}
- assert {[r do_rm_call xreadgroup group g c BLOCK 0 STREAMS empty_stream >] eq {}}
-
- }
-
- test {Monitor disallow inside RM_Call} {
- set e {}
- catch {
- r do_rm_call monitor
- } e
- set e
- } {*ERR*DENY BLOCKING*}
-
- test {subscribe disallow inside RM_Call} {
- set e {}
- catch {
- r do_rm_call subscribe x
- } e
- set e
- } {*ERR*DENY BLOCKING*}
-
- test {RM_Call from blocked client} {
- r hset hash foo bar
- r do_bg_rm_call hgetall hash
- } {foo bar}
-
- test {RM_Call from blocked client with script mode} {
- r do_bg_rm_call_format S hset k foo bar
- } {1}
-
- test {RM_Call from blocked client with oom mode} {
- r config set maxmemory 1
- # will set server.pre_command_oom_state to 1
- assert_error {OOM command not allowed*} {r hset hash foo bar}
- r config set maxmemory 0
- # now its should be OK to call OOM commands
- r do_bg_rm_call_format M hset k1 foo bar
- } {1} {needs:config-maxmemory}
-
- test {RESP version carries through to blocked client} {
- for {set client_proto 2} {$client_proto <= 3} {incr client_proto} {
- if {[lsearch $::denytags "resp3"] >= 0} {
- if {$client_proto == 3} {continue}
- } elseif {$::force_resp3} {
- if {$client_proto == 2} {continue}
- }
- r hello $client_proto
- r readraw 1
- set ret [r do_fake_bg_true]
- if {$client_proto == 2} {
- assert_equal $ret {:1}
- } else {
- assert_equal $ret "#t"
- }
- r readraw 0
- r hello 2
- }
- }
-
-foreach call_type {nested normal} {
- test "Busy module command - $call_type" {
- set busy_time_limit 50
- set old_time_limit [lindex [r config get busy-reply-threshold] 1]
- r config set busy-reply-threshold $busy_time_limit
- set rd [redis_deferring_client]
-
- # run command that blocks until released
- set start [clock clicks -milliseconds]
- if {$call_type == "nested"} {
- $rd do_rm_call slow_fg_command 0
- } else {
- $rd slow_fg_command 0
- }
- $rd flush
-
- # send another command after the blocked one, to make sure we don't attempt to process it
- $rd ping
- $rd flush
-
- # make sure we get BUSY error, and that we didn't get it too early
- wait_for_condition 50 100 {
- ([catch {r ping} reply] == 1) &&
- ([string match {*BUSY Slow module operation*} $reply])
- } else {
- fail "Failed waiting for busy slow response"
- }
- assert_morethan_equal [expr [clock clicks -milliseconds]-$start] $busy_time_limit
-
- # abort the blocking operation
- r stop_slow_fg_command
- wait_for_condition 50 100 {
- [catch {r ping} e] == 0
- } else {
- fail "Failed waiting for busy command to end"
- }
- assert_equal [$rd read] "1"
- assert_equal [$rd read] "PONG"
-
- # run command that blocks for 200ms
- set start [clock clicks -milliseconds]
- if {$call_type == "nested"} {
- $rd do_rm_call slow_fg_command 200000
- } else {
- $rd slow_fg_command 200000
- }
- $rd flush
- after 10 ;# try to make sure redis started running the command before we proceed
-
- # make sure we didn't get BUSY error, it simply blocked till the command was done
- r ping
- # The command blocks for 200ms, allow 1-2ms clock skew (1%)
- # to accommodate differences between using of monotonic timer and ustime
- assert_morethan_equal [expr [clock clicks -milliseconds]-$start] 198
- $rd read
-
- $rd close
- r config set busy-reply-threshold $old_time_limit
- }
-}
-
- test {RM_Call from blocked client} {
- set busy_time_limit 50
- set old_time_limit [lindex [r config get busy-reply-threshold] 1]
- r config set busy-reply-threshold $busy_time_limit
-
- # trigger slow operation
- r set_slow_bg_operation 1
- r hset hash foo bar
- set rd [redis_deferring_client]
- set start [clock clicks -milliseconds]
- $rd do_bg_rm_call hgetall hash
-
- # send another command after the blocked one, to make sure we don't attempt to process it
- $rd ping
- $rd flush
-
- # wait till we know we're blocked inside the module
- wait_for_condition 50 100 {
- [r is_in_slow_bg_operation] eq 1
- } else {
- fail "Failed waiting for slow operation to start"
- }
-
- # make sure we get BUSY error, and that we didn't get here too early
- assert_error {*BUSY Slow module operation*} {r ping}
- assert_morethan_equal [expr [clock clicks -milliseconds]-$start] $busy_time_limit
- # abort the blocking operation
- r set_slow_bg_operation 0
-
- wait_for_condition 50 100 {
- [r is_in_slow_bg_operation] eq 0
- } else {
- fail "Failed waiting for slow operation to stop"
- }
- assert_equal [r ping] {PONG}
-
- r config set busy-reply-threshold $old_time_limit
- assert_equal [$rd read] {foo bar}
- assert_equal [$rd read] {PONG}
- $rd close
- }
-
- test {blocked client reaches client output buffer limit} {
- r hset hash big [string repeat x 50000]
- r hset hash bada [string repeat x 50000]
- r hset hash boom [string repeat x 50000]
- r config set client-output-buffer-limit {normal 100000 0 0}
- r client setname myclient
- catch {r do_bg_rm_call hgetall hash} e
- assert_match "*I/O error*" $e
- reconnect
- set clients [r client list]
- assert_no_match "*name=myclient*" $clients
- }
-
- test {module client error stats} {
- r config resetstat
-
- # simple module command that replies with string error
- assert_error "ERR unknown command 'hgetalllll'" {r do_rm_call hgetalllll}
- assert_equal [errorrstat ERR r] {count=1}
-
- # simple module command that replies with string error
- assert_error "ERR unknown subcommand 'bla'. Try CONFIG HELP." {r do_rm_call config bla}
- assert_equal [errorrstat ERR r] {count=2}
-
- # module command that replies with string error from bg thread
- assert_error "NULL reply returned" {r do_bg_rm_call hgetalllll}
- assert_equal [errorrstat NULL r] {count=1}
-
- # module command that returns an arity error
- r do_rm_call set x x
- assert_error "ERR wrong number of arguments for 'do_rm_call' command" {r do_rm_call}
- assert_equal [errorrstat ERR r] {count=3}
-
- # RM_Call that propagates an error
- assert_error "WRONGTYPE*" {r do_rm_call hgetall x}
- assert_equal [errorrstat WRONGTYPE r] {count=1}
- assert_match {*calls=1,*,rejected_calls=0,failed_calls=1} [cmdrstat hgetall r]
-
- # RM_Call from bg thread that propagates an error
- assert_error "WRONGTYPE*" {r do_bg_rm_call hgetall x}
- assert_equal [errorrstat WRONGTYPE r] {count=2}
- assert_match {*calls=2,*,rejected_calls=0,failed_calls=2} [cmdrstat hgetall r]
-
- assert_equal [s total_error_replies] 6
- assert_match {*calls=5,*,rejected_calls=0,failed_calls=4} [cmdrstat do_rm_call r]
- assert_match {*calls=2,*,rejected_calls=0,failed_calls=2} [cmdrstat do_bg_rm_call r]
- }
-
- set master [srv 0 client]
- set master_host [srv 0 host]
- set master_port [srv 0 port]
- start_server [list overrides [list loadmodule "$testmodule"] tags {"external:skip"}] {
- set replica [srv 0 client]
- set replica_host [srv 0 host]
- set replica_port [srv 0 port]
-
- # Start the replication process...
- $replica replicaof $master_host $master_port
- wait_for_sync $replica
-
- test {WAIT command on module blocked client} {
- pause_process [srv 0 pid]
-
- $master do_bg_rm_call_format ! hset bk1 foo bar
-
- assert_equal [$master wait 1 1000] 0
- resume_process [srv 0 pid]
- assert_equal [$master wait 1 1000] 1
- assert_equal [$replica hget bk1 foo] bar
- }
- }
-
- test {Unblock by timer} {
- # When the client is unlock, we will get the OK reply.
- assert_match "OK" [r unblock_by_timer 100 0]
- }
-
- test {block time is shorter than timer period} {
- # This command does not have the reply.
- set rd [redis_deferring_client]
- $rd unblock_by_timer 100 10
- # Wait for the client to unlock.
- after 120
- $rd close
- }
-
- test {block time is equal to timer period} {
- # These time is equal, they will be unlocked in the same event loop,
- # when the client is unlock, we will get the OK reply from timer.
- assert_match "OK" [r unblock_by_timer 100 100]
- }
-
- test "Unload the module - blockedclient" {
- assert_equal {OK} [r module unload blockedclient]
- }
-}