mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 18:54:58 +00:00
da831c0d22
Updated procedure redis_deferring_client in test environent to valkey_deferring_client. Signed-off-by: Shivshankar-Reddy <shiva.sheri.github@gmail.com>
231 lines
8.9 KiB
Tcl
231 lines
8.9 KiB
Tcl
start_server {tags {"obuf-limits external:skip logreqres:skip"}} {
|
|
test {CONFIG SET client-output-buffer-limit} {
|
|
set oldval [lindex [r config get client-output-buffer-limit] 1]
|
|
|
|
catch {r config set client-output-buffer-limit "wrong number"} e
|
|
assert_match {*Wrong*arguments*} $e
|
|
|
|
catch {r config set client-output-buffer-limit "invalid_class 10mb 10mb 60"} e
|
|
assert_match {*Invalid*client*class*} $e
|
|
catch {r config set client-output-buffer-limit "master 10mb 10mb 60"} e
|
|
assert_match {*Invalid*client*class*} $e
|
|
|
|
catch {r config set client-output-buffer-limit "normal 10mbs 10mb 60"} e
|
|
assert_match {*Error*hard*} $e
|
|
|
|
catch {r config set client-output-buffer-limit "replica 10mb 10mbs 60"} e
|
|
assert_match {*Error*soft*} $e
|
|
|
|
catch {r config set client-output-buffer-limit "pubsub 10mb 10mb 60s"} e
|
|
assert_match {*Error*soft_seconds*} $e
|
|
|
|
r config set client-output-buffer-limit "normal 1mb 2mb 60 replica 3mb 4mb 70 pubsub 5mb 6mb 80"
|
|
set res [lindex [r config get client-output-buffer-limit] 1]
|
|
assert_equal $res "normal 1048576 2097152 60 slave 3145728 4194304 70 pubsub 5242880 6291456 80"
|
|
|
|
# Set back to the original value.
|
|
r config set client-output-buffer-limit $oldval
|
|
}
|
|
|
|
test {Client output buffer hard limit is enforced} {
|
|
r config set client-output-buffer-limit {pubsub 100000 0 0}
|
|
set rd1 [valkey_deferring_client]
|
|
|
|
$rd1 subscribe foo
|
|
set reply [$rd1 read]
|
|
assert {$reply eq "subscribe foo 1"}
|
|
|
|
set omem 0
|
|
while 1 {
|
|
r publish foo bar
|
|
set clients [split [r client list] "\r\n"]
|
|
set c [split [lindex $clients 1] " "]
|
|
if {![regexp {omem=([0-9]+)} $c - omem]} break
|
|
if {$omem > 200000} break
|
|
}
|
|
assert {$omem >= 70000 && $omem < 200000}
|
|
$rd1 close
|
|
}
|
|
|
|
foreach {soft_limit_time wait_for_timeout} {3 yes
|
|
4 no } {
|
|
if $wait_for_timeout {
|
|
set test_name "Client output buffer soft limit is enforced if time is overreached"
|
|
} else {
|
|
set test_name "Client output buffer soft limit is not enforced too early and is enforced when no traffic"
|
|
}
|
|
|
|
test $test_name {
|
|
r config set client-output-buffer-limit "pubsub 0 100000 $soft_limit_time"
|
|
set soft_limit_time [expr $soft_limit_time*1000]
|
|
set rd1 [valkey_deferring_client]
|
|
|
|
$rd1 client setname test_client
|
|
set reply [$rd1 read]
|
|
assert {$reply eq "OK"}
|
|
|
|
$rd1 subscribe foo
|
|
set reply [$rd1 read]
|
|
assert {$reply eq "subscribe foo 1"}
|
|
|
|
set omem 0
|
|
set start_time 0
|
|
set time_elapsed 0
|
|
set last_under_limit_time [clock milliseconds]
|
|
while 1 {
|
|
r publish foo [string repeat "x" 1000]
|
|
set clients [split [r client list] "\r\n"]
|
|
set c [lsearch -inline $clients *name=test_client*]
|
|
if {$start_time != 0} {
|
|
set time_elapsed [expr {[clock milliseconds]-$start_time}]
|
|
# Make sure test isn't taking too long
|
|
assert {$time_elapsed <= [expr $soft_limit_time+3000]}
|
|
}
|
|
if {$wait_for_timeout && $c == ""} {
|
|
# Make sure we're disconnected when we reach the soft limit
|
|
assert {$omem >= 100000 && $time_elapsed >= $soft_limit_time}
|
|
break
|
|
} else {
|
|
assert {[regexp {omem=([0-9]+)} $c - omem]}
|
|
}
|
|
if {$omem > 100000} {
|
|
if {$start_time == 0} {set start_time $last_under_limit_time}
|
|
if {!$wait_for_timeout && $time_elapsed >= [expr $soft_limit_time-1000]} break
|
|
# Slow down loop when omem has reached the limit.
|
|
after 10
|
|
} else {
|
|
# if the OS socket buffers swallowed what we previously filled, reset the start timer.
|
|
set start_time 0
|
|
set last_under_limit_time [clock milliseconds]
|
|
}
|
|
}
|
|
|
|
if {!$wait_for_timeout} {
|
|
# After we completely stopped the traffic, wait for soft limit to time out
|
|
set timeout [expr {$soft_limit_time+1500 - ([clock milliseconds]-$start_time)}]
|
|
wait_for_condition [expr $timeout/10] 10 {
|
|
[lsearch [split [r client list] "\r\n"] *name=test_client*] == -1
|
|
} else {
|
|
fail "Soft limit timed out but client still connected"
|
|
}
|
|
}
|
|
|
|
$rd1 close
|
|
}
|
|
}
|
|
|
|
test {No response for single command if client output buffer hard limit is enforced} {
|
|
r config set latency-tracking no
|
|
r config set client-output-buffer-limit {normal 100000 0 0}
|
|
# Total size of all items must be more than 100k
|
|
set item [string repeat "x" 1000]
|
|
for {set i 0} {$i < 150} {incr i} {
|
|
r lpush mylist $item
|
|
}
|
|
set orig_mem [s used_memory]
|
|
# Set client name and get all items
|
|
set rd [valkey_deferring_client]
|
|
$rd client setname mybiglist
|
|
assert {[$rd read] eq "OK"}
|
|
$rd lrange mylist 0 -1
|
|
$rd flush
|
|
after 100
|
|
|
|
# Before we read reply, the server will close this client.
|
|
set clients [r client list]
|
|
assert_no_match "*name=mybiglist*" $clients
|
|
set cur_mem [s used_memory]
|
|
# 10k just is a deviation threshold
|
|
assert {$cur_mem < 10000 + $orig_mem}
|
|
|
|
# Read nothing
|
|
set fd [$rd channel]
|
|
assert_equal {} [$rd rawread]
|
|
}
|
|
|
|
# Note: This test assumes that what's written with one write, will be read by the server in one read.
|
|
# this assumption is wrong, but seem to work empirically (for now)
|
|
test {No response for multi commands in pipeline if client output buffer limit is enforced} {
|
|
r config set client-output-buffer-limit {normal 100000 0 0}
|
|
set value [string repeat "x" 10000]
|
|
r set bigkey $value
|
|
set rd1 [valkey_deferring_client]
|
|
set rd2 [valkey_deferring_client]
|
|
$rd2 client setname multicommands
|
|
assert_equal "OK" [$rd2 read]
|
|
|
|
# Let the server sleep 1s firstly
|
|
$rd1 debug sleep 1
|
|
$rd1 flush
|
|
after 100
|
|
|
|
# Create a pipeline of commands that will be processed in one socket read.
|
|
# It is important to use one write, in TLS mode independent writes seem
|
|
# to wait for response from the server.
|
|
# Total size should be less than OS socket buffer, the server can
|
|
# execute all commands in this pipeline when it wakes up.
|
|
set buf ""
|
|
for {set i 0} {$i < 15} {incr i} {
|
|
append buf "set $i $i\r\n"
|
|
append buf "get $i\r\n"
|
|
append buf "del $i\r\n"
|
|
# One bigkey is 10k, total response size must be more than 100k
|
|
append buf "get bigkey\r\n"
|
|
}
|
|
$rd2 write $buf
|
|
$rd2 flush
|
|
after 100
|
|
|
|
# Reds must wake up if it can send reply
|
|
assert_equal "PONG" [r ping]
|
|
set clients [r client list]
|
|
assert_no_match "*name=multicommands*" $clients
|
|
assert_equal {} [$rd2 rawread]
|
|
}
|
|
|
|
test {Execute transactions completely even if client output buffer limit is enforced} {
|
|
r config set client-output-buffer-limit {normal 100000 0 0}
|
|
# Total size of all items must be more than 100k
|
|
set item [string repeat "x" 1000]
|
|
for {set i 0} {$i < 150} {incr i} {
|
|
r lpush mylist2 $item
|
|
}
|
|
|
|
# Output buffer limit is enforced during executing transaction
|
|
r client setname transactionclient
|
|
r set k1 v1
|
|
r multi
|
|
r set k2 v2
|
|
r get k2
|
|
r lrange mylist2 0 -1
|
|
r set k3 v3
|
|
r del k1
|
|
catch {[r exec]} e
|
|
assert_match "*I/O error*" $e
|
|
reconnect
|
|
set clients [r client list]
|
|
assert_no_match "*name=transactionclient*" $clients
|
|
|
|
# Transactions should be executed completely
|
|
assert_equal {} [r get k1]
|
|
assert_equal "v2" [r get k2]
|
|
assert_equal "v3" [r get k3]
|
|
}
|
|
|
|
test "Obuf limit, HRANDFIELD with huge count stopped mid-run" {
|
|
r config set client-output-buffer-limit {normal 1000000 0 0}
|
|
r hset myhash a b
|
|
catch {r hrandfield myhash -999999999} e
|
|
assert_match "*I/O error*" $e
|
|
reconnect
|
|
}
|
|
|
|
test "Obuf limit, KEYS stopped mid-run" {
|
|
r config set client-output-buffer-limit {normal 100000 0 0}
|
|
populate 1000 "long-key-name-prefix-of-100-chars-------------------------------------------------------------------"
|
|
catch {r keys *} e
|
|
assert_match "*I/O error*" $e
|
|
reconnect
|
|
}
|
|
}
|