mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-21 23:58:51 -05:00
tests/*: replace redis with redict in Lua usage
Signed-off-by: Drew DeVault <sir@cmpwn.com>
This commit is contained in:
parent
a91d1148cf
commit
e32c74c826
@ -1,4 +1,4 @@
|
||||
# Test suite for redis-cli command-line hinting mechanism.
|
||||
# Test suite for redict-cli command-line hinting mechanism.
|
||||
# Each test case consists of two strings: a (partial) input command line, and the expected hint string.
|
||||
|
||||
# Command with one arg: GET key
|
||||
|
@ -116,7 +116,7 @@ test "Cluster consistency during live resharding" {
|
||||
} elseif {$listid % 3 == 1} {
|
||||
$cluster_plaintext rpush $key $ele
|
||||
} else {
|
||||
$cluster eval {redis.call("rpush",KEYS[1],ARGV[1])} 1 $key $ele
|
||||
$cluster eval {redict.call("rpush",KEYS[1],ARGV[1])} 1 $key $ele
|
||||
}
|
||||
lappend content($key) $ele
|
||||
|
||||
|
@ -53,7 +53,7 @@ test "Send CLUSTER FAILOVER to #5, during load" {
|
||||
if {$listid % 2} {
|
||||
$cluster rpush $key $ele
|
||||
} else {
|
||||
$cluster eval {redis.call("rpush",KEYS[1],ARGV[1])} 1 $key $ele
|
||||
$cluster eval {redict.call("rpush",KEYS[1],ARGV[1])} 1 $key $ele
|
||||
}
|
||||
lappend content($key) $ele
|
||||
|
||||
|
@ -84,8 +84,8 @@ test "read-only blocking operations from replica" {
|
||||
|
||||
test "reply MOVED when eval from replica for update" {
|
||||
catch {[$replica eval {#!lua
|
||||
return redis.call('del','a')
|
||||
return redict.call('del','a')
|
||||
} 1 a
|
||||
]} err
|
||||
assert {[string range $err 0 4] eq {MOVED}}
|
||||
}
|
||||
}
|
||||
|
2
tests/cluster/tmp/.gitignore
vendored
2
tests/cluster/tmp/.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
redis_*
|
||||
redict_*
|
||||
sentinel_*
|
||||
|
@ -442,7 +442,7 @@ tags {"aof external:skip"} {
|
||||
# make sure that the script times out during loading
|
||||
create_aof $aof_dirpath $aof_file {
|
||||
append_to_aof [formatCommand select 9]
|
||||
append_to_aof [formatCommand eval {redis.call('set',KEYS[1],'y'); for i=1,1500000 do redis.call('ping') end return 'ok'} 1 x]
|
||||
append_to_aof [formatCommand eval {redict.call('set',KEYS[1],'y'); for i=1,1500000 do redict.call('ping') end return 'ok'} 1 x]
|
||||
}
|
||||
set rd [redict_deferring_client]
|
||||
$rd debug loadaof
|
||||
@ -466,9 +466,9 @@ tags {"aof external:skip"} {
|
||||
}
|
||||
create_aof $aof_dirpath $aof_file {
|
||||
append_to_aof [formatCommand select 9]
|
||||
append_to_aof [formatCommand eval {redis.call("set",KEYS[1],"100")} 1 foo]
|
||||
append_to_aof [formatCommand eval {redis.call("incr",KEYS[1])} 1 foo]
|
||||
append_to_aof [formatCommand eval {redis.call("incr",KEYS[1])} 1 foo]
|
||||
append_to_aof [formatCommand eval {redict.call("set",KEYS[1],"100")} 1 foo]
|
||||
append_to_aof [formatCommand eval {redict.call("incr",KEYS[1])} 1 foo]
|
||||
append_to_aof [formatCommand eval {redict.call("incr",KEYS[1])} 1 foo]
|
||||
}
|
||||
start_server [list overrides [list dir $server_path appendonly yes replica-read-only yes replicaof "127.0.0.1 0"]] {
|
||||
assert_equal [r get foo] 102
|
||||
|
@ -367,10 +367,10 @@ start_server {overrides {save ""}} {
|
||||
|
||||
exec cp -f tests/assets/scriptbackup.rdb $server_path
|
||||
start_server [list overrides [list "dir" $server_path "dbfilename" "scriptbackup.rdb" "appendonly" "no"]] {
|
||||
# the script is: "return redis.call('set', 'foo', 'bar')""
|
||||
# its sha1 is: a0c38691e9fffe4563723c32ba77a34398e090e6
|
||||
# the script is: "return redict.call('set', 'foo', 'bar')""
|
||||
# its sha1 is: 0ede24b0c6cf991e80a18f0ef8e7f211764125e2
|
||||
test {script won't load anymore if it's in rdb} {
|
||||
assert_equal [r script exists a0c38691e9fffe4563723c32ba77a34398e090e6] 0
|
||||
assert_equal [r script exists 0ede24b0c6cf991e80a18f0ef8e7f211764125e2] 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,21 +395,21 @@ start_server {} {
|
||||
|
||||
# repeate with script
|
||||
assert_error {MISCONF *} {r eval {
|
||||
return redis.call('set','x',1)
|
||||
return redict.call('set','x',1)
|
||||
} 1 x
|
||||
}
|
||||
assert_equal {x} [r eval {
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
]
|
||||
|
||||
# again with script using shebang
|
||||
assert_error {MISCONF *} {r eval {#!lua
|
||||
return redis.call('set','x',1)
|
||||
return redict.call('set','x',1)
|
||||
} 1 x
|
||||
}
|
||||
assert_equal {x} [r eval {#!lua flags=no-writes
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
]
|
||||
|
||||
|
@ -449,7 +449,7 @@ if {!$::tls} { ;# fake_redict_node doesn't support TLS
|
||||
assert_match "*SUCCESS*" $output
|
||||
r acl deluser clitest
|
||||
}
|
||||
|
||||
|
||||
proc test_redict_cli_rdb_dump {functions_only} {
|
||||
r flushdb
|
||||
r function flush
|
||||
@ -457,7 +457,7 @@ if {!$::tls} { ;# fake_redict_node doesn't support TLS
|
||||
set dir [lindex [r config get dir] 1]
|
||||
|
||||
assert_equal "OK" [r debug populate 100000 key 1000]
|
||||
assert_equal "lib1" [r function load "#!lua name=lib1\nredis.register_function('func1', function() return 123 end)"]
|
||||
assert_equal "lib1" [r function load "#!lua name=lib1\nredict.register_function('func1', function() return 123 end)"]
|
||||
if {$functions_only} {
|
||||
set args "--functions-rdb $dir/cli.rdb"
|
||||
} else {
|
||||
@ -470,7 +470,7 @@ if {!$::tls} { ;# fake_redict_node doesn't support TLS
|
||||
file rename "$dir/cli.rdb" "$dir/dump.rdb"
|
||||
|
||||
assert_equal "OK" [r set should-not-exist 1]
|
||||
assert_equal "should_not_exist_func" [r function load "#!lua name=should_not_exist_func\nredis.register_function('should_not_exist_func', function() return 456 end)"]
|
||||
assert_equal "should_not_exist_func" [r function load "#!lua name=should_not_exist_func\nredict.register_function('should_not_exist_func', function() return 456 end)"]
|
||||
assert_equal "OK" [r debug reload nosave]
|
||||
assert_equal {} [r get should-not-exist]
|
||||
assert_equal {{library_name lib1 engine LUA functions {{name func1 description {} flags {}}}}} [r function list]
|
||||
|
@ -67,8 +67,8 @@ start_server {tags {"repl external:skip"}} {
|
||||
|
||||
# Load some functions to be used later
|
||||
$master FUNCTION load replace {#!lua name=test
|
||||
redis.register_function{function_name='f_default_flags', callback=function(keys, args) return redis.call('get',keys[1]) end, flags={}}
|
||||
redis.register_function{function_name='f_no_writes', callback=function(keys, args) return redis.call('get',keys[1]) end, flags={'no-writes'}}
|
||||
redict.register_function{function_name='f_default_flags', callback=function(keys, args) return redict.call('get',keys[1]) end, flags={}}
|
||||
redict.register_function{function_name='f_no_writes', callback=function(keys, args) return redict.call('get',keys[1]) end, flags={'no-writes'}}
|
||||
}
|
||||
|
||||
test {First server should have role slave after SLAVEOF} {
|
||||
@ -80,14 +80,14 @@ start_server {tags {"repl external:skip"}} {
|
||||
$master config set min-slaves-max-lag 3
|
||||
$master config set min-slaves-to-write 1
|
||||
assert_equal OK [$master set foo 123]
|
||||
assert_equal OK [$master eval "return redis.call('set','foo',12345)" 0]
|
||||
assert_equal OK [$master eval "return redict.call('set','foo',12345)" 0]
|
||||
}
|
||||
|
||||
test {With min-slaves-to-write (2,3): master should not be writable} {
|
||||
$master config set min-slaves-max-lag 3
|
||||
$master config set min-slaves-to-write 2
|
||||
assert_error "*NOREPLICAS*" {$master set foo bar}
|
||||
assert_error "*NOREPLICAS*" {$master eval "redis.call('set','foo','bar')" 0}
|
||||
assert_error "*NOREPLICAS*" {$master eval "redict.call('set','foo','bar')" 0}
|
||||
}
|
||||
|
||||
test {With min-slaves-to-write function without no-write flag} {
|
||||
@ -98,17 +98,17 @@ start_server {tags {"repl external:skip"}} {
|
||||
test {With not enough good slaves, read in Lua script is still accepted} {
|
||||
$master config set min-slaves-max-lag 3
|
||||
$master config set min-slaves-to-write 1
|
||||
$master eval "redis.call('set','foo','bar')" 0
|
||||
$master eval "redict.call('set','foo','bar')" 0
|
||||
|
||||
$master config set min-slaves-to-write 2
|
||||
$master eval "return redis.call('get','foo')" 0
|
||||
$master eval "return redict.call('get','foo')" 0
|
||||
} {bar}
|
||||
|
||||
test {With min-slaves-to-write: master not writable with lagged slave} {
|
||||
$master config set min-slaves-max-lag 2
|
||||
$master config set min-slaves-to-write 1
|
||||
assert_equal OK [$master set foo 123]
|
||||
assert_equal OK [$master eval "return redis.call('set','foo',12345)" 0]
|
||||
assert_equal OK [$master eval "return redict.call('set','foo',12345)" 0]
|
||||
# Killing a slave to make it become a lagged slave.
|
||||
pause_process [srv 0 pid]
|
||||
# Waiting for slave kill.
|
||||
@ -118,7 +118,7 @@ start_server {tags {"repl external:skip"}} {
|
||||
fail "Master didn't become readonly"
|
||||
}
|
||||
assert_error "*NOREPLICAS*" {$master set foo 123}
|
||||
assert_error "*NOREPLICAS*" {$master eval "return redis.call('set','foo',12345)" 0}
|
||||
assert_error "*NOREPLICAS*" {$master eval "return redict.call('set','foo',12345)" 0}
|
||||
resume_process [srv 0 pid]
|
||||
}
|
||||
}
|
||||
@ -272,8 +272,8 @@ start_server {tags {"repl external:skip"}} {
|
||||
wait_for_sync $replica
|
||||
}
|
||||
|
||||
test {Data divergence can happen under default conditions} {
|
||||
$replica config set propagation-error-behavior ignore
|
||||
test {Data divergence can happen under default conditions} {
|
||||
$replica config set propagation-error-behavior ignore
|
||||
$master debug replicate fake-command-1
|
||||
|
||||
# Wait for replication to normalize
|
||||
@ -286,7 +286,7 @@ start_server {tags {"repl external:skip"}} {
|
||||
assert_equal [count_log_message 0 "== CRITICAL =="] 1
|
||||
}
|
||||
|
||||
test {Data divergence is allowed on writable replicas} {
|
||||
test {Data divergence is allowed on writable replicas} {
|
||||
$replica config set replica-read-only no
|
||||
$replica set number2 foo
|
||||
$master incrby number2 1
|
||||
|
@ -196,7 +196,7 @@ start_server {tags {"repl external:skip"}} {
|
||||
[$B lrange foo 0 -1] eq {a b c}
|
||||
} else {
|
||||
fail "Master and replica have different digest: [$A debug digest] VS [$B debug digest]"
|
||||
}
|
||||
}
|
||||
assert_match {*calls=1,*,rejected_calls=0,failed_calls=1*} [cmdrstat blpop $B]
|
||||
}
|
||||
}
|
||||
@ -259,12 +259,12 @@ start_server {tags {"repl external:skip"}} {
|
||||
# DB is empty.
|
||||
r -1 flushdb
|
||||
r -1 flushdb
|
||||
r -1 eval {redis.call("flushdb")} 0
|
||||
r -1 eval {redict.call("flushdb")} 0
|
||||
|
||||
# DBs are empty.
|
||||
r -1 flushall
|
||||
r -1 flushall
|
||||
r -1 eval {redis.call("flushall")} 0
|
||||
r -1 eval {redict.call("flushall")} 0
|
||||
|
||||
# add another command to check nothing else was propagated after the above
|
||||
r -1 incr x
|
||||
@ -580,12 +580,12 @@ foreach testType {Successful Aborted} {
|
||||
|
||||
# Set a function value on replica to check status during loading, on failure and after swapping db
|
||||
$replica function load {#!lua name=test
|
||||
redis.register_function('test', function() return 'hello1' end)
|
||||
redict.register_function('test', function() return 'hello1' end)
|
||||
}
|
||||
|
||||
# Set a function value on master to check it reaches the replica when replication ends
|
||||
$master function load {#!lua name=test
|
||||
redis.register_function('test', function() return 'hello2' end)
|
||||
redict.register_function('test', function() return 'hello2' end)
|
||||
}
|
||||
|
||||
# Remember the sync_full stat before the client kill.
|
||||
@ -733,7 +733,7 @@ test {diskless loading short read} {
|
||||
|
||||
# Set a function value to check short read handling on functions
|
||||
r function load {#!lua name=test
|
||||
redis.register_function('test', function() return 'hello1' end)
|
||||
redict.register_function('test', function() return 'hello1' end)
|
||||
}
|
||||
|
||||
for {set k 0} {$k < 3} {incr k} {
|
||||
|
@ -25,14 +25,14 @@ proc redictbenchmark {host port {opts {}}} {
|
||||
}
|
||||
|
||||
proc redictbenchmarkuri {host port {opts {}}} {
|
||||
set cmd [list src/redict-benchmark -u redis://$host:$port]
|
||||
set cmd [list src/redict-benchmark -u redict://$host:$port]
|
||||
lappend cmd {*}[redictbenchmark_tls_config "tests"]
|
||||
lappend cmd {*}$opts
|
||||
return $cmd
|
||||
}
|
||||
|
||||
proc redictbenchmarkuriuserpass {host port user pass {opts {}}} {
|
||||
set cmd [list src/redict-benchmark -u redis://$user:$pass@$host:$port]
|
||||
set cmd [list src/redict-benchmark -u redict://$user:$pass@$host:$port]
|
||||
lappend cmd {*}[redictbenchmark_tls_config "tests"]
|
||||
lappend cmd {*}$opts
|
||||
return $cmd
|
||||
|
@ -43,7 +43,7 @@ proc crashlog_from_file {filename} {
|
||||
set logall 0
|
||||
set result {}
|
||||
foreach line $lines {
|
||||
if {[string match {*REDIS BUG REPORT START*} $line]} {
|
||||
if {[string match {*REDICT BUG REPORT START*} $line]} {
|
||||
set logall 1
|
||||
}
|
||||
if {[regexp {^\[\d+\]\s+\d+\s+\w+\s+\d{2}:\d{2}:\d{2} \#} $line]} {
|
||||
@ -577,7 +577,7 @@ proc wait_load_handlers_disconnected {{level 0}} {
|
||||
}
|
||||
}
|
||||
|
||||
proc K { x y } { set x }
|
||||
proc K { x y } { set x }
|
||||
|
||||
# Shuffle a list with Fisher-Yates algorithm.
|
||||
proc lshuffle {list} {
|
||||
@ -1019,7 +1019,7 @@ proc get_nonloopback_client {} {
|
||||
}
|
||||
|
||||
# The following functions and variables are used only when running large-memory
|
||||
# tests. We avoid defining them when not running large-memory tests because the
|
||||
# tests. We avoid defining them when not running large-memory tests because the
|
||||
# global variables takes up lots of memory.
|
||||
proc init_large_mem_vars {} {
|
||||
if {![info exists ::str500]} {
|
||||
|
@ -252,7 +252,7 @@ start_server {tags {"acl external:skip"}} {
|
||||
catch {$rd read} e
|
||||
set e
|
||||
} {*NOPERM*channel*}
|
||||
|
||||
|
||||
test {Subscribers are killed when revoked of channel permission} {
|
||||
set rd [redict_deferring_client]
|
||||
r ACL setuser psuser resetchannels &foo:1
|
||||
@ -463,7 +463,7 @@ start_server {tags {"acl external:skip"}} {
|
||||
# Appending to the existing access string of bob.
|
||||
r ACL setuser bob +@all +client|id
|
||||
# Although this does nothing, we retain it anyways so we can reproduce
|
||||
# the original ACL.
|
||||
# the original ACL.
|
||||
set cmdstr [dict get [r ACL getuser bob] commands]
|
||||
assert_equal {+@all +client|id} $cmdstr
|
||||
|
||||
@ -780,7 +780,7 @@ start_server {tags {"acl external:skip"}} {
|
||||
|
||||
test {ACL can log errors in the context of Lua scripting} {
|
||||
r AUTH antirez foo
|
||||
catch {r EVAL {redis.call('incr','foo')} 0}
|
||||
catch {r EVAL {redict.call('incr','foo')} 0}
|
||||
r AUTH default ""
|
||||
set entry [lindex [r ACL LOG] 0]
|
||||
assert {[dict get $entry context] eq {lua}}
|
||||
@ -919,7 +919,7 @@ start_server {tags {"acl external:skip"}} {
|
||||
set current_invalid_cmd_accesses [s acl_access_denied_cmd]
|
||||
set current_invalid_key_accesses [s acl_access_denied_key]
|
||||
set current_invalid_channel_accesses [s acl_access_denied_channel]
|
||||
assert_error "*WRONGPASS*" {r AUTH notrealuser 1233456}
|
||||
assert_error "*WRONGPASS*" {r AUTH notrealuser 1233456}
|
||||
assert {[s acl_access_denied_auth] eq [expr $current_auth_failures + 1]}
|
||||
assert_error "*WRONGPASS*" {r HELLO 3 AUTH notrealuser 1233456}
|
||||
assert {[s acl_access_denied_auth] eq [expr $current_auth_failures + 2]}
|
||||
@ -960,7 +960,7 @@ start_server {tags {"acl external:skip"}} {
|
||||
assert {[s acl_access_denied_cmd] eq $current_invalid_cmd_accesses}
|
||||
assert {[s acl_access_denied_key] eq [expr $current_invalid_key_accesses + 1]}
|
||||
assert {[s acl_access_denied_channel] eq $current_invalid_channel_accesses}
|
||||
}
|
||||
}
|
||||
|
||||
# If a user try to access an unauthorized channel the metric increases
|
||||
test {ACL-Metrics invalid channels accesses} {
|
||||
@ -1203,11 +1203,11 @@ start_server [list overrides [list "dir" $server_path "aclfile" "user.acl"] tags
|
||||
set corruption "\nuser alice on nopass ~* -@all"
|
||||
exec echo $corruption >> $server_path/user.acl
|
||||
catch {r ACL LOAD} err
|
||||
assert_match {*Duplicate user 'alice' found*} $err
|
||||
assert_match {*Duplicate user 'alice' found*} $err
|
||||
|
||||
# Verify the previous users still exist
|
||||
# NOTE: A missing user evaluates to an empty
|
||||
# string.
|
||||
# string.
|
||||
assert {[r ACL GETUSER alice] != ""}
|
||||
assert_equal [dict get [r ACL GETUSER alice] commands] "+@all"
|
||||
assert {[r ACL GETUSER bob] != ""}
|
||||
@ -1221,17 +1221,17 @@ start_server [list overrides [list "dir" $server_path "aclfile" "user.acl"] tags
|
||||
set corruption "\nuser default on nopass ~* -@all"
|
||||
exec echo $corruption >> $server_path/user.acl
|
||||
catch {r ACL LOAD} err
|
||||
assert_match {*Duplicate user 'default' found*} $err
|
||||
assert_match {*Duplicate user 'default' found*} $err
|
||||
|
||||
# Verify the previous users still exist
|
||||
# NOTE: A missing user evaluates to an empty
|
||||
# string.
|
||||
# string.
|
||||
assert {[r ACL GETUSER alice] != ""}
|
||||
assert_equal [dict get [r ACL GETUSER alice] commands] "+@all"
|
||||
assert {[r ACL GETUSER bob] != ""}
|
||||
assert {[r ACL GETUSER default] != ""}
|
||||
}
|
||||
|
||||
|
||||
test {Test loading duplicate users in config on startup} {
|
||||
catch {exec src/redict-server --user foo --user foo} err
|
||||
assert_match {*Duplicate user*} $err
|
||||
|
@ -200,7 +200,7 @@ start_server {tags {"aofrw external:skip"} overrides {aof-use-rdb-preamble no}}
|
||||
test "AOF rewrite functions" {
|
||||
r flushall
|
||||
r FUNCTION LOAD {#!lua name=test
|
||||
redis.register_function('test', function() return 1 end)
|
||||
redict.register_function('test', function() return 1 end)
|
||||
}
|
||||
r bgrewriteaof
|
||||
waitForBgrewriteaof r
|
||||
|
@ -215,7 +215,7 @@ start_server {} {
|
||||
set key_length [expr 1024*200]
|
||||
set long_key [string repeat k $key_length]
|
||||
# Use a script so we won't need to pass the long key name when dirtying it in the loop
|
||||
set script_sha [$rr script load "redis.call('incr', '$long_key')"]
|
||||
set script_sha [$rr script load "redict.call('incr', '$long_key')"]
|
||||
|
||||
# Pause serverCron so it won't update memory usage since we're testing the update logic when
|
||||
# writing tracking redirection output
|
||||
|
@ -88,7 +88,7 @@ start_multiple_servers 3 [list overrides $base_conf] {
|
||||
set node1_rd [redict_deferring_client 0]
|
||||
|
||||
test "use previous hostip in \"cluster-preferred-endpoint-type unknown-endpoint\" mode" {
|
||||
|
||||
|
||||
# backup and set cluster-preferred-endpoint-type unknown-endpoint
|
||||
set endpoint_type_before_set [lindex [split [$node1 CONFIG GET cluster-preferred-endpoint-type] " "] 1]
|
||||
$node1 CONFIG SET cluster-preferred-endpoint-type unknown-endpoint
|
||||
@ -187,7 +187,7 @@ start_multiple_servers 5 [list overrides $base_conf] {
|
||||
# upload a function to all the cluster
|
||||
exec src/redict-cli --cluster-yes --cluster call 127.0.0.1:[srv 0 port] \
|
||||
FUNCTION LOAD {#!lua name=TEST
|
||||
redis.register_function('test', function() return 'hello' end)
|
||||
redict.register_function('test', function() return 'hello' end)
|
||||
}
|
||||
|
||||
# adding node to the cluster
|
||||
@ -211,7 +211,7 @@ start_multiple_servers 5 [list overrides $base_conf] {
|
||||
|
||||
# add function to node 5
|
||||
assert_equal {TEST} [$node5_rd FUNCTION LOAD {#!lua name=TEST
|
||||
redis.register_function('test', function() return 'hello' end)
|
||||
redict.register_function('test', function() return 'hello' end)
|
||||
}]
|
||||
|
||||
# make sure functions was added to node 5
|
||||
@ -254,10 +254,10 @@ test {Migrate the last slot away from a node using redict-cli} {
|
||||
exec src/redict-cli --cluster-yes --cluster add-node \
|
||||
127.0.0.1:[srv -3 port] \
|
||||
127.0.0.1:[srv 0 port]
|
||||
|
||||
|
||||
# First we wait for new node to be recognized by entire cluster
|
||||
wait_for_cluster_size 4
|
||||
|
||||
|
||||
wait_for_condition 1000 50 {
|
||||
[CI 0 cluster_state] eq {ok} &&
|
||||
[CI 1 cluster_state] eq {ok} &&
|
||||
|
@ -10,30 +10,30 @@ start_cluster 1 0 {tags {external:skip cluster}} {
|
||||
# Test that scripts with shebang block cross slot operations
|
||||
assert_error "ERR Script attempted to access keys that do not hash to the same slot*" {
|
||||
r 0 eval {#!lua
|
||||
redis.call('set', 'foo', 'bar')
|
||||
redis.call('set', 'bar', 'foo')
|
||||
redict.call('set', 'foo', 'bar')
|
||||
redict.call('set', 'bar', 'foo')
|
||||
return 'OK'
|
||||
} 0}
|
||||
|
||||
# Test the functions by default block cross slot operations
|
||||
r 0 function load REPLACE {#!lua name=crossslot
|
||||
local function test_cross_slot(keys, args)
|
||||
redis.call('set', 'foo', 'bar')
|
||||
redis.call('set', 'bar', 'foo')
|
||||
redict.call('set', 'foo', 'bar')
|
||||
redict.call('set', 'bar', 'foo')
|
||||
return 'OK'
|
||||
end
|
||||
|
||||
redis.register_function('test_cross_slot', test_cross_slot)}
|
||||
redict.register_function('test_cross_slot', test_cross_slot)}
|
||||
assert_error "ERR Script attempted to access keys that do not hash to the same slot*" {r FCALL test_cross_slot 0}
|
||||
}
|
||||
|
||||
test {Cross slot commands are allowed by default for eval scripts and with allow-cross-slot-keys flag} {
|
||||
# Old style lua scripts are allowed to access cross slot operations
|
||||
r 0 eval "redis.call('set', 'foo', 'bar'); redis.call('set', 'bar', 'foo')" 0
|
||||
r 0 eval "redict.call('set', 'foo', 'bar'); redict.call('set', 'bar', 'foo')" 0
|
||||
|
||||
# scripts with allow-cross-slot-keys flag are allowed
|
||||
r 0 eval {#!lua flags=allow-cross-slot-keys
|
||||
redis.call('set', 'foo', 'bar'); redis.call('set', 'bar', 'foo')
|
||||
redict.call('set', 'foo', 'bar'); redict.call('set', 'bar', 'foo')
|
||||
} 0
|
||||
|
||||
# Retrieve data from different slot to verify data has been stored in the correct dictionary in cluster-enabled setup
|
||||
@ -46,12 +46,12 @@ start_cluster 1 0 {tags {external:skip cluster}} {
|
||||
# Functions with allow-cross-slot-keys flag are allowed
|
||||
r 0 function load REPLACE {#!lua name=crossslot
|
||||
local function test_cross_slot(keys, args)
|
||||
redis.call('set', 'foo', 'bar')
|
||||
redis.call('set', 'bar', 'foo')
|
||||
redict.call('set', 'foo', 'bar')
|
||||
redict.call('set', 'bar', 'foo')
|
||||
return 'OK'
|
||||
end
|
||||
|
||||
redis.register_function{function_name='test_cross_slot', callback=test_cross_slot, flags={ 'allow-cross-slot-keys' }}}
|
||||
redict.register_function{function_name='test_cross_slot', callback=test_cross_slot, flags={ 'allow-cross-slot-keys' }}}
|
||||
r FCALL test_cross_slot 0
|
||||
|
||||
# Retrieve data from different slot to verify data has been stored in the correct dictionary in cluster-enabled setup
|
||||
@ -59,18 +59,18 @@ start_cluster 1 0 {tags {external:skip cluster}} {
|
||||
assert_equal "bar" [r 0 get foo]
|
||||
assert_equal "foo" [r 0 get bar]
|
||||
}
|
||||
|
||||
|
||||
test {Cross slot commands are also blocked if they disagree with pre-declared keys} {
|
||||
assert_error "ERR Script attempted to access keys that do not hash to the same slot*" {
|
||||
r 0 eval {#!lua
|
||||
redis.call('set', 'foo', 'bar')
|
||||
redict.call('set', 'foo', 'bar')
|
||||
return 'OK'
|
||||
} 1 bar}
|
||||
}
|
||||
|
||||
test {Cross slot commands are allowed by default if they disagree with pre-declared keys} {
|
||||
r 0 flushall
|
||||
r 0 eval "redis.call('set', 'foo', 'bar')" 1 bar
|
||||
r 0 eval "redict.call('set', 'foo', 'bar')" 1 bar
|
||||
|
||||
# Make sure the script writes to the right slot
|
||||
assert_equal 1 [r 0 cluster COUNTKEYSINSLOT 12182] ;# foo slot
|
||||
@ -79,7 +79,7 @@ start_cluster 1 0 {tags {external:skip cluster}} {
|
||||
|
||||
test "Function no-cluster flag" {
|
||||
R 0 function load {#!lua name=test
|
||||
redis.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-cluster'}}
|
||||
redict.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-cluster'}}
|
||||
}
|
||||
catch {R 0 fcall f1 0} e
|
||||
assert_match {*Can not run script on cluster, 'no-cluster' flag is set*} $e
|
||||
@ -91,7 +91,7 @@ start_cluster 1 0 {tags {external:skip cluster}} {
|
||||
return 1
|
||||
} 0
|
||||
} e
|
||||
|
||||
|
||||
assert_match {*Can not run script on cluster, 'no-cluster' flag is set*} $e
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,11 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
proc get_function_code {args} {
|
||||
return [format "#!%s name=%s\nredis.register_function('%s', function(KEYS, ARGV)\n %s \nend)" [lindex $args 0] [lindex $args 1] [lindex $args 2] [lindex $args 3]]
|
||||
return [format "#!%s name=%s\nredict.register_function('%s', function(KEYS, ARGV)\n %s \nend)" [lindex $args 0] [lindex $args 1] [lindex $args 2] [lindex $args 3]]
|
||||
}
|
||||
|
||||
proc get_no_writes_function_code {args} {
|
||||
return [format "#!%s name=%s\nredis.register_function{function_name='%s', callback=function(KEYS, ARGV)\n %s \nend, flags={'no-writes'}}" [lindex $args 0] [lindex $args 1] [lindex $args 2] [lindex $args 3]]
|
||||
return [format "#!%s name=%s\nredict.register_function{function_name='%s', callback=function(KEYS, ARGV)\n %s \nend, flags={'no-writes'}}" [lindex $args 0] [lindex $args 1] [lindex $args 2] [lindex $args 3]]
|
||||
}
|
||||
|
||||
start_server {tags {"scripting"}} {
|
||||
@ -151,7 +151,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - test flushall and flushdb do not clean functions} {
|
||||
r function flush
|
||||
r function load REPLACE [get_function_code lua test test {return redis.call('set', 'x', '1')}]
|
||||
r function load REPLACE [get_function_code lua test test {return redict.call('set', 'x', '1')}]
|
||||
r flushall
|
||||
r flushdb
|
||||
r function list
|
||||
@ -215,19 +215,19 @@ start_server {tags {"scripting"}} {
|
||||
} {*unknown subcommand or wrong number of arguments for 'restore'. Try FUNCTION HELP.}
|
||||
|
||||
test {FUNCTION - test fcall_ro with write command} {
|
||||
r function load REPLACE [get_no_writes_function_code lua test test {return redis.call('set', 'x', '1')}]
|
||||
r function load REPLACE [get_no_writes_function_code lua test test {return redict.call('set', 'x', '1')}]
|
||||
catch { r fcall_ro test 1 x } e
|
||||
set _ $e
|
||||
} {*Write commands are not allowed from read-only scripts*}
|
||||
|
||||
test {FUNCTION - test fcall_ro with read only commands} {
|
||||
r function load REPLACE [get_no_writes_function_code lua test test {return redis.call('get', 'x')}]
|
||||
r function load REPLACE [get_no_writes_function_code lua test test {return redict.call('get', 'x')}]
|
||||
r set x 1
|
||||
r fcall_ro test 1 x
|
||||
} {1}
|
||||
|
||||
test {FUNCTION - test keys and argv} {
|
||||
r function load REPLACE [get_function_code lua test test {return redis.call('set', KEYS[1], ARGV[1])}]
|
||||
r function load REPLACE [get_function_code lua test test {return redict.call('set', KEYS[1], ARGV[1])}]
|
||||
r fcall test 1 x foo
|
||||
r get x
|
||||
} {foo}
|
||||
@ -323,7 +323,7 @@ start_server {tags {"scripting repl external:skip"}} {
|
||||
|
||||
test {FUNCTION - creation is replicated to replica} {
|
||||
r function load [get_no_writes_function_code LUA test test {return 'hello'}]
|
||||
wait_for_condition 150 100 {
|
||||
wait_for_condition 150 100 {
|
||||
[r -1 function list] eq {{library_name test engine LUA functions {{name test description {} flags no-writes}}}}
|
||||
} else {
|
||||
fail "Failed waiting for function to replicate to replica"
|
||||
@ -416,7 +416,7 @@ start_server {tags {"scripting repl external:skip"}} {
|
||||
} {*can't write against a read only replica*}
|
||||
|
||||
test "FUNCTION - function effect is replicated to replica" {
|
||||
r function load REPLACE [get_function_code LUA test test {return redis.call('set', 'x', '1')}]
|
||||
r function load REPLACE [get_function_code LUA test test {return redict.call('set', 'x', '1')}]
|
||||
r fcall test 1 x
|
||||
assert {[r get x] eq {1}}
|
||||
wait_for_condition 150 100 {
|
||||
@ -439,7 +439,7 @@ test {FUNCTION can processes create, delete and flush commands in AOF when doing
|
||||
start_server {} {
|
||||
r config set appendonly yes
|
||||
waitForBgrewriteaof r
|
||||
r FUNCTION LOAD "#!lua name=test\nredis.register_function('test', function() return 'hello' end)"
|
||||
r FUNCTION LOAD "#!lua name=test\nredict.register_function('test', function() return 'hello' end)"
|
||||
r config set slave-read-only yes
|
||||
r slaveof 127.0.0.1 0
|
||||
r debug loadaof
|
||||
@ -453,7 +453,7 @@ test {FUNCTION can processes create, delete and flush commands in AOF when doing
|
||||
r slaveof no one
|
||||
assert_equal [r function list] {}
|
||||
|
||||
r FUNCTION LOAD "#!lua name=test\nredis.register_function('test', function() return 'hello' end)"
|
||||
r FUNCTION LOAD "#!lua name=test\nredict.register_function('test', function() return 'hello' end)"
|
||||
r FUNCTION FLUSH
|
||||
|
||||
r slaveof 127.0.0.1 0
|
||||
@ -467,9 +467,9 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test shared function can access default globals} {
|
||||
r function load {#!lua name=lib1
|
||||
local function ping()
|
||||
return redis.call('ping')
|
||||
return redict.call('ping')
|
||||
end
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return ping()
|
||||
@ -484,13 +484,13 @@ start_server {tags {"scripting"}} {
|
||||
local function add1(a)
|
||||
return a + 1
|
||||
end
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return add1(1)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f2',
|
||||
function(keys, args)
|
||||
return add1(2)
|
||||
@ -508,13 +508,13 @@ start_server {tags {"scripting"}} {
|
||||
local function add1(a)
|
||||
return a + 2
|
||||
end
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return add1(1)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f2',
|
||||
'not a function'
|
||||
)
|
||||
@ -528,7 +528,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration function name collision} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return 1
|
||||
@ -544,13 +544,13 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration function name collision on same library} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return 1
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return 1
|
||||
@ -564,7 +564,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with no argument} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function()
|
||||
redict.register_function()
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -573,7 +573,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with only name} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function('f1')
|
||||
redict.register_function('f1')
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -582,7 +582,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with to many arguments} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function('f1', function() return 1 end, {}, 'description', 'extra arg')
|
||||
redict.register_function('f1', function() return 1 end, {}, 'description', 'extra arg')
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -591,7 +591,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with no string name} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function(nil, function() return 1 end)
|
||||
redict.register_function(nil, function() return 1 end)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -600,7 +600,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with wrong name format} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function('test\0test', function() return 1 end)
|
||||
redict.register_function('test\0test', function() return 1 end)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -609,7 +609,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - test registration with empty name} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
redis.register_function('', function() return 1 end)
|
||||
redict.register_function('', function() return 1 end)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -624,37 +624,37 @@ start_server {tags {"scripting"}} {
|
||||
set _ $e
|
||||
} {*attempted to access nonexistent global variable 'math'*}
|
||||
|
||||
test {LIBRARIES - redis.call from function load} {
|
||||
test {LIBRARIES - redict.call from function load} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
return redis.call('ping')
|
||||
return redict.call('ping')
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
} {*attempted to access nonexistent global variable 'call'*}
|
||||
|
||||
test {LIBRARIES - redis.setresp from function load} {
|
||||
test {LIBRARIES - redict.setresp from function load} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
return redis.setresp(3)
|
||||
return redict.setresp(3)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
} {*attempted to access nonexistent global variable 'setresp'*}
|
||||
|
||||
test {LIBRARIES - redis.set_repl from function load} {
|
||||
test {LIBRARIES - redict.set_repl from function load} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
return redis.set_repl(redis.REPL_NONE)
|
||||
return redict.set_repl(redict.REPL_NONE)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
} {*attempted to access nonexistent global variable 'set_repl'*}
|
||||
|
||||
test {LIBRARIES - redis.acl_check_cmd from function load} {
|
||||
test {LIBRARIES - redict.acl_check_cmd from function load} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib2
|
||||
return redis.acl_check_cmd('set','xx',1)
|
||||
return redict.acl_check_cmd('set','xx',1)
|
||||
}
|
||||
} e
|
||||
set _ $e
|
||||
@ -662,7 +662,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {LIBRARIES - malicious access test} {
|
||||
# the 'library' API is not exposed inside a
|
||||
# function context and the 'redis' API is not
|
||||
# function context and the 'redict' API is not
|
||||
# expose on the library registration context.
|
||||
# But a malicious user might find a way to hack it
|
||||
# (as demonstrated in this test). This is why we
|
||||
@ -670,16 +670,16 @@ start_server {tags {"scripting"}} {
|
||||
# code itself and we want to test it and verify
|
||||
# that it works properly.
|
||||
r function load replace {#!lua name=lib1
|
||||
local lib = redis
|
||||
local lib = redict
|
||||
lib.register_function('f1', function ()
|
||||
lib.redis = redis
|
||||
lib.redict = redict
|
||||
lib.math = math
|
||||
return {ok='OK'}
|
||||
end)
|
||||
|
||||
lib.register_function('f2', function ()
|
||||
lib.register_function('f1', function ()
|
||||
lib.redis = redis
|
||||
lib.redict = redict
|
||||
lib.math = math
|
||||
return {ok='OK'}
|
||||
end)
|
||||
@ -689,14 +689,14 @@ start_server {tags {"scripting"}} {
|
||||
assert_match {*Attempt to modify a readonly table*} $e
|
||||
|
||||
catch {[r function load {#!lua name=lib2
|
||||
redis.math.random()
|
||||
redict.math.random()
|
||||
}]} e
|
||||
assert_match {*Script attempted to access nonexistent global variable 'math'*} $e
|
||||
|
||||
catch {[r function load {#!lua name=lib2
|
||||
redis.redis.call('ping')
|
||||
redict.redict.call('ping')
|
||||
}]} e
|
||||
assert_match {*Script attempted to access nonexistent global variable 'redis'*} $e
|
||||
assert_match {*Script attempted to access nonexistent global variable 'redict'*} $e
|
||||
|
||||
catch {[r fcall f2 0]} e
|
||||
assert_match {*can only be called on FUNCTION LOAD command*} $e
|
||||
@ -709,10 +709,10 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {LIBRARIES - register function inside a function} {
|
||||
r function load {#!lua name=lib
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f2',
|
||||
function(key, args)
|
||||
return 2
|
||||
@ -757,7 +757,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {LIBRARIES - named arguments} {
|
||||
r function load {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback=function()
|
||||
return 'hello'
|
||||
@ -771,7 +771,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, bad function name} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name=function() return 1 end,
|
||||
callback=function()
|
||||
return 'hello'
|
||||
@ -786,7 +786,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, bad callback type} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback='bad',
|
||||
description='some desc'
|
||||
@ -799,7 +799,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, bad description} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback=function()
|
||||
return 'hello'
|
||||
@ -814,7 +814,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, unknown argument} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback=function()
|
||||
return 'hello'
|
||||
@ -830,7 +830,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, missing function name} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
callback=function()
|
||||
return 'hello'
|
||||
end,
|
||||
@ -844,7 +844,7 @@ start_server {tags {"scripting"}} {
|
||||
test {LIBRARIES - named arguments, missing callback} {
|
||||
catch {
|
||||
r function load replace {#!lua name=lib
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
description='desc'
|
||||
}
|
||||
@ -859,19 +859,19 @@ start_server {tags {"scripting"}} {
|
||||
local function add1(a)
|
||||
return a + 1
|
||||
end
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f1',
|
||||
function(keys, args)
|
||||
return add1(1)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f2',
|
||||
function(keys, args)
|
||||
return add1(2)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f3',
|
||||
function(keys, args)
|
||||
return add1(3)
|
||||
@ -883,7 +883,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
# load a library with different name but with the same function name
|
||||
r function load {#!lua name=lib1
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f6',
|
||||
function(keys, args)
|
||||
return 7
|
||||
@ -894,19 +894,19 @@ start_server {tags {"scripting"}} {
|
||||
local function add1(a)
|
||||
return a + 1
|
||||
end
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f4',
|
||||
function(keys, args)
|
||||
return add1(4)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f5',
|
||||
function(keys, args)
|
||||
return add1(5)
|
||||
end
|
||||
)
|
||||
redis.register_function(
|
||||
redict.register_function(
|
||||
'f3',
|
||||
function(keys, args)
|
||||
return add1(3)
|
||||
@ -932,14 +932,14 @@ start_server {tags {"scripting"}} {
|
||||
test {FUNCTION - test function list with code} {
|
||||
r function flush
|
||||
r function load {#!lua name=library1
|
||||
redis.register_function('f6', function(keys, args) return 7 end)
|
||||
redict.register_function('f6', function(keys, args) return 7 end)
|
||||
}
|
||||
r function list withcode
|
||||
} {{library_name library1 engine LUA functions {{name f6 description {} flags {}}} library_code {*redis.register_function('f6', function(keys, args) return 7 end)*}}}
|
||||
} {{library_name library1 engine LUA functions {{name f6 description {} flags {}}} library_code {*redict.register_function('f6', function(keys, args) return 7 end)*}}}
|
||||
|
||||
test {FUNCTION - test function list with pattern} {
|
||||
r function load {#!lua name=lib1
|
||||
redis.register_function('f7', function(keys, args) return 7 end)
|
||||
redict.register_function('f7', function(keys, args) return 7 end)
|
||||
}
|
||||
r function list libraryname library*
|
||||
} {{library_name library1 engine LUA functions {{name f6 description {} flags {}}}}}
|
||||
@ -967,14 +967,14 @@ start_server {tags {"scripting"}} {
|
||||
test {FUNCTION - verify OOM on function load and function restore} {
|
||||
r function flush
|
||||
r function load replace {#!lua name=test
|
||||
redis.register_function('f1', function() return 1 end)
|
||||
redict.register_function('f1', function() return 1 end)
|
||||
}
|
||||
set payload [r function dump]
|
||||
r config set maxmemory 1
|
||||
|
||||
r function flush
|
||||
catch {r function load replace {#!lua name=test
|
||||
redis.register_function('f1', function() return 1 end)
|
||||
redict.register_function('f1', function() return 1 end)
|
||||
}} e
|
||||
assert_match {*command not allowed when used memory*} $e
|
||||
|
||||
@ -987,9 +987,9 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - verify allow-omm allows running any command} {
|
||||
r FUNCTION load replace {#!lua name=f1
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback=function() return redis.call('set', 'x', '1') end,
|
||||
callback=function() return redict.call('set', 'x', '1') end,
|
||||
flags={'allow-oom'}
|
||||
}
|
||||
}
|
||||
@ -1006,7 +1006,7 @@ start_server {tags {"scripting"}} {
|
||||
start_server {tags {"scripting"}} {
|
||||
test {FUNCTION - wrong flags type named arguments} {
|
||||
catch {r function load replace {#!lua name=test
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name = 'f1',
|
||||
callback = function() return 1 end,
|
||||
flags = 'bad flags type'
|
||||
@ -1017,7 +1017,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - wrong flag type} {
|
||||
catch {r function load replace {#!lua name=test
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name = 'f1',
|
||||
callback = function() return 1 end,
|
||||
flags = {function() return 1 end}
|
||||
@ -1028,7 +1028,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - unknown flag} {
|
||||
catch {r function load replace {#!lua name=test
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name = 'f1',
|
||||
callback = function() return 1 end,
|
||||
flags = {'unknown'}
|
||||
@ -1039,9 +1039,9 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - write script on fcall_ro} {
|
||||
r function load replace {#!lua name=test
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name = 'f1',
|
||||
callback = function() return redis.call('set', 'x', 1) end
|
||||
callback = function() return redict.call('set', 'x', 1) end
|
||||
}
|
||||
}
|
||||
catch {r fcall_ro f1 1 x} e
|
||||
@ -1050,9 +1050,9 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - write script with no-writes flag} {
|
||||
r function load replace {#!lua name=test
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name = 'f1',
|
||||
callback = function() return redis.call('set', 'x', 1) end,
|
||||
callback = function() return redict.call('set', 'x', 1) end,
|
||||
flags = {'no-writes'}
|
||||
}
|
||||
}
|
||||
@ -1062,7 +1062,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - deny oom} {
|
||||
r FUNCTION load replace {#!lua name=test
|
||||
redis.register_function('f1', function() return redis.call('set', 'x', '1') end)
|
||||
redict.register_function('f1', function() return redict.call('set', 'x', '1') end)
|
||||
}
|
||||
|
||||
r config set maxmemory 1
|
||||
@ -1075,7 +1075,7 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - deny oom on no-writes function} {
|
||||
r FUNCTION load replace {#!lua name=test
|
||||
redis.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-writes'}}
|
||||
redict.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-writes'}}
|
||||
}
|
||||
|
||||
r config set maxmemory 1
|
||||
@ -1088,12 +1088,12 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - allow stale} {
|
||||
r FUNCTION load replace {#!lua name=test
|
||||
redis.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-writes'}}
|
||||
redis.register_function{function_name='f2', callback=function() return 'hello' end, flags={'allow-stale', 'no-writes'}}
|
||||
redis.register_function{function_name='f3', callback=function() return redis.call('get', 'x') end, flags={'allow-stale', 'no-writes'}}
|
||||
redis.register_function{function_name='f4', callback=function() return redis.call('info', 'server') end, flags={'allow-stale', 'no-writes'}}
|
||||
redict.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-writes'}}
|
||||
redict.register_function{function_name='f2', callback=function() return 'hello' end, flags={'allow-stale', 'no-writes'}}
|
||||
redict.register_function{function_name='f3', callback=function() return redict.call('get', 'x') end, flags={'allow-stale', 'no-writes'}}
|
||||
redict.register_function{function_name='f4', callback=function() return redict.call('info', 'server') end, flags={'allow-stale', 'no-writes'}}
|
||||
}
|
||||
|
||||
|
||||
r config set replica-serve-stale-data no
|
||||
r replicaof 127.0.0.1 1
|
||||
|
||||
@ -1114,15 +1114,15 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - redict version api} {
|
||||
r FUNCTION load replace {#!lua name=test
|
||||
local version = redis.REDICT_VERSION_NUM
|
||||
local version = redict.REDICT_VERSION_NUM
|
||||
|
||||
redis.register_function{function_name='get_version_v1', callback=function()
|
||||
redict.register_function{function_name='get_version_v1', callback=function()
|
||||
return string.format('%s.%s.%s',
|
||||
bit.band(bit.rshift(version, 16), 0x000000ff),
|
||||
bit.band(bit.rshift(version, 8), 0x000000ff),
|
||||
bit.band(version, 0x000000ff))
|
||||
end}
|
||||
redis.register_function{function_name='get_version_v2', callback=function() return redis.REDICT_VERSION end}
|
||||
redict.register_function{function_name='get_version_v2', callback=function() return redict.REDICT_VERSION end}
|
||||
}
|
||||
|
||||
catch {[r fcall f1 0]} e
|
||||
@ -1133,12 +1133,12 @@ start_server {tags {"scripting"}} {
|
||||
r FUNCTION FLUSH
|
||||
|
||||
r FUNCTION load {#!lua name=test1
|
||||
redis.register_function('f1', function() return 1 end)
|
||||
redis.register_function('f2', function() return 1 end)
|
||||
redict.register_function('f1', function() return 1 end)
|
||||
redict.register_function('f2', function() return 1 end)
|
||||
}
|
||||
|
||||
r FUNCTION load {#!lua name=test2
|
||||
redis.register_function('f3', function() return 1 end)
|
||||
redict.register_function('f3', function() return 1 end)
|
||||
}
|
||||
|
||||
r function stats
|
||||
@ -1158,15 +1158,15 @@ start_server {tags {"scripting"}} {
|
||||
r FUNCTION FLUSH
|
||||
|
||||
r FUNCTION load {#!lua name=test1
|
||||
redis.register_function('f1', function() return 1 end)
|
||||
redis.register_function('f2', function() return 1 end)
|
||||
redict.register_function('f1', function() return 1 end)
|
||||
redict.register_function('f2', function() return 1 end)
|
||||
}
|
||||
|
||||
catch {r FUNCTION load {#!lua name=test1
|
||||
redis.register_function('f3', function() return 1 end)
|
||||
redict.register_function('f3', function() return 1 end)
|
||||
}} e
|
||||
assert_match "*Library 'test1' already exists*" $e
|
||||
|
||||
|
||||
|
||||
r function stats
|
||||
} {running_script {} engines {LUA {libraries_count 1 functions_count 2}}}
|
||||
@ -1178,35 +1178,35 @@ start_server {tags {"scripting"}} {
|
||||
|
||||
test {FUNCTION - function test empty engine} {
|
||||
catch {r function load replace {#! name=test
|
||||
redis.register_function('foo', function() return 1 end)
|
||||
redict.register_function('foo', function() return 1 end)
|
||||
}} e
|
||||
set _ $e
|
||||
} {ERR Engine '' not found}
|
||||
|
||||
test {FUNCTION - function test unknown metadata value} {
|
||||
catch {r function load replace {#!lua name=test foo=bar
|
||||
redis.register_function('foo', function() return 1 end)
|
||||
redict.register_function('foo', function() return 1 end)
|
||||
}} e
|
||||
set _ $e
|
||||
} {ERR Invalid metadata value given: foo=bar}
|
||||
|
||||
test {FUNCTION - function test no name} {
|
||||
catch {r function load replace {#!lua
|
||||
redis.register_function('foo', function() return 1 end)
|
||||
redict.register_function('foo', function() return 1 end)
|
||||
}} e
|
||||
set _ $e
|
||||
} {ERR Library name was not given}
|
||||
|
||||
test {FUNCTION - function test multiple names} {
|
||||
catch {r function load replace {#!lua name=foo name=bar
|
||||
redis.register_function('foo', function() return 1 end)
|
||||
redict.register_function('foo', function() return 1 end)
|
||||
}} e
|
||||
set _ $e
|
||||
} {ERR Invalid metadata value, name argument was given multiple times}
|
||||
|
||||
test {FUNCTION - function test name with quotes} {
|
||||
r function load replace {#!lua name="foo"
|
||||
redis.register_function('foo', function() return 1 end)
|
||||
redict.register_function('foo', function() return 1 end)
|
||||
}
|
||||
} {foo}
|
||||
|
||||
@ -1214,7 +1214,7 @@ start_server {tags {"scripting"}} {
|
||||
r FUNCTION FLUSH
|
||||
|
||||
r FUNCTION load {#!lua name=test1
|
||||
redis.register_function('f1', function()
|
||||
redict.register_function('f1', function()
|
||||
mt = getmetatable(_G)
|
||||
original_globals = mt.__index
|
||||
original_globals['redict'] = function() return 1 end
|
||||
|
@ -146,7 +146,7 @@ start_server {tags {"info" "external:skip"}} {
|
||||
r config resetstat
|
||||
assert_match {} [errorstat ERR]
|
||||
assert_equal [s total_error_replies] 0
|
||||
catch {r eval {redis.pcall('XGROUP', 'CREATECONSUMER', 's1', 'mygroup', 'consumer') return } 0} e
|
||||
catch {r eval {redict.pcall('XGROUP', 'CREATECONSUMER', 's1', 'mygroup', 'consumer') return } 0} e
|
||||
assert_match {*count=1*} [errorstat ERR]
|
||||
assert_match {*calls=1,*,rejected_calls=0,failed_calls=1} [cmdstat xgroup\\|createconsumer]
|
||||
assert_match {*calls=1,*,rejected_calls=0,failed_calls=0} [cmdstat eval]
|
||||
@ -284,7 +284,7 @@ start_server {tags {"info" "external:skip"}} {
|
||||
r config resetstat
|
||||
for {set j 1} {$j <= 1100} {incr j} {
|
||||
assert_error "$j my error message" {
|
||||
r eval {return redis.error_reply(string.format('%s my error message', ARGV[1]))} 0 $j
|
||||
r eval {return redict.error_reply(string.format('%s my error message', ARGV[1]))} 0 $j
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ start_server {tags {"info" "external:skip"}} {
|
||||
assert_morethan $cycle1 0
|
||||
assert_morethan $el_sum1 0
|
||||
assert_morethan $cmd_sum1 0
|
||||
after 110 ;# default hz is 10, wait for a cron tick.
|
||||
after 110 ;# default hz is 10, wait for a cron tick.
|
||||
set info2 [r info stats]
|
||||
set cycle2 [getInfoProperty $info2 eventloop_cycles]
|
||||
set el_sum2 [getInfoProperty $info2 eventloop_duration_sum]
|
||||
@ -512,7 +512,7 @@ start_server {tags {"info" "external:skip"}} {
|
||||
assert_equal [dict get $mem_stats db.dict.rehashing.count] {0}
|
||||
# set 4 more keys to trigger rehashing
|
||||
# get the info within a transaction to make sure the rehashing is not completed
|
||||
r multi
|
||||
r multi
|
||||
r set b c
|
||||
r set c d
|
||||
r set d e
|
||||
|
@ -114,9 +114,9 @@ start_server {tags {"introspection"}} {
|
||||
r config resetstat
|
||||
r set mykey myval
|
||||
r eval {
|
||||
redis.call('set', KEYS[1], 0)
|
||||
redis.call('expire', KEYS[1], 0)
|
||||
redis.call('geoadd', KEYS[1], 0, 0, "bar")
|
||||
redict.call('set', KEYS[1], 0)
|
||||
redict.call('expire', KEYS[1], 0)
|
||||
redict.call('geoadd', KEYS[1], 0, 0, "bar")
|
||||
} 1 mykey
|
||||
assert_match {*calls=1,*} [cmdstat eval]
|
||||
assert_match {*calls=2,*} [cmdstat set]
|
||||
|
@ -224,7 +224,7 @@ start_server {tags {"introspection"}} {
|
||||
set rd [redict_deferring_client]
|
||||
$rd monitor
|
||||
$rd read ;# Discard the OK
|
||||
r eval {redis.call('set',KEYS[1],ARGV[1])} 1 foo bar
|
||||
r eval {redict.call('set',KEYS[1],ARGV[1])} 1 foo bar
|
||||
assert_match {*eval*} [$rd read]
|
||||
assert_match {*lua*"set"*"foo"*"bar"*} [$rd read]
|
||||
$rd close
|
||||
@ -232,7 +232,7 @@ start_server {tags {"introspection"}} {
|
||||
|
||||
test {MONITOR can log commands issued by functions} {
|
||||
r function load replace {#!lua name=test
|
||||
redis.register_function('test', function() return redis.call('set', 'foo', 'bar') end)
|
||||
redict.register_function('test', function() return redict.call('set', 'foo', 'bar') end)
|
||||
}
|
||||
set rd [redict_deferring_client]
|
||||
$rd monitor
|
||||
@ -253,7 +253,7 @@ 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} _
|
||||
|
||||
|
||||
assert_match {*"key"*"9"*"5000"*} [$rd read]
|
||||
assert_match {*"key"*"9"*"5000"*"(redacted)"*} [$rd read]
|
||||
assert_match {*"key"*"9"*"5000"*"(redacted)"*"(redacted)"*} [$rd read]
|
||||
@ -296,46 +296,46 @@ start_server {tags {"introspection"}} {
|
||||
|
||||
$rd close
|
||||
}
|
||||
|
||||
|
||||
test {MONITOR log blocked command only once} {
|
||||
|
||||
|
||||
# need to reconnect in order to reset the clients state
|
||||
reconnect
|
||||
|
||||
|
||||
set rd [redict_deferring_client]
|
||||
set bc [redict_deferring_client]
|
||||
r del mylist
|
||||
|
||||
|
||||
$rd monitor
|
||||
$rd read ; # Discard the OK
|
||||
|
||||
|
||||
$bc blpop mylist 0
|
||||
wait_for_blocked_clients_count 1
|
||||
r lpush mylist 1
|
||||
wait_for_blocked_clients_count 0
|
||||
r lpush mylist 2
|
||||
|
||||
|
||||
# we expect to see the blpop on the monitor first
|
||||
assert_match {*"blpop"*"mylist"*"0"*} [$rd read]
|
||||
|
||||
|
||||
# we scan out all the info commands on the monitor
|
||||
set monitor_output [$rd read]
|
||||
while { [string match {*"info"*} $monitor_output] } {
|
||||
set monitor_output [$rd read]
|
||||
}
|
||||
|
||||
|
||||
# we expect to locate the lpush right when the client was unblocked
|
||||
assert_match {*"lpush"*"mylist"*"1"*} $monitor_output
|
||||
|
||||
|
||||
# we scan out all the info commands
|
||||
set monitor_output [$rd read]
|
||||
while { [string match {*"info"*} $monitor_output] } {
|
||||
set monitor_output [$rd read]
|
||||
}
|
||||
|
||||
|
||||
# we expect to see the next lpush and not duplicate blpop command
|
||||
assert_match {*"lpush"*"mylist"*"2"*} $monitor_output
|
||||
|
||||
|
||||
$rd close
|
||||
$bc close
|
||||
}
|
||||
@ -574,7 +574,7 @@ start_server {tags {"introspection"}} {
|
||||
assert_equal [r config get save] {save {}}
|
||||
}
|
||||
} {} {external:skip}
|
||||
|
||||
|
||||
test {CONFIG SET with multiple args} {
|
||||
set some_configs {maxmemory 10000001 repl-backlog-size 10000002 save {3000 5}}
|
||||
|
||||
@ -596,7 +596,7 @@ start_server {tags {"introspection"}} {
|
||||
|
||||
test {CONFIG SET rollback on set error} {
|
||||
# This test passes an invalid percent value to maxmemory-clients which should cause an
|
||||
# input verification failure during the "set" phase before trying to apply the
|
||||
# input verification failure during the "set" phase before trying to apply the
|
||||
# configuration. We want to make sure the correct failure happens and everything
|
||||
# is rolled back.
|
||||
# backup maxmemory config
|
||||
@ -619,7 +619,7 @@ start_server {tags {"introspection"}} {
|
||||
|
||||
test {CONFIG SET rollback on apply error} {
|
||||
# This test tries to configure a used port number in redict. This is expected
|
||||
# to pass the `CONFIG SET` validity checking implementation but fail on
|
||||
# to pass the `CONFIG SET` validity checking implementation but fail on
|
||||
# actual "apply" of the setting. This will validate that after an "apply"
|
||||
# failure we rollback to the previous values.
|
||||
proc dummy_accept {chan addr port} {}
|
||||
@ -651,8 +651,8 @@ start_server {tags {"introspection"}} {
|
||||
set used_port [find_available_port $::baseport $::portcount]
|
||||
dict set some_configs port $used_port
|
||||
|
||||
# Run a dummy server on used_port so we know we can't configure redict to
|
||||
# use it. It's ok for this to fail because that means used_port is invalid
|
||||
# Run a dummy server on used_port so we know we can't configure redict to
|
||||
# use it. It's ok for this to fail because that means used_port is invalid
|
||||
# anyway
|
||||
catch {socket -server dummy_accept -myaddr 127.0.0.1 $used_port} e
|
||||
if {$::verbose} { puts "dummy_accept: $e" }
|
||||
@ -698,18 +698,18 @@ start_server {tags {"introspection"}} {
|
||||
|
||||
test {CONFIG GET multiple args} {
|
||||
set res [r config get maxmemory maxmemory* bind *of]
|
||||
|
||||
|
||||
# Verify there are no duplicates in the result
|
||||
assert_equal [expr [llength [dict keys $res]]*2] [llength $res]
|
||||
|
||||
|
||||
# Verify we got both name and alias in result
|
||||
assert {[dict exists $res slaveof] && [dict exists $res replicaof]}
|
||||
assert {[dict exists $res slaveof] && [dict exists $res replicaof]}
|
||||
|
||||
# Verify pattern found multiple maxmemory* configs
|
||||
assert {[dict exists $res maxmemory] && [dict exists $res maxmemory-samples] && [dict exists $res maxmemory-clients]}
|
||||
assert {[dict exists $res maxmemory] && [dict exists $res maxmemory-samples] && [dict exists $res maxmemory-clients]}
|
||||
|
||||
# Verify we also got the explicit config
|
||||
assert {[dict exists $res bind]}
|
||||
assert {[dict exists $res bind]}
|
||||
}
|
||||
|
||||
test {redict-server command line arguments - error cases} {
|
||||
|
@ -155,7 +155,7 @@ tags {"needs:debug"} {
|
||||
r eval {
|
||||
local i = 0
|
||||
while (i < tonumber(ARGV[1])) do
|
||||
redis.call('sadd',KEYS[1],i)
|
||||
redict.call('sadd',KEYS[1],i)
|
||||
i = i+1
|
||||
end
|
||||
} 1 mybigkey $count
|
||||
|
@ -44,15 +44,15 @@ start_server {tags {"modules"}} {
|
||||
r lrange log-key 0 -1
|
||||
} "{ping @log}"
|
||||
|
||||
test {Command Filter applies on Lua redis.call()} {
|
||||
test {Command Filter applies on Lua redict.call()} {
|
||||
r del log-key
|
||||
r eval "redis.call('ping', '@log')" 0
|
||||
r eval "redict.call('ping', '@log')" 0
|
||||
r lrange log-key 0 -1
|
||||
} "{ping @log}"
|
||||
|
||||
test {Command Filter applies on Lua redis.call() that calls a module} {
|
||||
test {Command Filter applies on Lua redict.call() that calls a module} {
|
||||
r del log-key
|
||||
r eval "redis.call('commandfilter.ping')" 0
|
||||
r eval "redict.call('commandfilter.ping')" 0
|
||||
r lrange log-key 0 -1
|
||||
} "{ping @log}"
|
||||
|
||||
@ -86,7 +86,7 @@ start_server {tags {"modules"}} {
|
||||
r module unload commandfilter
|
||||
r module load $testmodule log-key 1
|
||||
|
||||
test {Command Filter REDISMODULE_CMDFILTER_NOSELF works as expected} {
|
||||
test {Command Filter REDICTMODULE_CMDFILTER_NOSELF works as expected} {
|
||||
r set mykey @log
|
||||
assert_equal "{set mykey @log}" [r lrange log-key 0 -1]
|
||||
|
||||
@ -94,7 +94,7 @@ start_server {tags {"modules"}} {
|
||||
r commandfilter.ping
|
||||
assert_equal {} [r lrange log-key 0 -1]
|
||||
|
||||
r eval "redis.call('commandfilter.ping')" 0
|
||||
r eval "redict.call('commandfilter.ping')" 0
|
||||
assert_equal {} [r lrange log-key 0 -1]
|
||||
}
|
||||
|
||||
@ -113,11 +113,11 @@ test {RM_CommandFilterArgInsert and script argv caching} {
|
||||
r module load $testmodule log-key 0
|
||||
r del mylist
|
||||
# command with 6 args
|
||||
r eval {redis.call('rpush', KEYS[1], 'elem1', 'elem2', 'elem3', 'elem4')} 1 mylist
|
||||
r eval {redict.call('rpush', KEYS[1], 'elem1', 'elem2', 'elem3', 'elem4')} 1 mylist
|
||||
# command with 3 args that is changed to 4
|
||||
r eval {redis.call('rpush', KEYS[1], '@insertafter')} 1 mylist
|
||||
r eval {redict.call('rpush', KEYS[1], '@insertafter')} 1 mylist
|
||||
# command with 6 args again
|
||||
r eval {redis.call('rpush', KEYS[1], 'elem1', 'elem2', 'elem3', 'elem4')} 1 mylist
|
||||
r eval {redict.call('rpush', KEYS[1], 'elem1', 'elem2', 'elem3', 'elem4')} 1 mylist
|
||||
assert_equal [r lrange mylist 0 -1] {elem1 elem2 elem3 elem4 @insertafter --inserted-after-- elem1 elem2 elem3 elem4}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ tags "modules" {
|
||||
assert_equal {} [r get lua]
|
||||
r get x
|
||||
} {3}
|
||||
|
||||
|
||||
test {Nested multi due to RM_Call, with client MULTI} {
|
||||
r del multi
|
||||
r del lua
|
||||
@ -56,7 +56,7 @@ tags "modules" {
|
||||
assert_equal {} [r get lua]
|
||||
r get x
|
||||
} {3}
|
||||
|
||||
|
||||
test {Nested multi due to RM_Call, with EVAL} {
|
||||
r del multi
|
||||
r del lua
|
||||
@ -64,10 +64,10 @@ tags "modules" {
|
||||
r set x 1
|
||||
r set x_copy 1
|
||||
r eval {
|
||||
redis.pcall('keyspace.del_key_copy', KEYS[1])
|
||||
redis.pcall('keyspace.incr_case1', KEYS[1])
|
||||
redis.pcall('keyspace.incr_case2', KEYS[1])
|
||||
redis.pcall('keyspace.incr_case3', KEYS[1])
|
||||
redict.pcall('keyspace.del_key_copy', KEYS[1])
|
||||
redict.pcall('keyspace.incr_case1', KEYS[1])
|
||||
redict.pcall('keyspace.incr_case2', KEYS[1])
|
||||
redict.pcall('keyspace.incr_case3', KEYS[1])
|
||||
} 1 x
|
||||
assert_equal {} [r get multi]
|
||||
assert_equal {1} [r get lua]
|
||||
|
@ -35,7 +35,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
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"]}
|
||||
@ -52,7 +52,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
test {test RedictModule_ResetDataset do not reset functions} {
|
||||
r function load {#!lua name=lib
|
||||
redis.register_function('test', function() return 1 end)
|
||||
redict.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
|
||||
@ -147,7 +147,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
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}
|
||||
$rd_trk test.rm_call EVAL "redict.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]
|
||||
@ -254,7 +254,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
# 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)
|
||||
redict.call('set','x',1)
|
||||
return 1
|
||||
} 1 x
|
||||
}
|
||||
@ -262,7 +262,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
# 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)
|
||||
redict.call('set','x',1)
|
||||
return 1
|
||||
} 1 x
|
||||
]
|
||||
@ -282,13 +282,13 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
test {rm_call EVAL} {
|
||||
r test.rm_call eval {
|
||||
redis.call('set','x',1)
|
||||
redict.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)
|
||||
redict.call('set','x',1)
|
||||
return 1
|
||||
} 1 x
|
||||
}
|
||||
@ -301,34 +301,34 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
# 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)
|
||||
redict.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)
|
||||
redict.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')
|
||||
redict.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')
|
||||
redict.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')
|
||||
redict.call('get','x')
|
||||
return 4
|
||||
} 1 x
|
||||
|
||||
@ -341,19 +341,19 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
# no shebang at all
|
||||
r test.rm_call eval {
|
||||
redis.call('set','x',1)
|
||||
redict.call('set','x',1)
|
||||
return 6
|
||||
} 1 x
|
||||
|
||||
# Shebang without flags
|
||||
r test.rm_call eval {#!lua
|
||||
redis.call('set','x', 1)
|
||||
redict.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)
|
||||
redict.call('set','x', 1)
|
||||
return 8
|
||||
} 1 x
|
||||
|
||||
@ -369,25 +369,25 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
assert_equal [
|
||||
r test.rm_call eval {#!lua flags=no-writes
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
] "some value"
|
||||
|
||||
assert_equal [
|
||||
r test.rm_call eval {
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
] "some value"
|
||||
|
||||
assert_error {NOREPLICAS *} {
|
||||
r test.rm_call eval {#!lua
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
}
|
||||
|
||||
assert_error {NOREPLICAS *} {
|
||||
r test.rm_call eval {
|
||||
return redis.call('set','x', 1)
|
||||
return redict.call('set','x', 1)
|
||||
} 1 x
|
||||
}
|
||||
|
||||
@ -402,25 +402,25 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
assert_error {READONLY You can't write against a read only replica. script*} {
|
||||
r test.rm_call eval {
|
||||
redis.call('set','x',1)
|
||||
redict.call('set','x',1)
|
||||
return 1
|
||||
} 1 x
|
||||
}
|
||||
|
||||
r test.rm_call eval {#!lua flags=no-writes
|
||||
redis.call('get','x')
|
||||
redict.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')
|
||||
redict.call('get','x')
|
||||
return 3
|
||||
} 1 x
|
||||
}
|
||||
|
||||
r test.rm_call eval {
|
||||
redis.call('get','x')
|
||||
redict.call('get','x')
|
||||
return 4
|
||||
} 1 x
|
||||
|
||||
@ -438,14 +438,14 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
assert_error {MASTERDOWN *} {
|
||||
r test.rm_call eval {#!lua flags=no-writes
|
||||
redis.call('get','x')
|
||||
redict.call('get','x')
|
||||
return 2
|
||||
} 1 x
|
||||
}
|
||||
|
||||
assert_error {MASTERDOWN *} {
|
||||
r test.rm_call eval {
|
||||
redis.call('get','x')
|
||||
redict.call('get','x')
|
||||
return 4
|
||||
} 1 x
|
||||
}
|
||||
@ -474,21 +474,21 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
||||
|
||||
# repeate with script
|
||||
assert_error {MISCONF *} {r test.rm_call eval {
|
||||
return redis.call('set','x',1)
|
||||
return redict.call('set','x',1)
|
||||
} 1 x
|
||||
}
|
||||
assert_equal {x} [r test.rm_call eval {
|
||||
return redis.call('get','x')
|
||||
return redict.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)
|
||||
return redict.call('set','x',1)
|
||||
} 1 x
|
||||
}
|
||||
assert_equal {x} [r test.rm_call eval {#!lua flags=no-writes
|
||||
return redis.call('get','x')
|
||||
return redict.call('get','x')
|
||||
} 1 x
|
||||
]
|
||||
|
||||
|
@ -143,7 +143,7 @@ tags "modules" {
|
||||
$master set asdf1 1
|
||||
$master set asdf2 2
|
||||
$master set asdf3 3
|
||||
|
||||
|
||||
$master config set maxmemory-policy allkeys-random
|
||||
$master config set maxmemory 1
|
||||
|
||||
@ -160,7 +160,7 @@ tags "modules" {
|
||||
# that performs `RedictModule_Call(ctx, "INCR", "c", "multi");` if the notification is inside multi exec.
|
||||
# so we will have 2 keys, "notifications" and "multi".
|
||||
wait_for_condition 500 10 {
|
||||
[$replica dbsize] eq 2
|
||||
[$replica dbsize] eq 2
|
||||
} else {
|
||||
fail "Not all keys have been evicted"
|
||||
}
|
||||
@ -452,9 +452,9 @@ tags "modules" {
|
||||
set repl [attach_to_replication_stream]
|
||||
|
||||
assert_equal [ $master eval { \
|
||||
redis.call("propagate-test.simple"); \
|
||||
redis.call("set", "x", "y"); \
|
||||
redis.call("propagate-test.mixed"); return "OK" } 0 ] {OK}
|
||||
redict.call("propagate-test.simple"); \
|
||||
redict.call("set", "x", "y"); \
|
||||
redict.call("propagate-test.mixed"); return "OK" } 0 ] {OK}
|
||||
|
||||
assert_replication_stream $repl {
|
||||
{multi}
|
||||
@ -647,7 +647,7 @@ tags "modules" {
|
||||
set repl [attach_to_replication_stream]
|
||||
|
||||
$master flushall
|
||||
|
||||
|
||||
$master get unexisting_key
|
||||
|
||||
wait_for_condition 500 10 {
|
||||
@ -667,7 +667,7 @@ tags "modules" {
|
||||
{get unexisting_key}
|
||||
{exec}
|
||||
}
|
||||
|
||||
|
||||
close_replication_stream $repl
|
||||
}
|
||||
|
||||
@ -734,23 +734,23 @@ tags "modules aof" {
|
||||
r config set appendonly yes
|
||||
r config set auto-aof-rewrite-percentage 0 ; # Disable auto-rewrite.
|
||||
waitForBgrewriteaof r
|
||||
|
||||
|
||||
r config resetstat
|
||||
r set foo bar
|
||||
r EVAL {return redis.call('SET', KEYS[1], ARGV[1])} 1 foo bar2
|
||||
r EVAL {return redict.call('SET', KEYS[1], ARGV[1])} 1 foo bar2
|
||||
r test.rm_call_replicate set foo bar3
|
||||
r EVAL {return redis.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar4
|
||||
|
||||
r EVAL {return redict.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar4
|
||||
|
||||
r multi
|
||||
r set foo bar5
|
||||
r EVAL {return redis.call('SET', KEYS[1], ARGV[1])} 1 foo bar6
|
||||
r EVAL {return redict.call('SET', KEYS[1], ARGV[1])} 1 foo bar6
|
||||
r test.rm_call_replicate set foo bar7
|
||||
r EVAL {return redis.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar8
|
||||
r EVAL {return redict.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar8
|
||||
r exec
|
||||
|
||||
assert_match {*calls=8,*,rejected_calls=0,failed_calls=0} [cmdrstat set r]
|
||||
|
||||
|
||||
|
||||
|
||||
# Load the AOF
|
||||
if {$aofload_type == "debug_cmd"} {
|
||||
r config resetstat
|
||||
@ -760,9 +760,9 @@ tags "modules aof" {
|
||||
restart_server 0 true false
|
||||
wait_done_loading r
|
||||
}
|
||||
|
||||
|
||||
assert_no_match {*calls=*} [cmdrstat set r]
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ tags "modules" {
|
||||
$master config set repl-diskless-sync-delay 0
|
||||
$master config set save ""
|
||||
$replica config set repl-diskless-load swapdb
|
||||
$replica config set save ""
|
||||
$replica config set save ""
|
||||
|
||||
# Initial sync to have matching replids between master and replica
|
||||
$replica replicaof $master_host $master_port
|
||||
@ -252,11 +252,11 @@ tags "modules" {
|
||||
|
||||
test {Diskless load swapdb RedictModuleEvent_ReplAsyncLoad handling: during loading, can keep module variable same as before} {
|
||||
# Wait for the replica to start reading the rdb and module for acknowledgement
|
||||
# We wanna abort only after the temp db was populated by REDISMODULE_AUX_BEFORE_RDB
|
||||
# We wanna abort only after the temp db was populated by REDICTMODULE_AUX_BEFORE_RDB
|
||||
wait_for_condition 100 100 {
|
||||
[s -1 async_loading] eq 1 && [$replica testrdb.async_loading.get.before] eq "value1_master"
|
||||
} else {
|
||||
fail "Module didn't receive or react to REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED"
|
||||
fail "Module didn't receive or react to REDICTMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED"
|
||||
}
|
||||
|
||||
assert_equal [$replica dbsize] 200
|
||||
@ -274,7 +274,7 @@ tags "modules" {
|
||||
wait_for_condition 100 100 {
|
||||
[s -1 async_loading] eq 0 && [$replica testrdb.async_loading.get.before] eq ""
|
||||
} else {
|
||||
fail "Module didn't receive or react to REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED"
|
||||
fail "Module didn't receive or react to REDICTMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED"
|
||||
}
|
||||
|
||||
assert_equal [$replica dbsize] 200
|
||||
|
@ -7,11 +7,11 @@
|
||||
set testmodule [file normalize tests/modules/usercall.so]
|
||||
|
||||
set test_script_set "#!lua
|
||||
redis.call('set','x',1)
|
||||
redict.call('set','x',1)
|
||||
return 1"
|
||||
|
||||
set test_script_get "#!lua
|
||||
redis.call('get','x')
|
||||
redict.call('get','x')
|
||||
return 1"
|
||||
|
||||
start_server {tags {"modules usercall"}} {
|
||||
|
@ -764,7 +764,7 @@ start_server {tags {"multi"}} {
|
||||
|
||||
# make sure that SCRIPT LOAD inside MULTI isn't propagated
|
||||
r multi
|
||||
r script load {redis.call('set', KEYS[1], 'foo')}
|
||||
r script load {redict.call('set', KEYS[1], 'foo')}
|
||||
r set foo bar
|
||||
set res [r exec]
|
||||
set sha [lindex $res 0]
|
||||
@ -781,7 +781,7 @@ start_server {tags {"multi"}} {
|
||||
|
||||
# make sure that EVAL inside MULTI is propagated in a transaction in effects
|
||||
r multi
|
||||
r eval {redis.call('set', KEYS[1], 'bar')} 1 bar
|
||||
r eval {redict.call('set', KEYS[1], 'bar')} 1 bar
|
||||
r exec
|
||||
|
||||
assert_replication_stream $repl {
|
||||
@ -902,7 +902,7 @@ start_server {tags {"multi"}} {
|
||||
r readraw 0
|
||||
set _ $res
|
||||
} {*CONFIG SET failed*}
|
||||
|
||||
|
||||
test "Flushall while watching several keys by one client" {
|
||||
r flushall
|
||||
r mset a{t} a b{t} b
|
||||
|
@ -82,7 +82,7 @@ start_server {tags {"pause network"}} {
|
||||
$rd2 publish foo bar
|
||||
wait_for_blocked_clients_count 2 50 100
|
||||
|
||||
r client unpause
|
||||
r client unpause
|
||||
assert_match "1" [$rd read]
|
||||
assert_match "0" [$rd2 read]
|
||||
$rd close
|
||||
@ -98,7 +98,7 @@ start_server {tags {"pause network"}} {
|
||||
assert_equal [$rr GET FOO] "QUEUED"
|
||||
assert_match "PONG BAR" [$rr EXEC]
|
||||
assert_equal [s 0 blocked_clients] 0
|
||||
r client unpause
|
||||
r client unpause
|
||||
$rr close
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ start_server {tags {"pause network"}} {
|
||||
r client PAUSE 60000 WRITE
|
||||
$rd EXEC
|
||||
wait_for_blocked_clients_count 1 50 100
|
||||
r client unpause
|
||||
r client unpause
|
||||
assert_match "OK" [$rd read]
|
||||
$rd close
|
||||
}
|
||||
@ -128,7 +128,7 @@ start_server {tags {"pause network"}} {
|
||||
} 0
|
||||
|
||||
wait_for_blocked_clients_count 2 50 100
|
||||
r client unpause
|
||||
r client unpause
|
||||
assert_match "1" [$rd read]
|
||||
assert_match "1" [$rd2 read]
|
||||
$rd close
|
||||
@ -139,7 +139,7 @@ start_server {tags {"pause network"}} {
|
||||
r set x y
|
||||
# create a function for later
|
||||
r FUNCTION load replace {#!lua name=f1
|
||||
redis.register_function{
|
||||
redict.register_function{
|
||||
function_name='f1',
|
||||
callback=function() return "hello" end,
|
||||
flags={'no-writes'}
|
||||
@ -163,7 +163,7 @@ start_server {tags {"pause network"}} {
|
||||
|
||||
# test EVAL_RO on a unique script that's for sure not in the cache
|
||||
assert_equal [$rr EVAL_RO {
|
||||
return redis.call('GeT', 'x')..' unique script'
|
||||
return redict.call('GeT', 'x')..' unique script'
|
||||
} 1 x
|
||||
] "y unique script"
|
||||
|
||||
@ -233,15 +233,15 @@ start_server {tags {"pause network"}} {
|
||||
test "Test may-replicate commands are rejected in RO scripts" {
|
||||
# that's specifically important for CLIENT PAUSE WRITE
|
||||
assert_error {ERR Write commands are not allowed from read-only scripts. script:*} {
|
||||
r EVAL_RO "return redis.call('publish','ch','msg')" 0
|
||||
r EVAL_RO "return redict.call('publish','ch','msg')" 0
|
||||
}
|
||||
assert_error {ERR Write commands are not allowed from read-only scripts. script:*} {
|
||||
r EVAL {#!lua flags=no-writes
|
||||
return redis.call('publish','ch','msg')
|
||||
return redict.call('publish','ch','msg')
|
||||
} 0
|
||||
}
|
||||
# make sure that publish isn't blocked from a non-RO script
|
||||
assert_equal [r EVAL "return redis.call('publish','ch','msg')" 0] 0
|
||||
assert_equal [r EVAL "return redict.call('publish','ch','msg')" 0] 0
|
||||
}
|
||||
|
||||
test "Test multiple clients can be queued up and unblocked" {
|
||||
@ -290,7 +290,7 @@ start_server {tags {"pause network"}} {
|
||||
r get bar{t}
|
||||
|
||||
# Now that clients have been unpaused, expires should go through
|
||||
assert_match [expr $expired_keys + 2] [s 0 expired_keys]
|
||||
assert_match [expr $expired_keys + 2] [s 0 expired_keys]
|
||||
}
|
||||
|
||||
test "Test that client pause starts at the end of a transaction" {
|
||||
@ -309,7 +309,7 @@ start_server {tags {"pause network"}} {
|
||||
assert_match "BAR" [r GET FOO2{t}]
|
||||
assert_match "" [r GET FOO3{t}]
|
||||
|
||||
r client unpause
|
||||
r client unpause
|
||||
assert_match "OK" [$rd read]
|
||||
$rd close
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ start_server {tags {"pubsub network"}} {
|
||||
assert_equal {1} [psubscribe $rd1 *]
|
||||
r set foo bar
|
||||
# second set of foo should not cause a 'new' event
|
||||
r set foo baz
|
||||
r set foo baz
|
||||
r set bar bar
|
||||
assert_equal "pmessage * __keyevent@${db}__:new foo" [$rd1 read]
|
||||
assert_equal "pmessage * __keyevent@${db}__:new bar" [$rd1 read]
|
||||
@ -475,10 +475,10 @@ start_server {tags {"pubsub network"}} {
|
||||
r hello 3
|
||||
r subscribe foo
|
||||
set res [r eval {
|
||||
redis.call("ping","abc")
|
||||
redis.call("publish","foo","bar")
|
||||
redis.call("publish","foo","vaz")
|
||||
redis.call("ping","def")
|
||||
redict.call("ping","abc")
|
||||
redict.call("publish","foo","bar")
|
||||
redict.call("publish","foo","vaz")
|
||||
redict.call("ping","def")
|
||||
return "bla"} 0]
|
||||
assert_equal $res {bla}
|
||||
assert_equal [r read] {message foo bar}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -117,7 +117,7 @@ foreach command {SORT SORT_RO} {
|
||||
test "SORT extracts STORE correctly" {
|
||||
r command getkeys sort abc store def
|
||||
} {abc def}
|
||||
|
||||
|
||||
test "SORT_RO get keys" {
|
||||
r command getkeys sort_ro abc
|
||||
} {abc}
|
||||
@ -185,8 +185,8 @@ foreach command {SORT SORT_RO} {
|
||||
r zadd zset 10 d
|
||||
r zadd zset 3 e
|
||||
r eval {
|
||||
return {redis.call('sort',KEYS[1],'by','nosort','asc'),
|
||||
redis.call('sort',KEYS[1],'by','nosort','desc')}
|
||||
return {redict.call('sort',KEYS[1],'by','nosort','asc'),
|
||||
redict.call('sort',KEYS[1],'by','nosort','desc')}
|
||||
} 1 zset
|
||||
} {{a c e b d} {d b e c a}}
|
||||
|
||||
|
@ -20,7 +20,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
|
||||
# Client to be used for SET and GET commands
|
||||
# We don't read this client's buffer
|
||||
set rd_sg [redict_client]
|
||||
set rd_sg [redict_client]
|
||||
|
||||
proc clean_all {} {
|
||||
uplevel {
|
||||
@ -223,7 +223,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
assert_equal "1" [$rd_sg GET key1]
|
||||
|
||||
# For write command in script, invalid key should not be tracked with NOLOOP flag
|
||||
$rd_sg eval "return redis.call('set', 'key1', '2')" 1 key1
|
||||
$rd_sg eval "return redict.call('set', 'key1', '2')" 1 key1
|
||||
assert_equal "2" [$rd_sg GET key1]
|
||||
$rd_sg CLIENT TRACKING off
|
||||
}
|
||||
@ -234,12 +234,12 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
$rd_sg MSET key2{t} 1 key2{t} 1
|
||||
|
||||
# If a script doesn't call any read command, don't track any keys
|
||||
r EVAL "redis.call('set', 'key3{t}', 'bar')" 2 key1{t} key2{t}
|
||||
r EVAL "redict.call('set', 'key3{t}', 'bar')" 2 key1{t} key2{t}
|
||||
$rd_sg MSET key2{t} 2 key1{t} 2
|
||||
assert_equal "PONG" [r ping]
|
||||
|
||||
# If a script calls a read command, just the read keys
|
||||
r EVAL "redis.call('get', 'key2{t}')" 2 key1{t} key2{t}
|
||||
r EVAL "redict.call('get', 'key2{t}')" 2 key1{t} key2{t}
|
||||
$rd_sg MSET key2{t} 2 key3{t} 2
|
||||
assert_equal {invalidate key2{t}} [r read]
|
||||
assert_equal "PONG" [r ping]
|
||||
@ -247,12 +247,12 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
# RO variants work like the normal variants
|
||||
|
||||
# If a RO script doesn't call any read command, don't track any keys
|
||||
r EVAL_RO "redis.call('ping')" 2 key1{t} key2{t}
|
||||
r EVAL_RO "redict.call('ping')" 2 key1{t} key2{t}
|
||||
$rd_sg MSET key2{t} 2 key1{t} 2
|
||||
assert_equal "PONG" [r ping]
|
||||
|
||||
# If a RO script calls a read command, just the read keys
|
||||
r EVAL_RO "redis.call('get', 'key2{t}')" 2 key1{t} key2{t}
|
||||
r EVAL_RO "redict.call('get', 'key2{t}')" 2 key1{t} key2{t}
|
||||
$rd_sg MSET key2{t} 2 key3{t} 2
|
||||
assert_equal {invalidate key2{t}} [r read]
|
||||
assert_equal "PONG" [r ping]
|
||||
@ -284,11 +284,11 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
|
||||
test {Different clients can redirect to the same connection} {
|
||||
r CLIENT TRACKING on REDIRECT $redir_id
|
||||
$rd CLIENT TRACKING on REDIRECT $redir_id
|
||||
$rd CLIENT TRACKING on REDIRECT $redir_id
|
||||
assert_equal OK [$rd read] ; # Consume the TRACKING reply
|
||||
$rd_sg MSET key1{t} 1 key2{t} 1
|
||||
r GET key1{t}
|
||||
$rd GET key2{t}
|
||||
$rd GET key2{t}
|
||||
assert_equal 1 [$rd read] ; # Consume the GET reply
|
||||
$rd_sg INCR key1{t}
|
||||
$rd_sg INCR key2{t}
|
||||
@ -299,19 +299,19 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
}
|
||||
|
||||
test {Different clients using different protocols can track the same key} {
|
||||
$rd HELLO 3
|
||||
$rd HELLO 3
|
||||
set reply [$rd read] ; # Consume the HELLO reply
|
||||
assert_equal 3 [dict get $reply proto]
|
||||
$rd CLIENT TRACKING on
|
||||
$rd CLIENT TRACKING on
|
||||
assert_equal OK [$rd read] ; # Consume the TRACKING reply
|
||||
$rd_sg set key1 1
|
||||
r GET key1
|
||||
$rd GET key1
|
||||
$rd GET key1
|
||||
assert_equal 1 [$rd read] ; # Consume the GET reply
|
||||
$rd_sg INCR key1
|
||||
set res1 [lindex [$rd_redirection read] 2]
|
||||
$rd PING ; # Non redirecting client has to talk to the server in order to get invalidation message
|
||||
set res2 [lindex [split [$rd read] " "] 1]
|
||||
set res2 [lindex [split [$rd read] " "] 1]
|
||||
assert_equal PONG [$rd read] ; # Consume the PING reply, which comes together with the invalidation message
|
||||
assert {$res1 eq {key1}}
|
||||
assert {$res2 eq {key1}}
|
||||
@ -346,7 +346,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
r CLIENT TRACKING off
|
||||
r CLIENT TRACKING on OPTOUT REDIRECT $redir_id
|
||||
$rd_sg SET key1 1
|
||||
r GET key1
|
||||
r GET key1
|
||||
$rd_sg SET key1 2
|
||||
set res [lindex [$rd_redirection read] 2]
|
||||
assert {$res eq {key1}}
|
||||
@ -392,7 +392,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
r CLIENT TRACKING on
|
||||
$rd_sg SET key1 1
|
||||
r GET key1
|
||||
r CLIENT TRACKING off
|
||||
r CLIENT TRACKING off
|
||||
r CLIENT TRACKING on BCAST
|
||||
$rd_sg INCR key1
|
||||
set inv_msg [r PING]
|
||||
@ -402,7 +402,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
}
|
||||
|
||||
test {BCAST with prefix collisions throw errors} {
|
||||
set r [redict_client]
|
||||
set r [redict_client]
|
||||
catch {$r CLIENT TRACKING ON BCAST PREFIX FOOBAR PREFIX FOO} output
|
||||
assert_match {ERR Prefix 'FOOBAR'*'FOO'*} $output
|
||||
|
||||
@ -587,9 +587,9 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
|
||||
# Keys are defined to be evicted 100 at a time by default.
|
||||
# If after eviction the number of keys still surpasses the limit
|
||||
# defined in tracking-table-max-keys, we increases eviction
|
||||
# effort to 200, and then 300, etc.
|
||||
# This test tests this effort incrementation.
|
||||
# defined in tracking-table-max-keys, we increases eviction
|
||||
# effort to 200, and then 300, etc.
|
||||
# This test tests this effort incrementation.
|
||||
test {Server is able to evacuate enough keys when num of keys surpasses limit by more than defined initial effort} {
|
||||
clean_all
|
||||
set NUM_OF_KEYS_TO_TEST 250
|
||||
@ -616,11 +616,11 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
r CLIENT TRACKING on REDIRECT $redir_id
|
||||
$rd_sg SET key1 1
|
||||
$rd_sg SET key2 2
|
||||
r GET key1
|
||||
r GET key1
|
||||
r GET key2
|
||||
$rd CLIENT TRACKING on BCAST PREFIX prefix:
|
||||
assert [string match *OK* [$rd read]]
|
||||
$rd_sg SET prefix:key1 1
|
||||
$rd_sg SET prefix:key1 1
|
||||
$rd_sg SET prefix:key2 2
|
||||
set info [r info]
|
||||
regexp "\r\ntracking_total_items:(.*?)\r\n" $info _ total_items
|
||||
@ -752,7 +752,7 @@ start_server {tags {"tracking network logreqres:skip"}} {
|
||||
test {Regression test for #11715} {
|
||||
# This issue manifests when a client invalidates keys through the max key
|
||||
# limit, which invalidates keys to get Redict below the limit, but no command is
|
||||
# then executed. This can occur in several ways but the simplest is through
|
||||
# then executed. This can occur in several ways but the simplest is through
|
||||
# multi-exec which queues commands.
|
||||
clean_all
|
||||
r config set tracking-table-max-keys 2
|
||||
|
Loading…
Reference in New Issue
Block a user