Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
72935b9d
Commit
72935b9d
authored
Mar 21, 2023
by
Vitaly Arbuzov
Browse files
Merge branch 'unstable' into dict-split-by-slot
parents
6baf20af
6948daca
Changes
456
Hide whitespace changes
Inline
Side-by-side
tests/unit/client-eviction.tcl
View file @
72935b9d
tags
{
"external:skip"
}
{
tags
{
"external:skip
logreqres:skip
"
}
{
# Get info about a redis client connection:
# name - name of client we want to query
...
...
tests/unit/cluster/misc.tcl
View file @
72935b9d
...
...
@@ -12,5 +12,16 @@ start_cluster 2 2 {tags {external:skip cluster}} {
assert_error
{
ASK*
}
{
R 0 GET FOO
}
R 0 ping
}
{
PONG
}
test
"Coverage: Basic cluster commands"
{
assert_equal
{
OK
}
[
R 0 CLUSTER saveconfig
]
set id
[
R 0 CLUSTER MYID
]
assert_equal
{
0
}
[
R 0 CLUSTER count-failure-reports $id
]
assert_match
"*shard-id*"
[
R 0 CLUSTER slaves $id
]
R 0 flushall
assert_equal
{
OK
}
[
R 0 CLUSTER flushslots
]
}
}
tests/unit/expire.tcl
View file @
72935b9d
...
...
@@ -628,6 +628,9 @@ start_server {tags {"expire"}} {
}
{
-1
}
{
needs:debug
}
test
{
GETEX propagate as to replica as PERSIST, DEL, or nothing
}
{
# In the above tests, many keys with random expiration times are set, flush
# the DBs to avoid active expiry kicking in and messing the replication streams.
r flushall
set repl
[
attach_to_replication_stream
]
r set foo bar EX 100
r getex foo PERSIST
...
...
tests/unit/geo.tcl
View file @
72935b9d
...
...
@@ -222,6 +222,10 @@ start_server {tags {"geo"}} {
r georadius nyc -73.9798091 40.7598464 3 km asc
}
{{
central park n/q/r
}
4545
{
union square
}}
test
{
GEORADIUS_RO simple
(
sorted
)}
{
r georadius_ro nyc -73.9798091 40.7598464 3 km asc
}
{{
central park n/q/r
}
4545
{
union square
}}
test
{
GEOSEARCH simple
(
sorted
)}
{
r geosearch nyc fromlonlat -73.9798091 40.7598464 bybox 6 6 km asc
}
{{
central park n/q/r
}
4545
{
union square
}
{
lic market
}}
...
...
@@ -263,6 +267,12 @@ start_server {tags {"geo"}} {
r georadius nyc -73.9798091 40.7598464 10 km COUNT 3
}
{{
central park n/q/r
}
4545
{
union square
}}
test
{
GEORADIUS with multiple WITH* tokens
}
{
assert_match
{{{
central park n/q/r
}
1791875761332224
{
-73.97334* 40.76480*
}}
{
4545 1791875796750882
{
-73.95641* 40.74809*
}}}
[
r georadius nyc -73.9798091 40.7598464 10 km WITHCOORD WITHHASH COUNT 2
]
assert_match
{{{
central park n/q/r
}
1791875761332224
{
-73.97334* 40.76480*
}}
{
4545 1791875796750882
{
-73.95641* 40.74809*
}}}
[
r georadius nyc -73.9798091 40.7598464 10 km WITHHASH WITHCOORD COUNT 2
]
assert_match
{{{
central park n/q/r
}
0.7750 1791875761332224
{
-73.97334* 40.76480*
}}
{
4545 2.3651 1791875796750882
{
-73.95641* 40.74809*
}}}
[
r georadius nyc -73.9798091 40.7598464 10 km WITHDIST WITHHASH WITHCOORD COUNT 2
]
}
test
{
GEORADIUS with ANY not sorted by default
}
{
r georadius nyc -73.9798091 40.7598464 10 km COUNT 3 ANY
}
{{
wtc one
}
{
union square
}
{
central park n/q/r
}}
...
...
@@ -293,6 +303,10 @@ start_server {tags {"geo"}} {
test
{
GEORADIUSBYMEMBER simple
(
sorted
)}
{
r georadiusbymember nyc
"wtc one"
7 km
}
{{
wtc one
}
{
union square
}
{
central park n/q/r
}
4545
{
lic market
}}
test
{
GEORADIUSBYMEMBER_RO simple
(
sorted
)}
{
r georadiusbymember_ro nyc
"wtc one"
7 km
}
{{
wtc one
}
{
union square
}
{
central park n/q/r
}
4545
{
lic market
}}
test
{
GEORADIUSBYMEMBER search areas contain satisfied points in oblique direction
}
{
r del k1
...
...
tests/unit/introspection.tcl
View file @
72935b9d
...
...
@@ -7,7 +7,7 @@ start_server {tags {"introspection"}} {
test
{
CLIENT LIST
}
{
r client list
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=
2
*
}
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=*
}
test
{
CLIENT LIST with IDs
}
{
set myid
[
r client id
]
...
...
@@ -17,7 +17,7 @@ start_server {tags {"introspection"}} {
test
{
CLIENT INFO
}
{
r client info
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=
2
*
}
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=*
}
test
{
CLIENT KILL with illegal arguments
}
{
assert_error
"ERR wrong number of arguments for 'client|kill' command"
{
r client kill
}
...
...
@@ -94,6 +94,48 @@ start_server {tags {"introspection"}} {
}
}
{}
{
needs:save
}
test
"CLIENT REPLY OFF/ON: disable all commands reply"
{
set rd
[
redis_deferring_client
]
# These replies were silenced.
$rd client reply off
$rd ping pong
$rd ping pong2
$rd client reply on
assert_equal
{
OK
}
[
$rd
read
]
$rd ping pong3
assert_equal
{
pong3
}
[
$rd
read
]
$rd close
}
test
"CLIENT REPLY SKIP: skip the next command reply"
{
set rd
[
redis_deferring_client
]
# The first pong reply was silenced.
$rd client reply skip
$rd ping pong
$rd ping pong2
assert_equal
{
pong2
}
[
$rd
read
]
$rd close
}
test
"CLIENT REPLY ON: unset SKIP flag"
{
set rd
[
redis_deferring_client
]
$rd client reply skip
$rd client reply on
assert_equal
{
OK
}
[
$rd
read
]
;
# OK from CLIENT REPLY ON command
$rd ping
assert_equal
{
PONG
}
[
$rd
read
]
$rd close
}
test
{
MONITOR can log executed commands
}
{
set rd
[
redis_deferring_client
]
$rd monitor
...
...
@@ -138,14 +180,22 @@ start_server {tags {"introspection"}} {
r migrate
[
srv 0 host
]
[
srv 0 port
]
key 9 5000 AUTH2 user password
catch
{
r auth not-real
}
_
catch
{
r auth not-real not-a-password
}
_
catch
{
r hello 2 AUTH not-real not-a-password
}
_
assert_match
{
*
"key"
*
"9"
*
"5000"
*
}
[
$rd
read
]
assert_match
{
*
"key"
*
"9"
*
"5000"
*
"(redacted)"
*
}
[
$rd
read
]
assert_match
{
*
"key"
*
"9"
*
"5000"
*
"(redacted)"
*
"(redacted)"
*
}
[
$rd
read
]
assert_match
{
*
"auth"
*
"(redacted)"
*
}
[
$rd
read
]
assert_match
{
*
"auth"
*
"(redacted)"
*
"(redacted)"
*
}
[
$rd
read
]
assert_match
{
*
"hello"
*
"2"
*
"AUTH"
*
"(redacted)"
*
"(redacted)"
*
}
[
$rd
read
]
foreach resp
{
3 2
}
{
if
{[
lsearch $::denytags
"resp3"
]
>= 0
}
{
if
{
$resp
== 3
}
{
continue
}
}
elseif
{
$::force
_resp3
}
{
if
{
$resp
== 2
}
{
continue
}
}
catch
{
r hello $resp AUTH not-real not-a-password
}
_
assert_match
"*
\"
hello
\"
*
\"
$resp
\"
*
\"
AUTH
\"
*
\"
(redacted)
\"
*
\"
(redacted)
\"
*"
[
$rd
read
]
}
$rd close
}
{
0
}
{
needs:repl
}
...
...
@@ -225,6 +275,27 @@ start_server {tags {"introspection"}} {
r client list
}
{
*name= *
}
test
{
Coverage: Basic CLIENT CACHING
}
{
set rd_redirection
[
redis_deferring_client
]
$rd_redirection client id
set redir_id
[
$rd
_redirection read
]
r CLIENT TRACKING on OPTIN REDIRECT $redir_id
r CLIENT CACHING yes
r CLIENT TRACKING off
}
{
OK
}
test
{
Coverage: Basic CLIENT REPLY
}
{
r CLIENT REPLY on
}
{
OK
}
test
{
Coverage: Basic CLIENT TRACKINGINFO
}
{
r CLIENT TRACKINGINFO
}
{
flags off redirect -1 prefixes
{}}
test
{
Coverage: Basic CLIENT GETREDIR
}
{
r CLIENT GETREDIR
}
{
-1
}
test
{
CLIENT SETNAME does not accept spaces
}
{
catch
{
r client setname
"foo bar"
}
e
set e
...
...
@@ -325,6 +396,8 @@ start_server {tags {"introspection"}} {
logfile
dir
socket-mark-id
req-res-logfile
client-default-resp
}
if
{
!$::tls
}
{
...
...
tests/unit/latency-monitor.tcl
View file @
72935b9d
...
...
@@ -71,6 +71,7 @@ start_server {tags {"latency-monitor needs:latency"}} {
assert
{[
string length
[
r latency histogram blabla set get
]]
> 0
}
}
tags
{
"needs:debug"
}
{
test
{
Test latency events logging
}
{
r debug sleep 0.3
after 1100
...
...
@@ -78,7 +79,7 @@ start_server {tags {"latency-monitor needs:latency"}} {
after 1100
r debug sleep 0.5
assert
{[
r latency history command
]
>= 3
}
}
{}
{
needs:debug
}
}
test
{
LATENCY HISTORY output is ok
}
{
set min 250
...
...
@@ -106,6 +107,18 @@ start_server {tags {"latency-monitor needs:latency"}} {
}
}
test
{
LATENCY GRAPH can output the event graph
}
{
set res
[
r latency graph command
]
assert_match
{
*command*high*low*
}
$res
# These numbers are taken from the
"Test latency events logging"
test.
#
(
debug sleep 0.3
)
and
(
debug sleep 0.5
)
, using range to prevent timing issue.
regexp
"command - high (.*?) ms, low (.*?) ms"
$res -> high low
assert_morethan_equal $high 500
assert_morethan_equal $low 300
}
}
;
# tag
test
{
LATENCY of expire events are correctly collected
}
{
r config set latency-monitor-threshold 20
r flushdb
...
...
@@ -124,6 +137,11 @@ start_server {tags {"latency-monitor needs:latency"}} {
fail
"key wasn't expired"
}
assert_match
{
*expire-cycle*
}
[
r latency latest
]
test
{
LATENCY GRAPH can output the expire event graph
}
{
assert_match
{
*expire-cycle*high*low*
}
[
r latency graph expire-cycle
]
}
r config set latency-monitor-threshold 200
}
...
...
tests/unit/moduleapi/aclcheck.tcl
View file @
72935b9d
...
...
@@ -92,6 +92,45 @@ start_server {tags {"modules acl"}} {
assert
{[
dict get $entry reason
]
eq
{
command
}}
}
test
{
test blocking of Commands outside of OnLoad
}
{
assert_equal
[
r block.commands.outside.onload
]
OK
}
test
{
test users to have access to module commands having acl categories
}
{
r acl SETUSER j1 on >password -@all +@WRITE
r acl SETUSER j2 on >password -@all +@READ
assert_equal
[
r acl DRYRUN j1 aclcheck.module.command.aclcategories.write
]
OK
assert_equal
[
r acl DRYRUN j2 aclcheck.module.command.aclcategories.write.function.read.category
]
OK
assert_equal
[
r acl DRYRUN j2 aclcheck.module.command.aclcategories.read.only.category
]
OK
}
test
{
test existing users to have access to module commands loaded on runtime
}
{
assert_equal
[
r module unload aclcheck
]
OK
r acl SETUSER j3 on >password -@all +@WRITE
assert_equal
[
r module load $testmodule
]
OK
assert_equal
[
r acl DRYRUN j3 aclcheck.module.command.aclcategories.write
]
OK
}
test
{
test existing users without permissions, do not have access to module commands loaded on runtime.
}
{
assert_equal
[
r module unload aclcheck
]
OK
r acl SETUSER j4 on >password -@all +@READ
r acl SETUSER j5 on >password -@all +@WRITE
assert_equal
[
r module load $testmodule
]
OK
catch
{
r acl DRYRUN j4 aclcheck.module.command.aclcategories.write
}
e
assert_equal
{
User j4 has no permissions to run the 'aclcheck.module.command.aclcategories.write' command
}
$e
catch
{
r acl DRYRUN j5 aclcheck.module.command.aclcategories.write.function.read.category
}
e
assert_equal
{
User j5 has no permissions to run the 'aclcheck.module.command.aclcategories.write.function.read.category' command
}
$e
}
test
{
test users without permissions, do not have access to module commands.
}
{
r acl SETUSER j6 on >password -@all +@READ
catch
{
r acl DRYRUN j6 aclcheck.module.command.aclcategories.write
}
e
assert_equal
{
User j6 has no permissions to run the 'aclcheck.module.command.aclcategories.write' command
}
$e
r acl SETUSER j7 on >password -@all +@WRITE
catch
{
r acl DRYRUN j7 aclcheck.module.command.aclcategories.write.function.read.category
}
e
assert_equal
{
User j7 has no permissions to run the 'aclcheck.module.command.aclcategories.write.function.read.category' command
}
$e
}
test
"Unload the module - aclcheck"
{
assert_equal
{
OK
}
[
r module unload aclcheck
]
}
...
...
tests/unit/moduleapi/async_rm_call.tcl
0 → 100644
View file @
72935b9d
set testmodule
[
file normalize tests/modules/blockedclient.so
]
set testmodule2
[
file normalize tests/modules/postnotifications.so
]
set testmodule3
[
file normalize tests/modules/blockonkeys.so
]
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
test
{
Locked GIL acquisition from async RM_Call
}
{
assert_equal
{
OK
}
[
r do_rm_call_async acquire_gil
]
}
test
"Blpop on async RM_Call fire and forget"
{
assert_equal
{
Blocked
}
[
r do_rm_call_fire_and_forget blpop l 0
]
r lpush l a
assert_equal
{
0
}
[
r llen l
]
}
foreach cmd
{
do_rm_call_async do_rm_call_async_script_mode
}
{
test
"Blpop on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd blpop l 0
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
l a
}
wait_for_blocked_clients_count 0
}
test
"Brpop on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd brpop l 0
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
l a
}
wait_for_blocked_clients_count 0
}
test
"Brpoplpush on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd brpoplpush l1 l2 0
wait_for_blocked_clients_count 1
r lpush l1 a
assert_equal
[
$rd
read
]
{
a
}
wait_for_blocked_clients_count 0
r lpop l2
}
{
a
}
test
"Blmove on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd blmove l1 l2 LEFT LEFT 0
wait_for_blocked_clients_count 1
r lpush l1 a
assert_equal
[
$rd
read
]
{
a
}
wait_for_blocked_clients_count 0
r lpop l2
}
{
a
}
test
"Bzpopmin on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd bzpopmin s 0
wait_for_blocked_clients_count 1
r zadd s 10 foo
assert_equal
[
$rd
read
]
{
s foo 10
}
wait_for_blocked_clients_count 0
}
test
"Bzpopmax on async RM_Call using
$cmd
"
{
set rd
[
redis_deferring_client
]
$rd $cmd bzpopmax s 0
wait_for_blocked_clients_count 1
r zadd s 10 foo
assert_equal
[
$rd
read
]
{
s foo 10
}
wait_for_blocked_clients_count 0
}
}
test
{
Nested async RM_Call
}
{
set rd
[
redis_deferring_client
]
$rd do_rm_call_async do_rm_call_async do_rm_call_async do_rm_call_async blpop l 0
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
l a
}
wait_for_blocked_clients_count 0
}
test
{
Test multiple async RM_Call waiting on the same event
}
{
set rd1
[
redis_deferring_client
]
set rd2
[
redis_deferring_client
]
$rd1 do_rm_call_async do_rm_call_async do_rm_call_async do_rm_call_async blpop l 0
$rd2 do_rm_call_async do_rm_call_async do_rm_call_async do_rm_call_async blpop l 0
wait_for_blocked_clients_count 2
r lpush l element element
assert_equal
[
$rd1
read
]
{
l element
}
assert_equal
[
$rd2
read
]
{
l element
}
wait_for_blocked_clients_count 0
}
test
{
async RM_Call calls RM_Call
}
{
assert_equal
{
PONG
}
[
r do_rm_call_async do_rm_call ping
]
}
test
{
async RM_Call calls background RM_Call calls RM_Call
}
{
assert_equal
{
PONG
}
[
r do_rm_call_async do_bg_rm_call do_rm_call ping
]
}
test
{
async RM_Call calls background RM_Call calls RM_Call calls async RM_Call
}
{
assert_equal
{
PONG
}
[
r do_rm_call_async do_bg_rm_call do_rm_call do_rm_call_async ping
]
}
test
{
async RM_Call inside async RM_Call callback
}
{
set rd
[
redis_deferring_client
]
$rd wait_and_do_rm_call blpop l 0
wait_for_blocked_clients_count 1
start_server
{}
{
test
"Connect a replica to the master instance"
{
r slaveof
[
srv -1 host
]
[
srv -1 port
]
wait_for_condition 50 100
{
[
s role
]
eq
{
slave
}
&&
[
string match
{
*master_link_status:up*
}
[
r info replication
]]
}
else
{
fail
"Can't turn the instance into a replica"
}
}
assert_equal
{
1
}
[
r -1 lpush l a
]
assert_equal
[
$rd
read
]
{
l a
}
}
wait_for_blocked_clients_count 0
}
test
{
Become replica while having async RM_Call running
}
{
r flushall
set rd
[
redis_deferring_client
]
$rd do_rm_call_async blpop l 0
wait_for_blocked_clients_count 1
#become a replica of a not existing redis
r replicaof localhost 30000
catch
{[
$rd
read
]}
e
assert_match
{
UNBLOCKED force unblock from blocking operation*
}
$e
wait_for_blocked_clients_count 0
r replicaof no one
r lpush l 1
# make sure the async rm_call was aborted
assert_equal
[
r llen l
]
{
1
}
}
test
{
Pipeline with blocking RM_Call
}
{
r flushall
set rd
[
redis_deferring_client
]
set buf
""
append buf
"do_rm_call_async blpop l 0
\r\n
"
append buf
"ping
\r\n
"
$rd write $buf
$rd flush
wait_for_blocked_clients_count 1
# release the blocked client
r lpush l 1
assert_equal
[
$rd
read
]
{
l 1
}
assert_equal
[
$rd
read
]
{
PONG
}
wait_for_blocked_clients_count 0
}
test
{
blocking RM_Call abort
}
{
r flushall
set rd
[
redis_deferring_client
]
$rd client id
set client_id
[
$rd
read
]
$rd do_rm_call_async blpop l 0
wait_for_blocked_clients_count 1
r client kill ID $client_id
assert_error
{
*error reading reply*
}
{
$rd
read
}
wait_for_blocked_clients_count 0
r lpush l 1
# make sure the async rm_call was aborted
assert_equal
[
r llen l
]
{
1
}
}
}
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
test
{
Test basic replication stream on unblock handler
}
{
r flushall
set repl
[
attach_to_replication_stream
]
set rd
[
redis_deferring_client
]
$rd do_rm_call_async blpop l 0
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
l a
}
assert_replication_stream $repl
{
{
select *
}
{
lpush l a
}
{
lpop l
}
}
close_replication_stream $repl
wait_for_blocked_clients_count 0
}
test
{
Test unblock handler are executed as a unit
}
{
r flushall
set repl
[
attach_to_replication_stream
]
set rd
[
redis_deferring_client
]
$rd blpop_and_set_multiple_keys l x 1 y 2
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
OK
}
assert_replication_stream $repl
{
{
select *
}
{
lpush l a
}
{
multi
}
{
lpop l
}
{
set x 1
}
{
set y 2
}
{
exec
}
}
close_replication_stream $repl
wait_for_blocked_clients_count 0
}
test
{
Test no propagation of blocking command
}
{
r flushall
set repl
[
attach_to_replication_stream
]
set rd
[
redis_deferring_client
]
$rd do_rm_call_async_no_replicate blpop l 0
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
l a
}
# make sure the lpop are not replicated
r set x 1
assert_replication_stream $repl
{
{
select *
}
{
lpush l a
}
{
set x 1
}
}
close_replication_stream $repl
wait_for_blocked_clients_count 0
}
}
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
r module load $testmodule2
test
{
Test unblock handler are executed as a unit with key space notifications
}
{
r flushall
set repl
[
attach_to_replication_stream
]
set rd
[
redis_deferring_client
]
$rd blpop_and_set_multiple_keys l string_foo 1 string_bar 2
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
OK
}
assert_replication_stream $repl
{
{
select *
}
{
lpush l a
}
{
multi
}
{
lpop l
}
{
set string_foo 1
}
{
set string_bar 2
}
{
incr string_changed
{
string_foo
}}
{
incr string_changed
{
string_bar
}}
{
incr string_total
}
{
incr string_total
}
{
exec
}
}
close_replication_stream $repl
wait_for_blocked_clients_count 0
}
test
{
Test unblock handler are executed as a unit with lazy expire
}
{
r flushall
r DEBUG SET-ACTIVE-EXPIRE 0
set repl
[
attach_to_replication_stream
]
set rd
[
redis_deferring_client
]
$rd blpop_and_set_multiple_keys l string_foo 1 string_bar 2
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
OK
}
# set expiration on string_foo
r pexpire string_foo 1
after 10
# now the key should have been expired
$rd blpop_and_set_multiple_keys l string_foo 1 string_bar 2
wait_for_blocked_clients_count 1
r lpush l a
assert_equal
[
$rd
read
]
{
OK
}
assert_replication_stream $repl
{
{
select *
}
{
lpush l a
}
{
multi
}
{
lpop l
}
{
set string_foo 1
}
{
set string_bar 2
}
{
incr string_changed
{
string_foo
}}
{
incr string_changed
{
string_bar
}}
{
incr string_total
}
{
incr string_total
}
{
exec
}
{
pexpireat string_foo *
}
{
lpush l a
}
{
multi
}
{
lpop l
}
{
del string_foo
}
{
set string_foo 1
}
{
set string_bar 2
}
{
incr expired
}
{
incr string_changed
{
string_foo
}}
{
incr string_changed
{
string_bar
}}
{
incr string_total
}
{
incr string_total
}
{
exec
}
}
close_replication_stream $repl
r DEBUG SET-ACTIVE-EXPIRE 1
}
wait_for_blocked_clients_count 0
}
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
r module load $testmodule3
test
{
Test unblock handler on module blocked on keys
}
{
set rd
[
redis_deferring_client
]
r fsl.push l 1
$rd do_rm_call_async FSL.BPOPGT l 3 0
wait_for_blocked_clients_count 1
r fsl.push l 2
r fsl.push l 3
r fsl.push l 4
assert_equal
[
$rd
read
]
{
4
}
wait_for_blocked_clients_count 0
}
}
\ No newline at end of file
tests/unit/moduleapi/basics.tcl
View file @
72935b9d
...
...
@@ -21,12 +21,17 @@ start_server {tags {"modules"}} {
}
test
{
test get resp
}
{
r hello 2
set reply
[
r test.getresp
]
assert_equal $reply 2
r hello 3
set reply
[
r test.getresp
]
assert_equal $reply 3
foreach resp
{
3 2
}
{
if
{[
lsearch $::denytags
"resp3"
]
>= 0
}
{
if
{
$resp
== 3
}
{
continue
}
}
elseif
{
$::force
_resp3
}
{
if
{
$resp
== 2
}
{
continue
}
}
r hello $resp
set reply
[
r test.getresp
]
assert_equal $reply $resp
r hello 2
}
}
test
"Unload the module - test"
{
...
...
tests/unit/moduleapi/blockedclient.tcl
View file @
72935b9d
...
...
@@ -91,6 +91,11 @@ start_server {tags {"modules"}} {
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
]
...
...
@@ -100,6 +105,7 @@ start_server {tags {"modules"}} {
assert_equal $ret
"#t"
}
r readraw 0
r hello 2
}
}
...
...
tests/unit/moduleapi/blockonkeys.tcl
View file @
72935b9d
...
...
@@ -286,4 +286,21 @@ start_server {tags {"modules"}} {
assert_equal
{
gg ff ee dd cc
}
[
$rd
read
]
$rd close
}
test
{
Module explicit unblock when blocked on keys
}
{
r del k
r set somekey someval
# Module client blocks to pop 5 elements from list
set rd
[
redis_deferring_client
]
$rd blockonkeys.blpopn_or_unblock k 5 0
wait_for_blocked_clients_count 1
# will now cause the module to trigger pop but instead will unblock the client from the reply_callback
r lpush k dd
# we should still get unblocked as the command should not reprocess
wait_for_blocked_clients_count 0
assert_equal
{
Action aborted
}
[
$rd
read
]
$rd get somekey
assert_equal
{
someval
}
[
$rd
read
]
$rd close
}
}
tests/unit/moduleapi/cmdintrospection.tcl
View file @
72935b9d
...
...
@@ -37,6 +37,9 @@ start_server {tags {"modules"}} {
dict unset redis_reply group
dict unset module_reply group
dict unset module_reply module
if
{
$::log
_req_res
}
{
dict unset redis_reply reply_schema
}
assert_equal $redis_reply $module_reply
}
...
...
tests/unit/moduleapi/commandfilter.tcl
View file @
72935b9d
...
...
@@ -116,3 +116,28 @@ test {RM_CommandFilterArgInsert and script argv caching} {
}
}
# previously, there was a bug that command filters would be rerun
(
which would cause args to swap back
)
# this test is meant to protect against that bug
test
{
Blocking Commands don't run through command filter when reprocessed
}
{
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule log-key 0
r del list1
{
t
}
r del list2
{
t
}
r lpush list2
{
t
}
a b c d e
set rd
[
redis_deferring_client
]
# we're asking to pop from the left, but the command filter swaps the two arguments,
# if it didn't swap it, we would end up with e d c b a 5
(
5 being the left most of the following lpush
)
# but since we swap the arguments, we end up with 1 e d c b a
(
1 being the right most of it
)
.
# if the command filter would run again on unblock, they would be swapped back.
$rd blmove list1
{
t
}
list2
{
t
}
left right 0
wait_for_blocked_client
r lpush list1
{
t
}
1 2 3 4 5
# validate that we moved the correct element with the swapped args
assert_equal
[
$rd
read
]
1
# validate that we moved the correct elements to the correct side of the list
assert_equal
[
r lpop list2
{
t
}]
1
}
}
tests/unit/moduleapi/datatype.tcl
View file @
72935b9d
...
...
@@ -8,6 +8,10 @@ start_server {tags {"modules"}} {
assert
{[
r datatype.get dtkey
]
eq
{
100 stringval
}}
}
test
{
test blocking of datatype creation outside of OnLoad
}
{
assert_equal
[
r block.create.datatype.outside.onload
]
OK
}
test
{
DataType: RM_SaveDataTypeToString
()
, RM_LoadDataTypeFromStringEncver
()
work
}
{
r datatype.set dtkey -1111 MyString
set encoded
[
r datatype.dump dtkey
]
...
...
tests/unit/moduleapi/moduleauth.tcl
0 → 100644
View file @
72935b9d
set testmodule
[
file normalize tests/modules/auth.so
]
set testmoduletwo
[
file normalize tests/modules/moduleauthtwo.so
]
set miscmodule
[
file normalize tests/modules/misc.so
]
proc cmdstat
{
cmd
}
{
return
[
cmdrstat $cmd r
]
}
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
r module load $testmoduletwo
set hello2_response
[
r HELLO 2
]
set hello3_response
[
r HELLO 3
]
test
{
test registering module auth callbacks
}
{
assert_equal
{
OK
}
[
r testmoduleone.rm_register_blocking_auth_cb
]
assert_equal
{
OK
}
[
r testmoduletwo.rm_register_auth_cb
]
assert_equal
{
OK
}
[
r testmoduleone.rm_register_auth_cb
]
}
test
{
test module AUTH for non existing / disabled users
}
{
r config resetstat
# Validate that an error is thrown for non existing users.
assert_error
{
*WRONGPASS*
}
{
r AUTH foo pwd
}
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
# Validate that an error is thrown for disabled users.
r acl setuser foo >pwd off ~* &* +@all
assert_error
{
*WRONGPASS*
}
{
r AUTH foo pwd
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=2
}
[
cmdstat auth
]
}
test
{
test non blocking module AUTH
}
{
r config resetstat
# Test for a fixed password user
r acl setuser foo >pwd on ~* &* +@all
assert_equal
{
OK
}
[
r AUTH foo allow
]
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo deny
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
assert_error
{
*WRONGPASS*
}
{
r AUTH foo nomatch
}
assert_match
{
*calls=3,*,rejected_calls=0,failed_calls=2
}
[
cmdstat auth
]
assert_equal
{
OK
}
[
r AUTH foo pwd
]
# Test for No Pass user
r acl setuser foo on ~* &* +@all nopass
assert_equal
{
OK
}
[
r AUTH foo allow
]
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo deny
}
assert_match
{
*calls=6,*,rejected_calls=0,failed_calls=3
}
[
cmdstat auth
]
assert_equal
{
OK
}
[
r AUTH foo nomatch
]
# Validate that the Module added an ACL Log entry.
set entry
[
lindex
[
r ACL LOG
]
0
]
assert
{[
dict get $entry username
]
eq
{
foo
}}
assert
{[
dict get $entry context
]
eq
{
module
}}
assert
{[
dict get $entry reason
]
eq
{
auth
}}
assert
{[
dict get $entry object
]
eq
{
Module Auth
}}
assert_match
{
*cmd=auth*
}
[
dict get $entry client-info
]
r ACL LOG RESET
}
test
{
test non blocking module HELLO AUTH
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# Validate proto 2 and 3 in case of success
assert_equal $hello2_response
[
r HELLO 2 AUTH foo pwd
]
assert_equal $hello2_response
[
r HELLO 2 AUTH foo allow
]
assert_equal $hello3_response
[
r HELLO 3 AUTH foo pwd
]
assert_equal $hello3_response
[
r HELLO 3 AUTH foo allow
]
# Validate denying AUTH for the HELLO cmd
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 2 AUTH foo deny
}
assert_match
{
*calls=5,*,rejected_calls=0,failed_calls=1
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 2 AUTH foo nomatch
}
assert_match
{
*calls=6,*,rejected_calls=0,failed_calls=2
}
[
cmdstat hello
]
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 3 AUTH foo deny
}
assert_match
{
*calls=7,*,rejected_calls=0,failed_calls=3
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 3 AUTH foo nomatch
}
assert_match
{
*calls=8,*,rejected_calls=0,failed_calls=4
}
[
cmdstat hello
]
# Validate that the Module added an ACL Log entry.
set entry
[
lindex
[
r ACL LOG
]
1
]
assert
{[
dict get $entry username
]
eq
{
foo
}}
assert
{[
dict get $entry context
]
eq
{
module
}}
assert
{[
dict get $entry reason
]
eq
{
auth
}}
assert
{[
dict get $entry object
]
eq
{
Module Auth
}}
assert_match
{
*cmd=hello*
}
[
dict get $entry client-info
]
r ACL LOG RESET
}
test
{
test non blocking module HELLO AUTH SETNAME
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# Validate clientname is set on success
assert_equal $hello2_response
[
r HELLO 2 AUTH foo pwd setname client1
]
assert
{[
r client getname
]
eq
{
client1
}}
assert_equal $hello2_response
[
r HELLO 2 AUTH foo allow setname client2
]
assert
{[
r client getname
]
eq
{
client2
}}
# Validate clientname is not updated on failure
r client setname client0
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 2 AUTH foo deny setname client1
}
assert
{[
r client getname
]
eq
{
client0
}}
assert_match
{
*calls=3,*,rejected_calls=0,failed_calls=1
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 2 AUTH foo nomatch setname client2
}
assert
{[
r client getname
]
eq
{
client0
}}
assert_match
{
*calls=4,*,rejected_calls=0,failed_calls=2
}
[
cmdstat hello
]
}
test
{
test blocking module AUTH
}
{
r config resetstat
# Test for a fixed password user
r acl setuser foo >pwd on ~* &* +@all
assert_equal
{
OK
}
[
r AUTH foo block_allow
]
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo block_deny
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
assert_error
{
*WRONGPASS*
}
{
r AUTH foo nomatch
}
assert_match
{
*calls=3,*,rejected_calls=0,failed_calls=2
}
[
cmdstat auth
]
assert_equal
{
OK
}
[
r AUTH foo pwd
]
# Test for No Pass user
r acl setuser foo on ~* &* +@all nopass
assert_equal
{
OK
}
[
r AUTH foo block_allow
]
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo block_deny
}
assert_match
{
*calls=6,*,rejected_calls=0,failed_calls=3
}
[
cmdstat auth
]
assert_equal
{
OK
}
[
r AUTH foo nomatch
]
# Validate that every Blocking AUTH command took at least 500000 usec.
set stats
[
cmdstat auth
]
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 500000
}
# Validate that the Module added an ACL Log entry.
set entry
[
lindex
[
r ACL LOG
]
0
]
assert
{[
dict get $entry username
]
eq
{
foo
}}
assert
{[
dict get $entry context
]
eq
{
module
}}
assert
{[
dict get $entry reason
]
eq
{
auth
}}
assert
{[
dict get $entry object
]
eq
{
Module Auth
}}
assert_match
{
*cmd=auth*
}
[
dict get $entry client-info
]
r ACL LOG RESET
}
test
{
test blocking module HELLO AUTH
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# validate proto 2 and 3 in case of success
assert_equal $hello2_response
[
r HELLO 2 AUTH foo pwd
]
assert_equal $hello2_response
[
r HELLO 2 AUTH foo block_allow
]
assert_equal $hello3_response
[
r HELLO 3 AUTH foo pwd
]
assert_equal $hello3_response
[
r HELLO 3 AUTH foo block_allow
]
# validate denying AUTH for the HELLO cmd
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 2 AUTH foo block_deny
}
assert_match
{
*calls=5,*,rejected_calls=0,failed_calls=1
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 2 AUTH foo nomatch
}
assert_match
{
*calls=6,*,rejected_calls=0,failed_calls=2
}
[
cmdstat hello
]
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 3 AUTH foo block_deny
}
assert_match
{
*calls=7,*,rejected_calls=0,failed_calls=3
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 3 AUTH foo nomatch
}
assert_match
{
*calls=8,*,rejected_calls=0,failed_calls=4
}
[
cmdstat hello
]
# Validate that every HELLO AUTH command took at least 500000 usec.
set stats
[
cmdstat hello
]
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 500000
}
# Validate that the Module added an ACL Log entry.
set entry
[
lindex
[
r ACL LOG
]
1
]
assert
{[
dict get $entry username
]
eq
{
foo
}}
assert
{[
dict get $entry context
]
eq
{
module
}}
assert
{[
dict get $entry reason
]
eq
{
auth
}}
assert
{[
dict get $entry object
]
eq
{
Module Auth
}}
assert_match
{
*cmd=hello*
}
[
dict get $entry client-info
]
r ACL LOG RESET
}
test
{
test blocking module HELLO AUTH SETNAME
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# Validate clientname is set on success
assert_equal $hello2_response
[
r HELLO 2 AUTH foo pwd setname client1
]
assert
{[
r client getname
]
eq
{
client1
}}
assert_equal $hello2_response
[
r HELLO 2 AUTH foo block_allow setname client2
]
assert
{[
r client getname
]
eq
{
client2
}}
# Validate clientname is not updated on failure
r client setname client0
assert_error
{
*Auth denied by Misc Module*
}
{
r HELLO 2 AUTH foo block_deny setname client1
}
assert
{[
r client getname
]
eq
{
client0
}}
assert_match
{
*calls=3,*,rejected_calls=0,failed_calls=1
}
[
cmdstat hello
]
assert_error
{
*WRONGPASS*
}
{
r HELLO 2 AUTH foo nomatch setname client2
}
assert
{[
r client getname
]
eq
{
client0
}}
assert_match
{
*calls=4,*,rejected_calls=0,failed_calls=2
}
[
cmdstat hello
]
# Validate that every HELLO AUTH SETNAME command took at least 500000 usec.
set stats
[
cmdstat hello
]
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 500000
}
}
test
{
test AUTH after registering multiple module auth callbacks
}
{
r config resetstat
# Register two more callbacks from the same module.
assert_equal
{
OK
}
[
r testmoduleone.rm_register_blocking_auth_cb
]
assert_equal
{
OK
}
[
r testmoduleone.rm_register_auth_cb
]
# Register another module auth callback from the second module.
assert_equal
{
OK
}
[
r testmoduletwo.rm_register_auth_cb
]
r acl setuser foo >pwd on ~* &* +@all
# Case 1 - Non Blocking Success
assert_equal
{
OK
}
[
r AUTH foo allow
]
# Case 2 - Non Blocking Deny
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo deny
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
r config resetstat
# Case 3 - Blocking Success
assert_equal
{
OK
}
[
r AUTH foo block_allow
]
# Case 4 - Blocking Deny
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo block_deny
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
# Validate that every Blocking AUTH command took at least 500000 usec.
set stats
[
cmdstat auth
]
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 500000
}
r config resetstat
# Case 5 - Non Blocking Success via the second module.
assert_equal
{
OK
}
[
r AUTH foo allow_two
]
# Case 6 - Non Blocking Deny via the second module.
assert_error
{
*Auth denied by Misc Module*
}
{
r AUTH foo deny_two
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
r config resetstat
# Case 7 - All four auth callbacks
"Skip"
by not explicitly allowing or denying.
assert_error
{
*WRONGPASS*
}
{
r AUTH foo nomatch
}
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
assert_equal
{
OK
}
[
r AUTH foo pwd
]
# Because we had to attempt all 4 callbacks, validate that the AUTH command took at least
# 1000000 usec
(
each blocking callback takes 500000 usec
)
.
set stats
[
cmdstat auth
]
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 1000000
}
}
test
{
module auth during blocking module auth
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
set rd
[
redis_deferring_client
]
set rd_two
[
redis_deferring_client
]
# Attempt blocking module auth. While this ongoing, attempt non blocking module auth from
# moduleone/moduletwo and start another blocking module auth from another deferring client.
$rd AUTH foo block_allow
wait_for_blocked_clients_count 1
assert_equal
{
OK
}
[
r AUTH foo allow
]
assert_equal
{
OK
}
[
r AUTH foo allow_two
]
# Validate that the non blocking module auth cmds finished before any blocking module auth.
set info_clients
[
r info clients
]
assert_match
"*blocked_clients:1*"
$info_clients
$rd_two AUTH foo block_allow
# Validate that all of the AUTH commands succeeded.
wait_for_blocked_clients_count 0 500 10
$rd flush
assert_equal
[
$rd
read
]
"OK"
$rd_two flush
assert_equal
[
$rd
_two read
]
"OK"
assert_match
{
*calls=4,*,rejected_calls=0,failed_calls=0
}
[
cmdstat auth
]
}
test
{
module auth inside MULTI EXEC
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# Validate that non blocking module auth inside MULTI succeeds.
r multi
r AUTH foo allow
assert_equal
{
OK
}
[
r exec
]
# Validate that blocking module auth inside MULTI throws an err.
r multi
r AUTH foo block_allow
assert_error
{
*ERR Blocking module command called from transaction*
}
{
r exec
}
assert_match
{
*calls=2,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
}
test
{
Disabling Redis User during blocking module auth
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
set rd
[
redis_deferring_client
]
# Attempt blocking module auth and disable the Redis user while module auth is in progress.
$rd AUTH foo pwd
wait_for_blocked_clients_count 1
r acl setuser foo >pwd off ~* &* +@all
# Validate that module auth failed.
wait_for_blocked_clients_count 0 500 10
$rd flush
assert_error
{
*WRONGPASS*
}
{
$rd read
}
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
}
test
{
Killing a client in the middle of blocking module auth
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
set rd
[
redis_deferring_client
]
$rd client id
set cid
[
$rd
read
]
# Attempt blocking module auth command on client `cid` and kill the client while module auth
# is in progress.
$rd AUTH foo pwd
wait_for_blocked_clients_count 1
r client kill id $cid
# Validate that the blocked client count goes to 0 and no AUTH command is tracked.
wait_for_blocked_clients_count 0 500 10
$rd flush
assert_error
{
*I/O error reading reply*
}
{
$rd read
}
assert_match
{}
[
cmdstat auth
]
}
test
{
test RM_AbortBlock Module API during blocking module auth
}
{
r config resetstat
r acl setuser foo >pwd on ~* &* +@all
# Attempt module auth. With the
"block_abort"
as the password, the
"testacl.so"
module
# blocks the client and uses the RM_AbortBlock API. This should result in module auth
# failing and the client being unblocked with the default AUTH err message.
assert_error
{
*WRONGPASS*
}
{
r AUTH foo block_abort
}
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=1
}
[
cmdstat auth
]
}
test
{
test RM_RegisterAuthCallback Module API during blocking module auth
}
{
r config resetstat
r acl setuser foo >defaultpwd on ~* &* +@all
set rd
[
redis_deferring_client
]
# Start the module auth attempt with the standard Redis auth password for the user. This
# will result in all module auth cbs attempted and then standard Redis auth will be tried.
$rd AUTH foo defaultpwd
wait_for_blocked_clients_count 1
# Validate that we allow modules to register module auth cbs while module auth is already
# in progress.
assert_equal
{
OK
}
[
r testmoduleone.rm_register_blocking_auth_cb
]
assert_equal
{
OK
}
[
r testmoduletwo.rm_register_auth_cb
]
# Validate that blocking module auth succeeds.
wait_for_blocked_clients_count 0 500 10
$rd flush
assert_equal
[
$rd
read
]
"OK"
set stats
[
cmdstat auth
]
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=0
}
$stats
# Validate that even the new blocking module auth cb which was registered in the middle of
# blocking module auth is attempted - making it take twice the duration
(
2x 500000 us
)
.
regexp
"usec_per_call=(
\[
0-9]{1,})
\.
*,"
$stats all usec_per_call
assert
{
$usec
_per_call >= 1000000
}
}
test
{
Module unload during blocking module auth
}
{
r config resetstat
r module load $miscmodule
set rd
[
redis_deferring_client
]
r acl setuser foo >pwd on ~* &* +@all
# Start a blocking module auth attempt.
$rd AUTH foo block_allow
wait_for_blocked_clients_count 1
# moduleone and moduletwo have module auth cbs registered. Because blocking module auth is
# ongoing, they cannot be unloaded.
catch
{
r module unload testacl
}
e
assert_match
{
*the module has blocked clients*
}
$e
# The moduleauthtwo module can be unregistered because no client is blocked on it.
assert_equal
"OK"
[
r module unload moduleauthtwo
]
# The misc module does not have module auth cbs registered, so it can be unloaded even when
# blocking module auth is ongoing.
assert_equal
"OK"
[
r module unload misc
]
# Validate that blocking module auth succeeds.
wait_for_blocked_clients_count 0 500 10
$rd flush
assert_equal
[
$rd
read
]
"OK"
assert_match
{
*calls=1,*,rejected_calls=0,failed_calls=0
}
[
cmdstat auth
]
# Validate that unloading the moduleauthtwo module does not unregister module auth cbs of
# of the testacl module. Module based auth should succeed.
assert_equal
{
OK
}
[
r AUTH foo allow
]
# Validate that the testacl module can be unloaded since blocking module auth is done.
r module unload testacl
# Validate that since all module auth cbs are unregistered, module auth attempts fail.
assert_error
{
*WRONGPASS*
}
{
r AUTH foo block_allow
}
assert_error
{
*WRONGPASS*
}
{
r AUTH foo allow_two
}
assert_error
{
*WRONGPASS*
}
{
r AUTH foo allow
}
assert_match
{
*calls=5,*,rejected_calls=0,failed_calls=3
}
[
cmdstat auth
]
}
}
tests/unit/moduleapi/moduleconfigs.tcl
View file @
72935b9d
...
...
@@ -77,6 +77,10 @@ start_server {tags {"modules"}} {
assert_match
{
*must be one of the following*
}
$e
}
test
{
test blocking of config registration and load outside of OnLoad
}
{
assert_equal
[
r block.register.configs.outside.onload
]
OK
}
test
{
Unload removes module configs
}
{
r module unload moduleconfigs
assert_equal
[
r config get moduleconfigs.*
]
""
...
...
tests/unit/moduleapi/reply.tcl
View file @
72935b9d
...
...
@@ -5,6 +5,11 @@ start_server {tags {"modules"}} {
# test all with hello 2/3
for
{
set proto 2
}
{
$proto
<= 3
}
{
incr proto
}
{
if
{[
lsearch $::denytags
"resp3"
]
>= 0
}
{
if
{
$proto
== 3
}
{
continue
}
}
elseif
{
$::force
_resp3
}
{
if
{
$proto
== 2
}
{
continue
}
}
r hello $proto
test
"RESP
$proto:
RM_ReplyWithString: an string reply"
{
...
...
@@ -120,6 +125,8 @@ start_server {tags {"modules"}} {
catch
{
r rw.error
}
e
assert_match
"An error"
$e
}
r hello 2
}
test
"Unload the module - replywith"
{
...
...
tests/unit/networking.tcl
View file @
72935b9d
...
...
@@ -121,7 +121,14 @@ start_server {config "minimal.conf" tags {"external:skip"}} {
# Make sure bind parameter is as expected and server handles binding
# accordingly.
assert_equal
{
bind
{}}
[
rediscli_exec 0 config get bind
]
#
(
it seems that rediscli_exec behaves differently in RESP3, possibly
# because CONFIG GET returns a dict instead of a list so redis-cli emits
# it in a single line
)
if
{
$::force
_resp3
}
{
assert_equal
{{
bind
}}
[
rediscli_exec 0 config get bind
]
}
else
{
assert_equal
{
bind
{}}
[
rediscli_exec 0 config get bind
]
}
catch
{
reconnect 0
}
err
assert_match
{
*connection refused*
}
$err
...
...
tests/unit/obuf-limits.tcl
View file @
72935b9d
start_server
{
tags
{
"obuf-limits external:skip"
}}
{
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
]
...
...
tests/unit/other.tcl
View file @
72935b9d
...
...
@@ -6,6 +6,30 @@ start_server {tags {"other"}} {
}
{
ok
}
}
test
{
Coverage: HELP commands
}
{
assert_match
"*OBJECT <subcommand> *"
[
r OBJECT HELP
]
assert_match
"*MEMORY <subcommand> *"
[
r MEMORY HELP
]
assert_match
"*PUBSUB <subcommand> *"
[
r PUBSUB HELP
]
assert_match
"*SLOWLOG <subcommand> *"
[
r SLOWLOG HELP
]
assert_match
"*CLIENT <subcommand> *"
[
r CLIENT HELP
]
assert_match
"*COMMAND <subcommand> *"
[
r COMMAND HELP
]
assert_match
"*CONFIG <subcommand> *"
[
r CONFIG HELP
]
assert_match
"*FUNCTION <subcommand> *"
[
r FUNCTION HELP
]
assert_match
"*MODULE <subcommand> *"
[
r MODULE HELP
]
}
test
{
Coverage: MEMORY MALLOC-STATS
}
{
if
{[
string match
{
*jemalloc*
}
[
s mem_allocator
]]}
{
assert_match
"*jemalloc*"
[
r memory malloc-stats
]
}
}
test
{
Coverage: MEMORY PURGE
}
{
if
{[
string match
{
*jemalloc*
}
[
s mem_allocator
]]}
{
assert_equal
{
OK
}
[
r memory purge
]
}
}
test
{
SAVE - make sure there are all the types as values
}
{
# Wait for a background saving in progress to terminate
waitForBgsave r
...
...
Prev
1
…
18
19
20
21
22
23
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment