Unverified Commit 2dba1e39 authored by Oran Agra's avatar Oran Agra Committed by GitHub
Browse files

Merge 6.2 RC3

parents ec2d1807 95338f9c
start_server {tags {"pause"}} { start_server {tags {"pause network"}} {
test "Test read commands are not blocked by client pause" { test "Test read commands are not blocked by client pause" {
r client PAUSE 100000000 WRITE r client PAUSE 100000000 WRITE
set rd [redis_deferring_client] set rd [redis_deferring_client]
......
start_server {tags {"protocol"}} { start_server {tags {"protocol network"}} {
test "Handle an empty query" { test "Handle an empty query" {
reconnect reconnect
r write "\r\n" r write "\r\n"
......
start_server {tags {"pubsub"}} { start_server {tags {"pubsub network"}} {
proc __consume_subscribe_messages {client type channels} { proc __consume_subscribe_messages {client type channels} {
set numsub -1 set numsub -1
set counts {} set counts {}
......
start_server {tags {"scan"}} { start_server {tags {"scan network"}} {
test "SCAN basic" { test "SCAN basic" {
r flushdb r flushdb
r debug populate 1000 r debug populate 1000
......
...@@ -330,6 +330,15 @@ start_server {tags {"scripting"}} { ...@@ -330,6 +330,15 @@ start_server {tags {"scripting"}} {
set e set e
} {NOSCRIPT*} } {NOSCRIPT*}
test {SCRIPTING FLUSH ASYNC} {
for {set j 0} {$j < 100} {incr j} {
r script load "return $j"
}
assert { [string match "*number_of_cached_scripts:100*" [r info Memory]] }
r script flush async
assert { [string match "*number_of_cached_scripts:0*" [r info Memory]] }
}
test {SCRIPT EXISTS - can detect already defined scripts?} { test {SCRIPT EXISTS - can detect already defined scripts?} {
r eval "return 1+1" 0 r eval "return 1+1" 0
r script exists a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bd9 a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bda r script exists a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bd9 a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bda
......
start_server {tags {"tracking"}} { start_server {tags {"tracking network"}} {
# Create a deferred client we'll use to redirect invalidation # Create a deferred client we'll use to redirect invalidation
# messages to. # messages to.
set rd_redirection [redis_deferring_client] set rd_redirection [redis_deferring_client]
......
...@@ -18,6 +18,181 @@ start_server {tags {"hash"}} { ...@@ -18,6 +18,181 @@ start_server {tags {"hash"}} {
assert_encoding ziplist smallhash assert_encoding ziplist smallhash
} }
proc create_hash {key entries} {
r del $key
foreach entry $entries {
r hset $key [lindex $entry 0] [lindex $entry 1]
}
}
proc get_keys {l} {
set res {}
foreach entry $l {
set key [lindex $entry 0]
lappend res $key
}
return $res
}
foreach {type contents} "ziplist {{a 1} {b 2} {c 3}} hashtable {{a 1} {b 2} {[randstring 70 90 alpha] 3}}" {
set original_max_value [lindex [r config get hash-max-ziplist-value] 1]
r config set hash-max-ziplist-value 10
create_hash myhash $contents
assert_encoding $type myhash
test "HRANDFIELD - $type" {
unset -nocomplain myhash
array set myhash {}
for {set i 0} {$i < 100} {incr i} {
set key [r hrandfield myhash]
set myhash($key) 1
}
assert_equal [lsort [get_keys $contents]] [lsort [array names myhash]]
}
r config set hash-max-ziplist-value $original_max_value
}
test "HRANDFIELD with RESP3" {
r hello 3
set res [r hrandfield myhash 3 withvalues]
assert_equal [llength $res] 3
assert_equal [llength [lindex $res 1]] 2
set res [r hrandfield myhash 3]
assert_equal [llength $res] 3
assert_equal [llength [lindex $res 1]] 1
}
r hello 2
test "HRANDFIELD count of 0 is handled correctly" {
r hrandfield myhash 0
} {}
test "HRANDFIELD with <count> against non existing key" {
r hrandfield nonexisting_key 100
} {}
foreach {type contents} "
hashtable {{a 1} {b 2} {c 3} {d 4} {e 5} {6 f} {7 g} {8 h} {9 i} {[randstring 70 90 alpha] 10}}
ziplist {{a 1} {b 2} {c 3} {d 4} {e 5} {6 f} {7 g} {8 h} {9 i} {10 j}} " {
test "HRANDFIELD with <count> - $type" {
set original_max_value [lindex [r config get hash-max-ziplist-value] 1]
r config set hash-max-ziplist-value 10
create_hash myhash $contents
assert_encoding $type myhash
# create a dict for easy lookup
unset -nocomplain mydict
foreach {k v} [r hgetall myhash] {
dict append mydict $k $v
}
# We'll stress different parts of the code, see the implementation
# of HRANDFIELD for more information, but basically there are
# four different code paths.
# PATH 1: Use negative count.
# 1) Check that it returns repeated elements with and without values.
set res [r hrandfield myhash -20]
assert_equal [llength $res] 20
# again with WITHVALUES
set res [r hrandfield myhash -20 withvalues]
assert_equal [llength $res] 40
# 2) Check that all the elements actually belong to the original hash.
foreach {key val} $res {
assert {[dict exists $mydict $key]}
}
# 3) Check that eventually all the elements are returned.
# Use both WITHVALUES and without
unset -nocomplain auxset
set iterations 1000
while {$iterations != 0} {
incr iterations -1
if {[expr {$iterations % 2}] == 0} {
set res [r hrandfield myhash -3 withvalues]
foreach {key val} $res {
dict append auxset $key $val
}
} else {
set res [r hrandfield myhash -3]
foreach key $res {
dict append auxset $key $val
}
}
if {[lsort [dict keys $mydict]] eq
[lsort [dict keys $auxset]]} {
break;
}
}
assert {$iterations != 0}
# PATH 2: positive count (unique behavior) with requested size
# equal or greater than set size.
foreach size {10 20} {
set res [r hrandfield myhash $size]
assert_equal [llength $res] 10
assert_equal [lsort $res] [lsort [dict keys $mydict]]
# again with WITHVALUES
set res [r hrandfield myhash $size withvalues]
assert_equal [llength $res] 20
assert_equal [lsort $res] [lsort $mydict]
}
# PATH 3: Ask almost as elements as there are in the set.
# In this case the implementation will duplicate the original
# set and will remove random elements up to the requested size.
#
# PATH 4: Ask a number of elements definitely smaller than
# the set size.
#
# We can test both the code paths just changing the size but
# using the same code.
foreach size {8 2} {
set res [r hrandfield myhash $size]
assert_equal [llength $res] $size
# again with WITHVALUES
set res [r hrandfield myhash $size withvalues]
assert_equal [llength $res] [expr {$size * 2}]
# 1) Check that all the elements actually belong to the
# original set.
foreach ele [dict keys $res] {
assert {[dict exists $mydict $ele]}
}
# 2) Check that eventually all the elements are returned.
# Use both WITHVALUES and without
unset -nocomplain auxset
set iterations 1000
while {$iterations != 0} {
incr iterations -1
if {[expr {$iterations % 2}] == 0} {
set res [r hrandfield myhash $size withvalues]
foreach {key value} $res {
dict append auxset $key $value
}
} else {
set res [r hrandfield myhash $size]
foreach key $res {
dict append auxset $key
}
}
if {[lsort [dict keys $mydict]] eq
[lsort [dict keys $auxset]]} {
break;
}
}
assert {$iterations != 0}
}
}
r config set hash-max-ziplist-value $original_max_value
}
test {HSET/HLEN - Big hash creation} { test {HSET/HLEN - Big hash creation} {
array set bighash {} array set bighash {}
for {set i 0} {$i < 1024} {incr i} { for {set i 0} {$i < 1024} {incr i} {
......
...@@ -501,7 +501,7 @@ start_server { ...@@ -501,7 +501,7 @@ start_server {
set iterations 1000 set iterations 1000
while {$iterations != 0} { while {$iterations != 0} {
incr iterations -1 incr iterations -1
set res [r srandmember myset -10] set res [r srandmember myset $size]
foreach ele $res { foreach ele $res {
set auxset($ele) 1 set auxset($ele) 1
} }
......
...@@ -102,6 +102,91 @@ start_server {tags {"string"}} { ...@@ -102,6 +102,91 @@ start_server {tags {"string"}} {
assert_equal 20 [r get x] assert_equal 20 [r get x]
} }
test "GETEX EX option" {
r del foo
r set foo bar
r getex foo ex 10
assert_range [r ttl foo] 5 10
}
test "GETEX PX option" {
r del foo
r set foo bar
r getex foo px 10000
assert_range [r pttl foo] 5000 10000
}
test "GETEX EXAT option" {
r del foo
r set foo bar
r getex foo exat [expr [clock seconds] + 10]
assert_range [r ttl foo] 5 10
}
test "GETEX PXAT option" {
r del foo
r set foo bar
r getex foo pxat [expr [clock milliseconds] + 10000]
assert_range [r pttl foo] 5000 10000
}
test "GETEX PERSIST option" {
r del foo
r set foo bar ex 10
assert_range [r ttl foo] 5 10
r getex foo persist
assert_equal -1 [r ttl foo]
}
test "GETEX no option" {
r del foo
r set foo bar
r getex foo
assert_equal bar [r getex foo]
}
test "GETEX syntax errors" {
set ex {}
catch {r getex foo non-existent-option} ex
set ex
} {*syntax*}
test "GETEX no arguments" {
set ex {}
catch {r getex} ex
set ex
} {*wrong number of arguments*}
test "GETDEL command" {
r del foo
r set foo bar
assert_equal bar [r getdel foo ]
assert_equal {} [r getdel foo ]
}
test {GETDEL propagate as DEL command to replica} {
set repl [attach_to_replication_stream]
r set foo bar
r getdel foo
assert_replication_stream $repl {
{select *}
{set foo bar}
{del foo}
}
}
test {GETEX without argument does not propagate to replica} {
set repl [attach_to_replication_stream]
r set foo bar
r getex foo
r del foo
assert_replication_stream $repl {
{select *}
{set foo bar}
{del foo}
}
}
test {MGET} { test {MGET} {
r flushdb r flushdb
r set foo BAR r set foo BAR
...@@ -437,6 +522,17 @@ start_server {tags {"string"}} { ...@@ -437,6 +522,17 @@ start_server {tags {"string"}} {
assert {$ttl <= 10 && $ttl > 5} assert {$ttl <= 10 && $ttl > 5}
} }
test "Extended SET EXAT option" {
r del foo
r set foo bar exat [expr [clock seconds] + 10]
assert_range [r ttl foo] 5 10
}
test "Extended SET PXAT option" {
r del foo
r set foo bar pxat [expr [clock milliseconds] + 10000]
assert_range [r ttl foo] 5 10
}
test {Extended SET using multiple options at once} { test {Extended SET using multiple options at once} {
r set foo val r set foo val
assert {[r set foo bar xx px 10000] eq {OK}} assert {[r set foo bar xx px 10000] eq {OK}}
......
...@@ -7,6 +7,8 @@ start_server {tags {"zset"}} { ...@@ -7,6 +7,8 @@ start_server {tags {"zset"}} {
} }
proc basics {encoding} { proc basics {encoding} {
set original_max_entries [lindex [r config get zset-max-ziplist-entries] 1]
set original_max_value [lindex [r config get zset-max-ziplist-value] 1]
if {$encoding == "ziplist"} { if {$encoding == "ziplist"} {
r config set zset-max-ziplist-entries 128 r config set zset-max-ziplist-entries 128
r config set zset-max-ziplist-value 64 r config set zset-max-ziplist-value 64
...@@ -713,6 +715,12 @@ start_server {tags {"zset"}} { ...@@ -713,6 +715,12 @@ start_server {tags {"zset"}} {
assert_equal {b 3 c 5} [r zinter 2 zseta zsetb withscores] assert_equal {b 3 c 5} [r zinter 2 zseta zsetb withscores]
} }
test "ZINTER RESP3 - $encoding" {
r hello 3
assert_equal {{b 3.0} {c 5.0}} [r zinter 2 zseta zsetb withscores]
}
r hello 2
test "ZINTERSTORE with weights - $encoding" { test "ZINTERSTORE with weights - $encoding" {
assert_equal 2 [r zinterstore zsetc 2 zseta zsetb weights 2 3] assert_equal 2 [r zinterstore zsetc 2 zseta zsetb weights 2 3]
assert_equal {b 7 c 12} [r zrange zsetc 0 -1 withscores] assert_equal {b 7 c 12} [r zrange zsetc 0 -1 withscores]
...@@ -919,6 +927,9 @@ start_server {tags {"zset"}} { ...@@ -919,6 +927,9 @@ start_server {tags {"zset"}} {
assert_equal 0 [r zcard z1] assert_equal 0 [r zcard z1]
assert_equal 1 [r zcard z2] assert_equal 1 [r zcard z2]
} }
r config set zset-max-ziplist-entries $original_max_entries
r config set zset-max-ziplist-value $original_max_value
} }
basics ziplist basics ziplist
...@@ -1016,6 +1027,8 @@ start_server {tags {"zset"}} { ...@@ -1016,6 +1027,8 @@ start_server {tags {"zset"}} {
} }
proc stressers {encoding} { proc stressers {encoding} {
set original_max_entries [lindex [r config get zset-max-ziplist-entries] 1]
set original_max_value [lindex [r config get zset-max-ziplist-value] 1]
if {$encoding == "ziplist"} { if {$encoding == "ziplist"} {
# Little extra to allow proper fuzzing in the sorting stresser # Little extra to allow proper fuzzing in the sorting stresser
r config set zset-max-ziplist-entries 256 r config set zset-max-ziplist-entries 256
...@@ -1440,6 +1453,8 @@ start_server {tags {"zset"}} { ...@@ -1440,6 +1453,8 @@ start_server {tags {"zset"}} {
r zadd zset 0 foo r zadd zset 0 foo
assert_equal {zset foo 0} [$rd read] assert_equal {zset foo 0} [$rd read]
} }
r config set zset-max-ziplist-entries $original_max_entries
r config set zset-max-ziplist-value $original_max_value
} }
tags {"slow"} { tags {"slow"} {
...@@ -1481,6 +1496,12 @@ start_server {tags {"zset"}} { ...@@ -1481,6 +1496,12 @@ start_server {tags {"zset"}} {
r zrange z2 0 -1 withscores r zrange z2 0 -1 withscores
} {a 1 b 2 c 3 d 4} } {a 1 b 2 c 3 d 4}
test {ZRANGESTORE RESP3} {
r hello 3
r zrange z2 0 -1 withscores
} {{a 1.0} {b 2.0} {c 3.0} {d 4.0}}
r hello 2
test {ZRANGESTORE range} { test {ZRANGESTORE range} {
set res [r zrangestore z2 z1 1 2] set res [r zrangestore z2 z1 1 2]
assert_equal $res 2 assert_equal $res 2
...@@ -1554,4 +1575,171 @@ start_server {tags {"zset"}} { ...@@ -1554,4 +1575,171 @@ start_server {tags {"zset"}} {
catch {r zrangebyscore z1 0 -1 REV} err catch {r zrangebyscore z1 0 -1 REV} err
assert_match "*syntax*" $err assert_match "*syntax*" $err
} }
proc get_keys {l} {
set res {}
foreach {score key} $l {
lappend res $key
}
return $res
}
foreach {type contents} "ziplist {1 a 2 b 3 c} skiplist {1 a 2 b 3 [randstring 70 90 alpha]}" {
set original_max_value [lindex [r config get zset-max-ziplist-value] 1]
r config set zset-max-ziplist-value 10
create_zset myzset $contents
assert_encoding $type myzset
test "ZRANDMEMBER - $type" {
unset -nocomplain myzset
array set myzset {}
for {set i 0} {$i < 100} {incr i} {
set key [r zrandmember myzset]
set myzset($key) 1
}
assert_equal [lsort [get_keys $contents]] [lsort [array names myzset]]
}
r config set zset-max-ziplist-value $original_max_value
}
test "ZRANDMEMBER with RESP3" {
r hello 3
set res [r zrandmember myzset 3 withscores]
assert_equal [llength $res] 3
assert_equal [llength [lindex $res 1]] 2
set res [r zrandmember myzset 3]
assert_equal [llength $res] 3
assert_equal [llength [lindex $res 1]] 1
}
r hello 2
test "ZRANDMEMBER count of 0 is handled correctly" {
r zrandmember myzset 0
} {}
test "ZRANDMEMBER with <count> against non existing key" {
r zrandmember nonexisting_key 100
} {}
foreach {type contents} "
skiplist {1 a 2 b 3 c 4 d 5 e 6 f 7 g 7 h 9 i 10 [randstring 70 90 alpha]}
ziplist {1 a 2 b 3 c 4 d 5 e 6 f 7 g 7 h 9 i 10 j} " {
test "ZRANDMEMBER with <count> - $type" {
set original_max_value [lindex [r config get zset-max-ziplist-value] 1]
r config set zset-max-ziplist-value 10
create_zset myzset $contents
assert_encoding $type myzset
# create a dict for easy lookup
unset -nocomplain mydict
foreach {k v} [r zrange myzset 0 -1 withscores] {
dict append mydict $k $v
}
# We'll stress different parts of the code, see the implementation
# of ZRANDMEMBER for more information, but basically there are
# four different code paths.
# PATH 1: Use negative count.
# 1) Check that it returns repeated elements with and without values.
set res [r zrandmember myzset -20]
assert_equal [llength $res] 20
# again with WITHSCORES
set res [r zrandmember myzset -20 withscores]
assert_equal [llength $res] 40
# 2) Check that all the elements actually belong to the original zset.
foreach {key val} $res {
assert {[dict exists $mydict $key]}
}
# 3) Check that eventually all the elements are returned.
# Use both WITHSCORES and without
unset -nocomplain auxset
set iterations 1000
while {$iterations != 0} {
incr iterations -1
if {[expr {$iterations % 2}] == 0} {
set res [r zrandmember myzset -3 withscores]
foreach {key val} $res {
dict append auxset $key $val
}
} else {
set res [r zrandmember myzset -3]
foreach key $res {
dict append auxset $key $val
}
}
if {[lsort [dict keys $mydict]] eq
[lsort [dict keys $auxset]]} {
break;
}
}
assert {$iterations != 0}
# PATH 2: positive count (unique behavior) with requested size
# equal or greater than set size.
foreach size {10 20} {
set res [r zrandmember myzset $size]
assert_equal [llength $res] 10
assert_equal [lsort $res] [lsort [dict keys $mydict]]
# again with WITHSCORES
set res [r zrandmember myzset $size withscores]
assert_equal [llength $res] 20
assert_equal [lsort $res] [lsort $mydict]
}
# PATH 3: Ask almost as elements as there are in the set.
# In this case the implementation will duplicate the original
# set and will remove random elements up to the requested size.
#
# PATH 4: Ask a number of elements definitely smaller than
# the set size.
#
# We can test both the code paths just changing the size but
# using the same code.
foreach size {8 2} {
set res [r zrandmember myzset $size]
assert_equal [llength $res] $size
# again with WITHSCORES
set res [r zrandmember myzset $size withscores]
assert_equal [llength $res] [expr {$size * 2}]
# 1) Check that all the elements actually belong to the
# original set.
foreach ele [dict keys $res] {
assert {[dict exists $mydict $ele]}
}
# 2) Check that eventually all the elements are returned.
# Use both WITHSCORES and without
unset -nocomplain auxset
set iterations 1000
while {$iterations != 0} {
incr iterations -1
if {[expr {$iterations % 2}] == 0} {
set res [r zrandmember myzset $size withscores]
foreach {key value} $res {
dict append auxset $key $value
}
} else {
set res [r zrandmember myzset $size]
foreach key $res {
dict append auxset $key
}
}
if {[lsort [dict keys $mydict]] eq
[lsort [dict keys $auxset]]} {
break;
}
}
assert {$iterations != 0}
}
}
r config set zset-max-ziplist-value $original_max_value
}
} }
source tests/support/cli.tcl source tests/support/cli.tcl
start_server {tags {"wait"}} { start_server {tags {"wait network"}} {
start_server {} { start_server {} {
set slave [srv 0 client] set slave [srv 0 client]
set slave_host [srv 0 host] set slave_host [srv 0 host]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment