summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/tests/unit/moduleapi/misc.tcl
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 22:52:54 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 22:52:54 +0100
commitdcacc00e3750300617ba6e16eb346713f91a783a (patch)
tree38e2d4fb5ed9d119711d4295c6eda4b014af73fd /examples/redis-unstable/tests/unit/moduleapi/misc.tcl
parent58dac10aeb8f5a041c46bddbeaf4c7966a99b998 (diff)
downloadcrep-dcacc00e3750300617ba6e16eb346713f91a783a.tar.gz
Remove testing data
Diffstat (limited to 'examples/redis-unstable/tests/unit/moduleapi/misc.tcl')
-rw-r--r--examples/redis-unstable/tests/unit/moduleapi/misc.tcl617
1 files changed, 0 insertions, 617 deletions
diff --git a/examples/redis-unstable/tests/unit/moduleapi/misc.tcl b/examples/redis-unstable/tests/unit/moduleapi/misc.tcl
deleted file mode 100644
index b51fffb..0000000
--- a/examples/redis-unstable/tests/unit/moduleapi/misc.tcl
+++ /dev/null
@@ -1,617 +0,0 @@
-set testmodule [file normalize tests/modules/misc.so]
-
-start_server {overrides {save {900 1}} tags {"modules external:skip"}} {
- r module load $testmodule
-
- test {test RM_Call} {
- set info [r test.call_info commandstats]
- # cmdstat is not in a default section, so we also test an argument was passed
- assert { [string match "*cmdstat_module*" $info] }
- }
-
- test {test RM_Call args array} {
- set info [r test.call_generic info commandstats]
- # cmdstat is not in a default section, so we also test an argument was passed
- assert { [string match "*cmdstat_module*" $info] }
- }
-
- test {test RM_Call recursive} {
- set info [r test.call_generic test.call_generic info commandstats]
- assert { [string match "*cmdstat_module*" $info] }
- }
-
- test {test redis version} {
- set version [s redis_version]
- assert_equal $version [r test.redisversion]
- }
-
- test {test long double conversions} {
- set ld [r test.ld_conversion]
- assert {[string match $ld "0.00000000000000001"]}
- }
-
- test {test unsigned long long conversions} {
- set ret [r test.ull_conversion]
- assert {[string match $ret "ok"]}
- }
-
- test {test module db commands} {
- r set x foo
- set key [r test.randomkey]
- assert_equal $key "x"
- assert_equal [r test.dbsize] 1
- r test.flushall
- assert_equal [r test.dbsize] 0
- }
-
- test {test RedisModule_ResetDataset do not reset functions} {
- r function load {#!lua name=lib
- redis.register_function('test', function() return 1 end)
- }
- assert_equal [r function list] {{library_name lib engine LUA functions {{name test description {} flags {}}}}}
- r test.flushall
- assert_equal [r function list] {{library_name lib engine LUA functions {{name test description {} flags {}}}}}
- r function flush
- }
-
- test {test module keyexists} {
- r set x foo
- assert_equal 1 [r test.keyexists x]
- r del x
- assert_equal 0 [r test.keyexists x]
- }
-
- test {test module lru api} {
- r config set maxmemory-policy allkeys-lru
- r set x foo
- set lru [r test.getlru x]
- assert { $lru <= 1000 }
- set was_set [r test.setlru x 100000]
- assert { $was_set == 1 }
- set idle [r object idletime x]
- assert { $idle >= 100 }
- set lru [r test.getlru x]
- assert { $lru >= 100000 }
- r config set maxmemory-policy allkeys-lfu
- set lru [r test.getlru x]
- assert { $lru == -1 }
- set was_set [r test.setlru x 100000]
- assert { $was_set == 0 }
- }
- r config set maxmemory-policy allkeys-lru
-
- test {test module lfu api} {
- r config set maxmemory-policy allkeys-lfu
- r set x foo
- set lfu [r test.getlfu x]
- assert { $lfu >= 1 }
- set was_set [r test.setlfu x 100]
- assert { $was_set == 1 }
- set freq [r object freq x]
- assert { $freq <= 100 }
- set lfu [r test.getlfu x]
- assert { $lfu <= 100 }
- r config set maxmemory-policy allkeys-lru
- set lfu [r test.getlfu x]
- assert { $lfu == -1 }
- set was_set [r test.setlfu x 100]
- assert { $was_set == 0 }
- }
-
- test {test module clientinfo api} {
- # Test basic sanity and SSL flag
- set info [r test.clientinfo]
- set ssl_flag [expr $::tls ? {"ssl:"} : {":"}]
-
- assert { [dict get $info db] == 9 }
- assert { [dict get $info flags] == "${ssl_flag}::::" }
-
- # Test MULTI flag
- r multi
- r test.clientinfo
- set info [lindex [r exec] 0]
- assert { [dict get $info flags] == "${ssl_flag}::::multi" }
-
- # Test TRACKING flag
- r client tracking on
- set info [r test.clientinfo]
- assert { [dict get $info flags] == "${ssl_flag}::tracking::" }
- r CLIENT TRACKING off
- }
-
- test {tracking with rm_call sanity} {
- set rd_trk [redis_client]
- $rd_trk HELLO 3
- $rd_trk CLIENT TRACKING on
- r MSET key1{t} 1 key2{t} 1
-
- # GET triggers tracking, SET does not
- $rd_trk test.rm_call GET key1{t}
- $rd_trk test.rm_call SET key2{t} 2
- r MSET key1{t} 2 key2{t} 2
- assert_equal {invalidate key1{t}} [$rd_trk read]
- assert_equal "PONG" [$rd_trk ping]
- $rd_trk close
- }
-
- test {tracking with rm_call with script} {
- set rd_trk [redis_client]
- $rd_trk HELLO 3
- $rd_trk CLIENT TRACKING on
- r MSET key1{t} 1 key2{t} 1
-
- # GET triggers tracking, SET does not
- $rd_trk test.rm_call EVAL "redis.call('get', 'key1{t}')" 2 key1{t} key2{t}
- r MSET key1{t} 2 key2{t} 2
- assert_equal {invalidate key1{t}} [$rd_trk read]
- assert_equal "PONG" [$rd_trk ping]
- $rd_trk close
- }
-
- test {RM_SignalModifiedKey - tracking invalidation} {
- set rd_trk [redis_client]
- $rd_trk HELLO 3
- $rd_trk CLIENT TRACKING on
- r SET mykey{t} abc
-
- # Track the key by reading it
- $rd_trk GET mykey{t}
-
- # # Modify the key using module command that calls RM_SignalModifiedKey
- r test.signalmodifiedkey mykey{t}
-
- # # Should receive invalidation message
- assert_equal {invalidate mykey{t}} [$rd_trk read]
- assert_equal "PONG" [$rd_trk ping]
- $rd_trk close
- }
-
- test {RM_SignalModifiedKey - update LRM timestamp} {
- set old_policy [config_get_set maxmemory-policy allkeys-lrm]
- r SET mykey{t} abc
- after 2000
- assert_morethan_equal [r object idletime mykey{t}] 1
-
- # LRM should be updated.
- r test.signalmodifiedkey mykey{t}
- assert_lessthan [r object idletime mykey{t}] 2
- r config set maxmemory-policy $old_policy
- } {OK} {slow}
-
- test {publish to self inside rm_call} {
- r hello 3
- r subscribe foo
-
- # published message comes after the response of the command that issued it.
- assert_equal [r test.rm_call publish foo bar] {1}
- assert_equal [r read] {message foo bar}
-
- r unsubscribe foo
- r hello 2
- set _ ""
- } {} {resp3}
-
- test {test module get/set client name by id api} {
- catch { r test.getname } e
- assert_equal "-ERR No name" $e
- r client setname nobody
- catch { r test.setname "name with spaces" } e
- assert_match "*Invalid argument*" $e
- assert_equal nobody [r client getname]
- assert_equal nobody [r test.getname]
- r test.setname somebody
- assert_equal somebody [r client getname]
- }
-
- test {test module getclientcert api} {
- set cert [r test.getclientcert]
-
- if {$::tls} {
- assert {$cert != ""}
- } else {
- assert {$cert == ""}
- }
- }
-
- test {test detached thread safe cnotext} {
- r test.log_tsctx "info" "Test message"
- verify_log_message 0 "*<misc> Test message*" 0
- }
-
- test {test RM_Call CLIENT INFO} {
- assert_match "*fd=-1*" [r test.call_generic client info]
- }
-
- test {Unsafe command names are sanitized in INFO output} {
- r test.weird:cmd
- set info [r info commandstats]
- assert_match {*cmdstat_test.weird_cmd:calls=1*} $info
- }
-
- test {test monotonic time} {
- set x [r test.monotonic_time]
- assert { [r test.monotonic_time] >= $x }
- }
-
- test {rm_call OOM} {
- r config set maxmemory 1
- r config set maxmemory-policy volatile-lru
-
- # sanity test plain call
- assert_equal {OK} [
- r test.rm_call set x 1
- ]
-
- # add the M flag
- assert_error {OOM *} {
- r test.rm_call_flags M set x 1
-
- }
-
- # test a non deny-oom command
- assert_equal {1} [
- r test.rm_call_flags M get x
- ]
-
- r config set maxmemory 0
- } {OK} {needs:config-maxmemory}
-
- test {rm_call clear OOM} {
- r config set maxmemory 1
-
- # verify rm_call fails with OOM
- assert_error {OOM *} {
- r test.rm_call_flags M set x 1
- }
-
- # clear OOM state
- r config set maxmemory 0
-
- # test set command is allowed
- r test.rm_call_flags M set x 1
- } {OK} {needs:config-maxmemory}
-
- test {rm_call OOM Eval} {
- r config set maxmemory 1
- r config set maxmemory-policy volatile-lru
-
- # use the M flag without allow-oom shebang flag
- assert_error {OOM *} {
- r test.rm_call_flags M eval {#!lua
- redis.call('set','x',1)
- return 1
- } 1 x
- }
-
- # add the M flag with allow-oom shebang flag
- assert_equal {1} [
- r test.rm_call_flags M eval {#!lua flags=allow-oom
- redis.call('set','x',1)
- return 1
- } 1 x
- ]
-
- r config set maxmemory 0
- } {OK} {needs:config-maxmemory}
-
- test {rm_call write flag} {
- # add the W flag
- assert_error {ERR Write command 'set' was called while write is not allowed.} {
- r test.rm_call_flags W set x 1
- }
-
- # test a non deny-oom command
- r test.rm_call_flags W get x
- } {1}
-
- test {rm_call EVAL} {
- r test.rm_call eval {
- redis.call('set','x',1)
- return 1
- } 1 x
-
- assert_error {ERR Write commands are not allowed from read-only scripts.*} {
- r test.rm_call eval {#!lua flags=no-writes
- redis.call('set','x',1)
- return 1
- } 1 x
- }
- }
-
- # Note: each script is unique, to check that flags are extracted correctly
- test {rm_call EVAL - OOM - with M flag} {
- r config set maxmemory 1
-
- # script without shebang, but uses SET, so fails
- assert_error {*OOM command not allowed when used memory > 'maxmemory'*} {
- r test.rm_call_flags M eval {
- redis.call('set','x',1)
- return 1
- } 1 x
- }
-
- # script with an allow-oom flag, succeeds despite using SET
- r test.rm_call_flags M eval {#!lua flags=allow-oom
- redis.call('set','x', 1)
- return 2
- } 1 x
-
- # script with no-writes flag, implies allow-oom, succeeds
- r test.rm_call_flags M eval {#!lua flags=no-writes
- redis.call('get','x')
- return 2
- } 1 x
-
- # script with shebang using default flags, so fails regardless of using only GET
- assert_error {*OOM command not allowed when used memory > 'maxmemory'*} {
- r test.rm_call_flags M eval {#!lua
- redis.call('get','x')
- return 3
- } 1 x
- }
-
- # script without shebang, but uses GET, so succeeds
- r test.rm_call_flags M eval {
- redis.call('get','x')
- return 4
- } 1 x
-
- r config set maxmemory 0
- } {OK} {needs:config-maxmemory}
-
- # All RM_Call for script succeeds in OOM state without using the M flag
- test {rm_call EVAL - OOM - without M flag} {
- r config set maxmemory 1
-
- # no shebang at all
- r test.rm_call eval {
- redis.call('set','x',1)
- return 6
- } 1 x
-
- # Shebang without flags
- r test.rm_call eval {#!lua
- redis.call('set','x', 1)
- return 7
- } 1 x
-
- # with allow-oom flag
- r test.rm_call eval {#!lua flags=allow-oom
- redis.call('set','x', 1)
- return 8
- } 1 x
-
- r config set maxmemory 0
- } {OK} {needs:config-maxmemory}
-
- test "not enough good replicas" {
- r set x "some value"
- r config set min-replicas-to-write 1
-
- # rm_call in script mode
- assert_error {NOREPLICAS *} {r test.rm_call_flags S set x s}
-
- assert_equal [
- r test.rm_call eval {#!lua flags=no-writes
- return redis.call('get','x')
- } 1 x
- ] "some value"
-
- assert_equal [
- r test.rm_call eval {
- return redis.call('get','x')
- } 1 x
- ] "some value"
-
- assert_error {NOREPLICAS *} {
- r test.rm_call eval {#!lua
- return redis.call('get','x')
- } 1 x
- }
-
- assert_error {NOREPLICAS *} {
- r test.rm_call eval {
- return redis.call('set','x', 1)
- } 1 x
- }
-
- r config set min-replicas-to-write 0
- }
-
- test {rm_call EVAL - read-only replica} {
- r replicaof 127.0.0.1 1
-
- # rm_call in script mode
- assert_error {READONLY *} {r test.rm_call_flags S set x 1}
-
- assert_error {READONLY You can't write against a read only replica. script*} {
- r test.rm_call eval {
- redis.call('set','x',1)
- return 1
- } 1 x
- }
-
- r test.rm_call eval {#!lua flags=no-writes
- redis.call('get','x')
- return 2
- } 1 x
-
- assert_error {READONLY Can not run script with write flag on readonly replica*} {
- r test.rm_call eval {#!lua
- redis.call('get','x')
- return 3
- } 1 x
- }
-
- r test.rm_call eval {
- redis.call('get','x')
- return 4
- } 1 x
-
- r replicaof no one
- } {OK} {needs:config-maxmemory}
-
- test {rm_call EVAL - stale replica} {
- r replicaof 127.0.0.1 1
- r config set replica-serve-stale-data no
-
- # rm_call in script mode
- assert_error {MASTERDOWN *} {
- r test.rm_call_flags S get x
- }
-
- assert_error {MASTERDOWN *} {
- r test.rm_call eval {#!lua flags=no-writes
- redis.call('get','x')
- return 2
- } 1 x
- }
-
- assert_error {MASTERDOWN *} {
- r test.rm_call eval {
- redis.call('get','x')
- return 4
- } 1 x
- }
-
- r replicaof no one
- r config set replica-serve-stale-data yes
- } {OK} {needs:config-maxmemory}
-
- test "rm_call EVAL - failed bgsave prevents writes" {
- r config set rdb-key-save-delay 10000000
- populate 1000
- r set x x
- r bgsave
- set pid1 [get_child_pid 0]
- catch {exec kill -9 $pid1}
- waitForBgsave r
-
- # make sure a read command succeeds
- assert_equal [r get x] x
-
- # make sure a write command fails
- assert_error {MISCONF *} {r set x y}
-
- # rm_call in script mode
- assert_error {MISCONF *} {r test.rm_call_flags S set x 1}
-
- # repeate with script
- assert_error {MISCONF *} {r test.rm_call eval {
- return redis.call('set','x',1)
- } 1 x
- }
- assert_equal {x} [r test.rm_call eval {
- return redis.call('get','x')
- } 1 x
- ]
-
- # again with script using shebang
- assert_error {MISCONF *} {r test.rm_call eval {#!lua
- return redis.call('set','x',1)
- } 1 x
- }
- assert_equal {x} [r test.rm_call eval {#!lua flags=no-writes
- return redis.call('get','x')
- } 1 x
- ]
-
- r config set rdb-key-save-delay 0
- r bgsave
- waitForBgsave r
-
- # server is writable again
- r set x y
- } {OK}
-
- test "malloc API" {
- assert_equal {OK} [r test.malloc_api 0]
- }
-
- test "Cluster keyslot" {
- assert_equal 12182 [r test.keyslot foo]
- }
-}
-
-start_server {tags {"modules external:skip"}} {
- r module load $testmodule
-
- test {test Dry Run - OK OOM/ACL} {
- set x 5
- r set x $x
- catch {r test.rm_call_flags DMC set x 10} e
- assert_match {*NULL reply returned*} $e
- assert_equal [r get x] 5
- }
-
- test {test Dry Run - Fail OOM} {
- set x 5
- r set x $x
- r config set maxmemory 1
- catch {r test.rm_call_flags DM set x 10} e
- assert_match {*OOM*} $e
- assert_equal [r get x] $x
- r config set maxmemory 0
- } {OK} {needs:config-maxmemory}
-
- test {test Dry Run - Fail ACL} {
- set x 5
- r set x $x
- # deny all permissions besides the dryrun command
- r acl setuser default resetkeys
-
- catch {r test.rm_call_flags DC set x 10} e
- assert_match {*NOPERM No permissions to access a key*} $e
- r acl setuser default +@all ~*
- assert_equal [r get x] $x
- }
-
- test {test silent open key} {
- r debug set-active-expire 0
- r test.clear_n_events
- r set x 1 PX 10
- after 1000
- # now the key has been expired, open it silently and make sure not event were fired.
- assert_error {key not found} {r test.silent_open_key x}
- assert_equal {0} [r test.get_n_events]
- }
-
-if {[string match {*jemalloc*} [s mem_allocator]]} {
- test {test RM_Call with large arg for SET command} {
- # set a big value to trigger increasing the query buf
- r set foo [string repeat A 100000]
- # set a smaller value but > PROTO_MBULK_BIG_ARG (32*1024) Redis will try to save the query buf itself on the DB.
- r test.call_generic set bar [string repeat A 33000]
- # asset the value was trimmed
- assert {[r memory usage bar] < 42000}; # 42K to count for Jemalloc's additional memory overhead.
- }
-} ;# if jemalloc
-
- test "Unload the module - misc" {
- assert_equal {OK} [r module unload misc]
- }
-}
-
-start_server {tags {"modules external:skip"}} {
- test {Detect incompatible operations in cluster mode for module} {
- r config set cluster-compatibility-sample-ratio 100
- set incompatible_ops [s cluster_incompatible_ops]
-
- # since test.no_cluster_cmd and its subcommand have 'no-cluster' flag,
- # they should not be counted as incompatible ops, increment the counter by 2
- r module load $testmodule
- assert_equal [expr $incompatible_ops+2] [s cluster_incompatible_ops]
-
- # incompatible_cluster_cmd is similar with MSET, check if it is counted as
- # incompatible ops with different number of keys
- # only 1 key, should not increment the counter
- r test.incompatible_cluster_cmd foo bar
- assert_equal [expr $incompatible_ops+2] [s cluster_incompatible_ops]
- # 2 cross slot keys, should increment the counter
- r test.incompatible_cluster_cmd foo bar bar foo
- assert_equal [expr $incompatible_ops+3] [s cluster_incompatible_ops]
- # 2 non cross slot keys, should not increment the counter
- r test.incompatible_cluster_cmd foo bar bar{foo} bar
- assert_equal [expr $incompatible_ops+3] [s cluster_incompatible_ops]
- }
-}