2019-10-24 02:38:52 -04:00
|
|
|
set testmodule [file normalize tests/modules/misc.so]
|
|
|
|
|
|
|
|
start_server {tags {"modules"}} {
|
|
|
|
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] }
|
|
|
|
}
|
|
|
|
|
2021-02-28 07:11:18 -05:00
|
|
|
test {test RM_Call recursive} {
|
|
|
|
set info [r test.call_generic test.call_generic info commandstats]
|
|
|
|
assert { [string match "*cmdstat_module*" $info] }
|
|
|
|
}
|
|
|
|
|
2020-10-11 10:21:58 -04:00
|
|
|
test {test redis version} {
|
|
|
|
set version [s redis_version]
|
|
|
|
assert_equal $version [r test.redisversion]
|
|
|
|
}
|
|
|
|
|
2019-11-04 12:04:35 -05:00
|
|
|
test {test long double conversions} {
|
|
|
|
set ld [r test.ld_conversion]
|
|
|
|
assert {[string match $ld "0.00000000000000001"]}
|
|
|
|
}
|
2022-06-26 08:02:52 -04:00
|
|
|
|
|
|
|
test {test unsigned long long conversions} {
|
|
|
|
set ret [r test.ull_conversion]
|
|
|
|
assert {[string match $ret "ok"]}
|
|
|
|
}
|
2019-11-04 12:04:35 -05:00
|
|
|
|
2019-11-04 12:30:31 -05:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-10-09 00:42:21 -04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-10-18 15:21:19 -04:00
|
|
|
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]
|
|
|
|
}
|
|
|
|
|
2021-06-10 08:39:33 -04:00
|
|
|
test {test module lru api} {
|
2019-11-10 02:04:39 -05:00
|
|
|
r config set maxmemory-policy allkeys-lru
|
2019-11-04 12:30:31 -05:00
|
|
|
r set x foo
|
|
|
|
set lru [r test.getlru x]
|
2019-11-10 02:04:39 -05:00
|
|
|
assert { $lru <= 1000 }
|
|
|
|
set was_set [r test.setlru x 100000]
|
|
|
|
assert { $was_set == 1 }
|
2019-11-04 12:30:31 -05:00
|
|
|
set idle [r object idletime x]
|
|
|
|
assert { $idle >= 100 }
|
|
|
|
set lru [r test.getlru x]
|
2019-11-10 02:04:39 -05:00
|
|
|
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 }
|
2019-11-04 12:30:31 -05:00
|
|
|
}
|
2019-11-10 02:04:39 -05:00
|
|
|
r config set maxmemory-policy allkeys-lru
|
|
|
|
|
2021-06-10 08:39:33 -04:00
|
|
|
test {test module lfu api} {
|
2019-11-10 02:04:39 -05:00
|
|
|
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 }
|
|
|
|
}
|
|
|
|
|
2020-08-17 10:46:54 -04:00
|
|
|
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::" }
|
2023-02-16 01:07:35 -05:00
|
|
|
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
|
2020-08-17 10:46:54 -04:00
|
|
|
}
|
2020-10-11 09:11:31 -04:00
|
|
|
|
2022-06-26 07:34:59 -04:00
|
|
|
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]
|
|
|
|
}
|
|
|
|
|
2020-10-11 10:11:42 -04:00
|
|
|
test {test module getclientcert api} {
|
|
|
|
set cert [r test.getclientcert]
|
|
|
|
|
|
|
|
if {$::tls} {
|
|
|
|
assert {$cert != ""}
|
|
|
|
} else {
|
|
|
|
assert {$cert == ""}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-11 09:11:31 -04:00
|
|
|
test {test detached thread safe cnotext} {
|
|
|
|
r test.log_tsctx "info" "Test message"
|
|
|
|
verify_log_message 0 "*<misc> Test message*" 0
|
|
|
|
}
|
2021-03-01 01:18:14 -05:00
|
|
|
|
|
|
|
test {test RM_Call CLIENT INFO} {
|
|
|
|
assert_match "*fd=-1*" [r test.call_generic client info]
|
|
|
|
}
|
2021-11-23 03:38:25 -05:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2022-01-13 04:36:03 -05:00
|
|
|
|
|
|
|
test {test monotonic time} {
|
|
|
|
set x [r test.monotonic_time]
|
|
|
|
assert { [r test.monotonic_time] >= $x }
|
|
|
|
}
|
2022-01-23 03:05:06 -05:00
|
|
|
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
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}
|
|
|
|
|
2022-09-26 03:03:45 -04:00
|
|
|
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}
|
|
|
|
|
2022-08-28 06:10:10 -04:00
|
|
|
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}
|
|
|
|
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# Note: each script is unique, to check that flags are extracted correctly
|
|
|
|
test {rm_call EVAL - OOM - with M flag} {
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
r config set maxmemory 1
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# 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 {
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
redis.call('set','x',1)
|
|
|
|
return 1
|
|
|
|
} 1 x
|
|
|
|
}
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# 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
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
redis.call('get','x')
|
|
|
|
return 2
|
|
|
|
} 1 x
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# 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
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
redis.call('get','x')
|
|
|
|
return 3
|
|
|
|
} 1 x
|
|
|
|
}
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# script without shebang, but uses GET, so succeeds
|
|
|
|
r test.rm_call_flags M eval {
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
redis.call('get','x')
|
|
|
|
return 4
|
|
|
|
} 1 x
|
|
|
|
|
|
|
|
r config set maxmemory 0
|
|
|
|
} {OK} {needs:config-maxmemory}
|
|
|
|
|
2022-10-27 02:29:43 -04:00
|
|
|
# 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}
|
|
|
|
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
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
|
|
|
|
|
Expose script flags to processCommand for better handling (#10744)
The important part is that read-only scripts (not just EVAL_RO
and FCALL_RO, but also ones with `no-writes` executed by normal EVAL or
FCALL), will now be permitted to run during CLIENT PAUSE WRITE (unlike
before where only the _RO commands would be processed).
Other than that, some errors like OOM, READONLY, MASTERDOWN are now
handled by processCommand, rather than the command itself affects the
error string (and even error code in some cases), and command stats.
Besides that, now the `may-replicate` commands, PFCOUNT and PUBLISH, will
be considered `write` commands in scripts and will be blocked in all
read-only scripts just like other write commands.
They'll also be blocked in EVAL_RO (i.e. even for scripts without the
`no-writes` shebang flag.
This commit also hides the `may_replicate` flag from the COMMAND command
output. this is a **breaking change**.
background about may_replicate:
We don't want to expose a no-may-replicate flag or alike to scripts, since we
consider the may-replicate thing an internal concern of redis, that we may
some day get rid of.
In fact, the may-replicate flag was initially introduced to flag EVAL: since
we didn't know what it's gonna do ahead of execution, before function-flags
existed). PUBLISH and PFCOUNT, both of which because they have side effects
which may some day be fixed differently.
code changes:
The changes in eval.c are mostly code re-ordering:
- evalCalcFunctionName is extracted out of evalGenericCommand
- evalExtractShebangFlags is extracted luaCreateFunction
- evalGetCommandFlags is new code
2022-06-01 07:09:40 -04:00
|
|
|
assert_error {READONLY Can not run script with write flag on readonly replica*} {
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
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}
|
2022-09-05 09:19:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
start_server {tags {"modules"}} {
|
|
|
|
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
|
Unify ACL failure error messaging. (#11160)
Motivation: for applications that use RM ACL verification functions, they would
want to return errors back to the user, in ways that are consistent with Redis.
While investigating how we should return ACL errors to the user, we realized that
Redis isn't consistent, and currently returns ACL error strings in 3 primary ways.
[For the actual implications of this change, see the "Impact" section at the bottom]
1. how it returns an error when calling a command normally
ACL_DENIED_CMD -> "this user has no permissions to run the '%s' command"
ACL_DENIED_KEY -> "this user has no permissions to access one of the keys used as arguments"
ACL_DENIED_CHANNEL -> "this user has no permissions to access one of the channels used as arguments"
2. how it returns an error when calling via 'acl dryrun' command
ACL_DENIED_CMD -> "This user has no permissions to run the '%s' command"
ACL_DENIED_KEY -> "This user has no permissions to access the '%s' key"
ACL_DENIED_CHANNEL -> "This user has no permissions to access the '%s' channel"
3. how it returns an error via RM_Call (and scripting is similar).
ACL_DENIED_CMD -> "can't run this command or subcommand";
ACL_DENIED_KEY -> "can't access at least one of the keys mentioned in the command arguments";
ACL_DENIED_CHANNEL -> "can't publish to the channel mentioned in the command";
In addition, if one wants to use RM_Call's "dry run" capability instead of the RM ACL
functions directly, one also sees a different problem than it returns ACL errors with a -ERR,
not a -PERM, so it can't be returned directly to the caller.
This PR modifies the code to generate a base message in a common manner with the ability
to set verbose flag for acl dry run errors, and keep it unset for normal/rm_call/script cases
```c
sds getAclErrorMessage(int acl_res, user *user, struct redisCommand *cmd, sds errored_val, int verbose) {
switch (acl_res) {
case ACL_DENIED_CMD:
return sdscatfmt(sdsempty(), "User %S has no permissions to run "
"the '%S' command", user->name, cmd->fullname);
case ACL_DENIED_KEY:
if (verbose) {
return sdscatfmt(sdsempty(), "User %S has no permissions to access "
"the '%S' key", user->name, errored_val);
} else {
return sdsnew("No permissions to access a key");
}
case ACL_DENIED_CHANNEL:
if (verbose) {
return sdscatfmt(sdsempty(), "User %S has no permissions to access "
"the '%S' channel", user->name, errored_val);
} else {
return sdsnew("No permissions to access a channel");
}
}
```
The caller can append/prepend the message (adding NOPERM for normal/RM_Call or indicating it's within a script).
Impact:
- Plain commands, as well as scripts and RM_Call now include the user name.
- ACL DRYRUN remains the only one that's verbose (mentions the offending channel or key name)
- Changes RM_Call ACL errors from being a `-ERR` to being `-NOPERM` (besides for textual changes)
**This somewhat a breaking change, but it only affects the RM_Call with both `C` and `E`, or `D`**
- Changes ACL errors in scripts textually from being
`The user executing the script <old non unified text>`
to
`ACL failure in script: <new unified text>`
2022-10-16 02:01:37 -04:00
|
|
|
assert_match {*NOPERM No permissions to access a key*} $e
|
2022-09-05 09:19:32 -04:00
|
|
|
r acl setuser default +@all ~*
|
|
|
|
assert_equal [r get x] $x
|
|
|
|
}
|
Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786)
* Fix broken protocol when redis can't persist to RDB (general commands, not
modules), excessive newline. regression of #10372 (7.0 RC3)
* Fix broken protocol when Redis can't persist to AOF (modules and
scripts), missing newline.
* Fix bug in OOM check of EVAL scripts called from RM_Call.
set the cached OOM state for scripts before executing module commands too,
so that it can serve scripts that are executed by modules.
i.e. in the past EVAL executed by RM_Call could have either falsely
fail or falsely succeeded because of a wrong cached OOM state flag.
* Fix bugs with RM_Yield:
1. SHUTDOWN should only accept the NOSAVE mode
2. Avoid eviction during yield command processing.
3. Avoid processing master client commands while yielding from another client
* Add new two more checks to RM_Call script mode.
1. READONLY You can't write against a read only replica
2. MASTERDOWN Link with MASTER is down and `replica-serve-stale-data` is set to `no`
* Add new RM_Call flag to let redis automatically refuse `deny-oom` commands
while over the memory limit.
* Add tests to cover various errors from Scripts, Modules, Modules
calling scripts, and Modules calling commands in script mode.
Add tests:
* Looks like the MISCONF error was completely uncovered by the tests,
add tests for it, including from scripts, and modules
* Add tests for NOREPLICAS from scripts
* Add tests for the various errors in module RM_Call, including RM_Call that
calls EVAL, and RM_call in "eval mode". that includes:
NOREPLICAS, READONLY, MASTERDOWN, MISCONF
2022-06-01 06:04:22 -04:00
|
|
|
|
2023-02-09 07:59:05 -05:00
|
|
|
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]
|
|
|
|
}
|
|
|
|
|
2023-03-07 02:06:58 -05:00
|
|
|
if {[string match {*jemalloc*} [s mem_allocator]]} {
|
2023-02-28 12:38:58 -05:00
|
|
|
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.
|
|
|
|
}
|
2023-03-07 02:06:58 -05:00
|
|
|
} ;# if jemalloc
|
2023-02-28 12:38:58 -05:00
|
|
|
|
2022-01-23 03:05:06 -05:00
|
|
|
test "Unload the module - misc" {
|
|
|
|
assert_equal {OK} [r module unload misc]
|
|
|
|
}
|
Unify ACL failure error messaging. (#11160)
Motivation: for applications that use RM ACL verification functions, they would
want to return errors back to the user, in ways that are consistent with Redis.
While investigating how we should return ACL errors to the user, we realized that
Redis isn't consistent, and currently returns ACL error strings in 3 primary ways.
[For the actual implications of this change, see the "Impact" section at the bottom]
1. how it returns an error when calling a command normally
ACL_DENIED_CMD -> "this user has no permissions to run the '%s' command"
ACL_DENIED_KEY -> "this user has no permissions to access one of the keys used as arguments"
ACL_DENIED_CHANNEL -> "this user has no permissions to access one of the channels used as arguments"
2. how it returns an error when calling via 'acl dryrun' command
ACL_DENIED_CMD -> "This user has no permissions to run the '%s' command"
ACL_DENIED_KEY -> "This user has no permissions to access the '%s' key"
ACL_DENIED_CHANNEL -> "This user has no permissions to access the '%s' channel"
3. how it returns an error via RM_Call (and scripting is similar).
ACL_DENIED_CMD -> "can't run this command or subcommand";
ACL_DENIED_KEY -> "can't access at least one of the keys mentioned in the command arguments";
ACL_DENIED_CHANNEL -> "can't publish to the channel mentioned in the command";
In addition, if one wants to use RM_Call's "dry run" capability instead of the RM ACL
functions directly, one also sees a different problem than it returns ACL errors with a -ERR,
not a -PERM, so it can't be returned directly to the caller.
This PR modifies the code to generate a base message in a common manner with the ability
to set verbose flag for acl dry run errors, and keep it unset for normal/rm_call/script cases
```c
sds getAclErrorMessage(int acl_res, user *user, struct redisCommand *cmd, sds errored_val, int verbose) {
switch (acl_res) {
case ACL_DENIED_CMD:
return sdscatfmt(sdsempty(), "User %S has no permissions to run "
"the '%S' command", user->name, cmd->fullname);
case ACL_DENIED_KEY:
if (verbose) {
return sdscatfmt(sdsempty(), "User %S has no permissions to access "
"the '%S' key", user->name, errored_val);
} else {
return sdsnew("No permissions to access a key");
}
case ACL_DENIED_CHANNEL:
if (verbose) {
return sdscatfmt(sdsempty(), "User %S has no permissions to access "
"the '%S' channel", user->name, errored_val);
} else {
return sdsnew("No permissions to access a channel");
}
}
```
The caller can append/prepend the message (adding NOPERM for normal/RM_Call or indicating it's within a script).
Impact:
- Plain commands, as well as scripts and RM_Call now include the user name.
- ACL DRYRUN remains the only one that's verbose (mentions the offending channel or key name)
- Changes RM_Call ACL errors from being a `-ERR` to being `-NOPERM` (besides for textual changes)
**This somewhat a breaking change, but it only affects the RM_Call with both `C` and `E`, or `D`**
- Changes ACL errors in scripts textually from being
`The user executing the script <old non unified text>`
to
`ACL failure in script: <new unified text>`
2022-10-16 02:01:37 -04:00
|
|
|
}
|