diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48a94ef9843..258f8197c84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,24 @@ jobs: - name: show-kernel-log run: sudo dmesg -c + test-without-lua: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: make + # Fail build if there are warnings + # build with TLS just for compilation coverage + run: make -j4 all-with-unit-tests SERVER_CFLAGS='-Werror' BUILD_TLS=yes USE_LUA=no + - name: test + run: | + sudo apt-get install tcl8.6 tclx + ./runtest --verbose --tags -slow --tags -scripting --dump-logs + - name: module api test + run: CFLAGS='-Werror' ./runtest-moduleapi --verbose --dump-logs --tags -scripting + - name: unit tests + run: | + ./src/valkey-unit-tests + build-debian-old: runs-on: ubuntu-latest container: debian:buster diff --git a/README.md b/README.md index 1a8ce1a4db4..5f1231d0b36 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,10 @@ as libsystemd-dev on Debian/Ubuntu or systemd-devel on CentOS) and run: % make USE_SYSTEMD=yes +To build without Lua scripting (it is enabled by default), run: + + % make USE_LUA=no + To append a suffix to Valkey program names, use: % make PROG_SUFFIX="-alt" diff --git a/src/Makefile b/src/Makefile index ae2de1c6268..2cb9a993850 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,7 +31,20 @@ endif ifneq ($(OPTIMIZATION),-O0) OPTIMIZATION+=-fno-omit-frame-pointer endif -DEPENDENCY_TARGETS=hiredis linenoise lua hdr_histogram fpconv + +# Lua enablement flags. Lua is enabled by default, +# but can be disabled with USE_LUA=no +ifneq ($(USE_LUA),no) + LUA_LIBS=../deps/lua/src/liblua.a + LUA_CFLAGS=-I../deps/lua/src -DUSE_LUA + LUA_TARGET=lua + LUA_TEST_FLAGS= +else + # Do not run tests that require Lua scripting + LUA_TEST_FLAGS=--tags -scripting +endif + +DEPENDENCY_TARGETS=hiredis linenoise ${LUA_TARGET} hdr_histogram fpconv NODEPS:=clean distclean # Default settings @@ -248,7 +261,7 @@ ifdef OPENSSL_PREFIX endif # Include paths to dependencies -FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src -I../deps/hdr_histogram -I../deps/fpconv +FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise ${LUA_CFLAGS} -I../deps/hdr_histogram -I../deps/fpconv # Determine systemd support and/or build preference (defaulting to auto-detection) BUILD_WITH_SYSTEMD=no @@ -477,7 +490,7 @@ endif # valkey-server $(SERVER_NAME): $(ENGINE_SERVER_OBJ) - $(SERVER_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a ../deps/hdr_histogram/libhdrhistogram.a ../deps/fpconv/libfpconv.a $(FINAL_LIBS) + $(SERVER_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ${LUA_LIBS} ../deps/hdr_histogram/libhdrhistogram.a ../deps/fpconv/libfpconv.a $(FINAL_LIBS) # Valkey static library, used to compile against for unit testing $(ENGINE_LIB_NAME): $(ENGINE_SERVER_OBJ) @@ -485,7 +498,7 @@ $(ENGINE_LIB_NAME): $(ENGINE_SERVER_OBJ) # valkey-unit-tests $(ENGINE_UNIT_TESTS): $(ENGINE_TEST_OBJ) $(ENGINE_LIB_NAME) - $(SERVER_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a ../deps/hdr_histogram/libhdrhistogram.a ../deps/fpconv/libfpconv.a $(FINAL_LIBS) + $(SERVER_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ${LUA_LIBS} ../deps/hdr_histogram/libhdrhistogram.a ../deps/fpconv/libfpconv.a $(FINAL_LIBS) # valkey-sentinel $(ENGINE_SENTINEL_NAME): $(SERVER_NAME) @@ -561,13 +574,13 @@ distclean: clean .PHONY: distclean test: $(SERVER_NAME) $(ENGINE_CHECK_AOF_NAME) $(ENGINE_CLI_NAME) $(ENGINE_BENCHMARK_NAME) - @(cd ..; ./runtest) + @(cd ..; ./runtest ${LUA_TEST_FLAGS}) test-unit: $(ENGINE_UNIT_TESTS) ./$(ENGINE_UNIT_TESTS) test-modules: $(SERVER_NAME) - @(cd ..; ./runtest-moduleapi) + @(cd ..; ./runtest-moduleapi ${LUA_TEST_FLAGS}) test-sentinel: $(ENGINE_SENTINEL_NAME) $(ENGINE_CLI_NAME) @(cd ..; ./runtest-sentinel) diff --git a/src/defrag.c b/src/defrag.c index 4d34009f8bf..303047741de 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -170,6 +170,7 @@ robj *activeDefragStringOb(robj *ob) { return activeDefragStringObEx(ob, 1); } +#ifdef USE_LUA /* Defrag helper for lua scripts * * returns NULL in case the allocation wasn't moved. @@ -189,6 +190,7 @@ luaScript *activeDefragLuaScript(luaScript *script) { return ret; } +#endif /* Defrag helper for dict main allocations (dict struct, and hash tables). * Receives a pointer to the dict* and return a new dict* when the dict @@ -299,10 +301,12 @@ void activeDefragSdsDict(dict *d, int val_type) { dictDefragFunctions defragfns = { .defragAlloc = activeDefragAlloc, .defragKey = (dictDefragAllocFunction *)activeDefragSds, - .defragVal = (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS ? (dictDefragAllocFunction *)activeDefragSds - : val_type == DEFRAG_SDS_DICT_VAL_IS_STROB ? (dictDefragAllocFunction *)activeDefragStringOb - : val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR ? (dictDefragAllocFunction *)activeDefragAlloc + .defragVal = (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS ? (dictDefragAllocFunction *)activeDefragSds + : val_type == DEFRAG_SDS_DICT_VAL_IS_STROB ? (dictDefragAllocFunction *)activeDefragStringOb + : val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR ? (dictDefragAllocFunction *)activeDefragAlloc +#ifdef USE_LUA : val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT ? (dictDefragAllocFunction *)activeDefragLuaScript +#endif : NULL)}; do { cursor = dictScanDefrag(d, cursor, activeDefragSdsDictCallback, &defragfns, NULL); @@ -812,7 +816,9 @@ void defragOtherGlobals(void) { /* there are many more pointers to defrag (e.g. client argv, output / aof buffers, etc. * but we assume most of these are short lived, we only need to defrag allocations * that remain static for a long time */ +#ifdef USE_LUA activeDefragSdsDict(evalScriptsDict(), DEFRAG_SDS_DICT_VAL_LUA_SCRIPT); +#endif moduleDefragGlobals(); kvstoreDictLUTDefrag(server.pubsub_channels, dictDefragTables); kvstoreDictLUTDefrag(server.pubsubshard_channels, dictDefragTables); diff --git a/src/eval.c b/src/eval.c index fd12e40ad2e..f5675d41a1a 100644 --- a/src/eval.c +++ b/src/eval.c @@ -35,7 +35,11 @@ * 2. scriptingInit() - initServer() function from server.c invokes this to initialize LUA at startup. * It is also invoked between 2 eval invocations to reset Lua. */ + #include "server.h" + +#ifdef USE_LUA + #include "sha1.h" #include "rand.h" #include "cluster.h" @@ -764,6 +768,10 @@ dict *evalScriptsDict(void) { return lctx.lua_scripts; } +unsigned long evalScriptsDictSize(void) { + return dictSize(evalScriptsDict()); +} + unsigned long evalScriptsMemory(void) { return lctx.lua_scripts_mem + dictMemUsage(lctx.lua_scripts) + dictSize(lctx.lua_scripts) * sizeof(luaScript) + listLength(lctx.lua_scripts_lru_list) * sizeof(listNode); @@ -1756,3 +1764,64 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) { rctx->start_time = getMonotonicUs(); } } + +#else /* USE_LUA is no */ + +/* These stubs are used when Lua is disabled at compile time. + * They typically do nothing and report 0. */ + +void scriptingInit(int setup) { + UNUSED(setup); +} + +int ldbPendingChildren(void) { + return 0; +} + +int ldbRemoveChild(pid_t pid) { + UNUSED(pid); + return 0; +} + +unsigned long evalMemory(void) { + return 0; +} + +unsigned long evalScriptsMemory(void) { + return 0; +} + +uint64_t evalGetCommandFlags(client *c, uint64_t cmd_flags) { + UNUSED(c); + /* Pass through the cmd_flags */ + return cmd_flags; +} + +unsigned long evalScriptsDictSize(void) { + return 0; +} + +void ldbKillForkedSessions(void) { +} + +void evalCommand(client *c) { + addReplyError(c, "No default engine loaded"); +} + +void evalRoCommand(client *c) { + addReplyError(c, "No default engine loaded"); +} + +void evalShaCommand(client *c) { + addReplyError(c, "No default engine loaded"); +} + +void evalShaRoCommand(client *c) { + addReplyError(c, "No default engine loaded"); +} + +void scriptCommand(client *c) { + addReplyError(c, "No default engine loaded"); +} + +#endif diff --git a/src/function_lua.c b/src/function_lua.c index fa9983bf7ed..283751bf2ec 100644 --- a/src/function_lua.c +++ b/src/function_lua.c @@ -40,6 +40,9 @@ */ #include "functions.h" + +#ifdef USE_LUA + #include "script_lua.h" #include #include @@ -507,3 +510,5 @@ int luaEngineInitEngine(void) { }; return functionsRegisterEngine(LUA_ENGINE_NAME, lua_engine); } + +#endif diff --git a/src/functions.c b/src/functions.c index a00fefb329c..0cfc1bed8ca 100644 --- a/src/functions.c +++ b/src/functions.c @@ -1114,9 +1114,11 @@ size_t functionsLibCtxFunctionsLen(functionsLibCtx *functions_ctx) { int functionsInit(void) { engines = dictCreate(&engineDictType); +#ifdef USE_LUA if (luaEngineInitEngine() != C_OK) { return C_ERR; } +#endif /* Must be initialized after engines initialization */ curr_functions_lib_ctx = functionsLibCtxCreate(); diff --git a/src/lazyfree.c b/src/lazyfree.c index 6176b43440b..c25e0dc4f78 100644 --- a/src/lazyfree.c +++ b/src/lazyfree.c @@ -51,6 +51,9 @@ void lazyFreeErrors(void *args[]) { /* Release the lua_scripts dict. */ void lazyFreeLuaScripts(void *args[]) { +#ifndef USE_LUA + UNUSED(args); +#else dict *lua_scripts = args[0]; list *lua_scripts_lru_list = args[1]; lua_State *lua = args[2]; @@ -58,6 +61,7 @@ void lazyFreeLuaScripts(void *args[]) { freeLuaScriptsSync(lua_scripts, lua_scripts_lru_list, lua); atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed); atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed); +#endif } /* Release the functions ctx. */ @@ -222,6 +226,7 @@ void freeErrorsRadixTreeAsync(rax *errors) { } } +#ifdef USE_LUA /* Free lua_scripts dict and lru list, if the dict is huge enough, free them in async way. * Close lua interpreter, if there are a lot of lua scripts, close it in async way. */ void freeLuaScriptsAsync(dict *lua_scripts, list *lua_scripts_lru_list, lua_State *lua) { @@ -232,6 +237,7 @@ void freeLuaScriptsAsync(dict *lua_scripts, list *lua_scripts_lru_list, lua_Stat freeLuaScriptsSync(lua_scripts, lua_scripts_lru_list, lua); } } +#endif /* Free functions ctx, if the functions ctx contains enough functions, free it in async way. */ void freeFunctionsAsync(functionsLibCtx *functions_lib_ctx) { diff --git a/src/object.c b/src/object.c index 8c1cf64892a..1fdbd7e7954 100644 --- a/src/object.c +++ b/src/object.c @@ -1306,7 +1306,7 @@ sds getMemoryDoctorReport(void) { } /* Too many scripts are cached? */ - if (dictSize(evalScriptsDict()) > 1000) { + if (evalScriptsDictSize() > 1000) { many_scripts = 1; num_reports++; } diff --git a/src/script_lua.c b/src/script_lua.c index 5093fa944fc..1a852b12db0 100644 --- a/src/script_lua.c +++ b/src/script_lua.c @@ -27,6 +27,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if USE_LUA + #include "script_lua.h" #include "fpconv_dtoa.h" @@ -1780,3 +1782,10 @@ void luaCallFunction(scriptRunCtx *run_ctx, unsigned long luaMemory(lua_State *lua) { return lua_gc(lua, LUA_GCCOUNT, 0) * 1024LL; } + +#else + +/* We need some declaration to prevent compiler warnings */ +#include + +#endif diff --git a/src/server.c b/src/server.c index 508edc71123..60286b8a80c 100644 --- a/src/server.c +++ b/src/server.c @@ -5669,7 +5669,7 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) { "used_memory_vm_eval:%lld\r\n", memory_lua, "used_memory_lua_human:%s\r\n", used_memory_lua_hmem, /* deprecated */ "used_memory_scripts_eval:%lld\r\n", (long long)mh->lua_caches, - "number_of_cached_scripts:%lu\r\n", dictSize(evalScriptsDict()), + "number_of_cached_scripts:%lu\r\n", evalScriptsDictSize(), "number_of_functions:%lu\r\n", functionsNum(), "number_of_libraries:%lu\r\n", functionsLibNum(), "used_memory_vm_functions:%lld\r\n", memory_functions, diff --git a/src/server.h b/src/server.h index 5cf56e9c868..bb12412ffef 100644 --- a/src/server.h +++ b/src/server.h @@ -50,7 +50,11 @@ #include #include #include + +#ifdef USE_LUA #include +#endif + #include #ifdef HAVE_LIBSYSTEMD @@ -3635,30 +3639,42 @@ int redis_check_rdb_main(int argc, char **argv, FILE *fp); int redis_check_aof_main(int argc, char **argv); /* Scripting */ + void scriptingInit(int setup); int ldbRemoveChild(pid_t pid); void ldbKillForkedSessions(void); int ldbPendingChildren(void); + +unsigned long evalMemory(void); +unsigned long evalScriptsDictSize(void); +unsigned long evalScriptsMemory(void); +uint64_t evalGetCommandFlags(client *c, uint64_t orig_flags); + +void freeFunctionsAsync(functionsLibCtx *lib_ctx); +uint64_t fcallGetCommandFlags(client *c, uint64_t orig_flags); +int isInsideYieldingLongCommand(void); + +#ifdef USE_LUA +/* The functions above are cross-cutting are stubbed when !USE_LUA. + * The declarations below are only included when Lua scripting is enabled. */ void luaLdbLineHook(lua_State *lua, lua_Debug *ar); void freeLuaScriptsSync(dict *lua_scripts, list *lua_scripts_lru_list, lua_State *lua); void freeLuaScriptsAsync(dict *lua_scripts, list *lua_scripts_lru_list, lua_State *lua); -void freeFunctionsAsync(functionsLibCtx *lib_ctx); int ldbIsEnabled(void); void ldbLog(sds entry); void ldbLogRespReply(char *reply); void sha1hex(char *digest, char *script, size_t len); unsigned long evalMemory(void); dict *evalScriptsDict(void); -unsigned long evalScriptsMemory(void); -uint64_t evalGetCommandFlags(client *c, uint64_t orig_flags); -uint64_t fcallGetCommandFlags(client *c, uint64_t orig_flags); -int isInsideYieldingLongCommand(void); typedef struct luaScript { uint64_t flags; robj *body; listNode *node; /* list node in lua_scripts_lru_list list. */ } luaScript; + +#endif + /* Cache of recently used small arguments to avoid malloc calls. */ #define LUA_CMD_OBJCACHE_SIZE 32 #define LUA_CMD_OBJCACHE_MAX_LEN 64 diff --git a/tests/README.md b/tests/README.md index 06756f394b0..4fcb6871d65 100644 --- a/tests/README.md +++ b/tests/README.md @@ -90,6 +90,7 @@ The following compatibility and capability tags are currently used: | `external:skip` | Not compatible with external servers. | | `cluster:skip` | Not compatible with `--cluster-mode`. | | `large-memory` | Test that requires more than 100MB | +| `scripting` | Tests that require a Lua engine. | | `tls:skip` | Not compatible with `--tls`. | | `needs:repl` | Uses replication and needs to be able to `SYNC` from server. | | `needs:debug` | Uses the `DEBUG` command or other debugging focused commands (like `OBJECT REFCOUNT`). | diff --git a/tests/integration/aof.tcl b/tests/integration/aof.tcl index 33c7c12d4b7..f5239251b0f 100644 --- a/tests/integration/aof.tcl +++ b/tests/integration/aof.tcl @@ -452,7 +452,7 @@ tags {"aof external:skip"} { wait_for_log_messages 0 {"*Slow script detected*"} 0 100 100 assert_equal [r get x] y } - } + } {} {scripting} test {EVAL can process writes from AOF in read-only replicas} { create_aof_manifest $aof_dirpath $aof_manifest_file { @@ -467,7 +467,7 @@ tags {"aof external:skip"} { 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 } - } + } {} {scripting} test {Test valkey-check-aof for old style resp AOF} { create_aof $aof_dirpath $aof_file { diff --git a/tests/integration/rdb.tcl b/tests/integration/rdb.tcl index 61cb0cea7e6..38738322fdc 100644 --- a/tests/integration/rdb.tcl +++ b/tests/integration/rdb.tcl @@ -423,7 +423,7 @@ start_server [list overrides [list "dir" $server_path "dbfilename" "scriptbackup # its sha1 is: a0c38691e9fffe4563723c32ba77a34398e090e6 test {script won't load anymore if it's in rdb} { assert_equal [r script exists a0c38691e9fffe4563723c32ba77a34398e090e6] 0 - } + } {} {scripting} } start_server {} { @@ -471,7 +471,7 @@ start_server {} { # server is writable again r set x y - } {OK} + } {OK} {scripting} } } ;# tags diff --git a/tests/integration/replication-4.tcl b/tests/integration/replication-4.tcl index d5b55b3b570..bb882b1b04e 100644 --- a/tests/integration/replication-4.tcl +++ b/tests/integration/replication-4.tcl @@ -52,7 +52,7 @@ start_server {tags {"repl network external:skip singledb:skip"} overrides {save } } -start_server {tags {"repl external:skip"}} { +start_server {tags {"repl scripting external:skip"}} { start_server {} { set master [srv -1 client] set master_host [srv -1 host] diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl index 1b5b0c030ae..40f8c23b04b 100644 --- a/tests/integration/replication.tcl +++ b/tests/integration/replication.tcl @@ -280,7 +280,7 @@ start_server {tags {"repl external:skip"}} { {incr x} } close_replication_stream $repl - } + } {} {scripting} test {ROLE in master reports master with a slave} { set res [r -1 role] @@ -437,7 +437,7 @@ start_server {tags {"repl external:skip"} overrides {save {}}} { } else { fail "Different datasets between replica and master" } - } + } {} {scripting} } } @@ -541,7 +541,7 @@ foreach testType {Successful Aborted} dualchannel {yes no} { # Diskless load swapdb when async_loading (matching master replid) foreach testType {Successful Aborted} { - start_server {tags {"repl external:skip"}} { + start_server {tags {"repl external:skip scripting"}} { set replica [srv 0 client] set replica_host [srv 0 host] set replica_port [srv 0 port] @@ -656,7 +656,7 @@ foreach testType {Successful Aborted} { after 200 ; # Give some time to Lua to call the hook again... assert_equal [$replica ping] "PONG" $rd_replica close - } + } {0} {scripting} test {Blocked commands and configs during async-loading} { assert_error {LOADING*} {$replica config set appendonly no} @@ -823,7 +823,7 @@ test {diskless loading short read} { $master config set rdb-key-save-delay 0 } } -} {} {external:skip} +} {} {scripting external:skip} # get current stime and utime metrics for a thread (since it's creation) proc get_cpu_metrics { statfile } { diff --git a/tests/integration/valkey-cli.tcl b/tests/integration/valkey-cli.tcl index 6344215a254..7e9f050a754 100644 --- a/tests/integration/valkey-cli.tcl +++ b/tests/integration/valkey-cli.tcl @@ -487,7 +487,7 @@ if {!$::tls} { ;# fake_redis_node doesn't support TLS assert_match "OK" [r config set repl-diskless-sync yes] assert_match "OK" [r config set repl-diskless-sync-delay 0] test_valkey_cli_rdb_dump $functions_only - } {} {needs:repl needs:debug} + } {} {needs:repl needs:debug scripting} } ;# foreach functions_only diff --git a/tests/unit/acl.tcl b/tests/unit/acl.tcl index a05359d7c9d..cbf1a495379 100644 --- a/tests/unit/acl.tcl +++ b/tests/unit/acl.tcl @@ -780,7 +780,7 @@ start_server {tags {"acl external:skip"}} { assert {[dict get $entry context] eq {lua}} assert {[dict get $entry object] eq {incr}} assert_match {*cmd=eval*} [dict get $entry client-info] - } + } {} {scripting} test {ACL LOG can accept a numerical argument to show less entries} { r AUTH antirez foo diff --git a/tests/unit/aofrw.tcl b/tests/unit/aofrw.tcl index 5cca6d90b9a..bb2997c60cf 100644 --- a/tests/unit/aofrw.tcl +++ b/tests/unit/aofrw.tcl @@ -205,7 +205,7 @@ start_server {tags {"aofrw external:skip"} overrides {aof-use-rdb-preamble no}} r debug loadaof assert_equal [r fcall test 0] 1 r FUNCTION LIST - } {{library_name test engine LUA functions {{name test description {} flags {}}}}} + } {{library_name test engine LUA functions {{name test description {} flags {}}}}} {scripting} test {BGREWRITEAOF is delayed if BGSAVE is in progress} { r flushall diff --git a/tests/unit/client-eviction.tcl b/tests/unit/client-eviction.tcl index ceeb20f7b60..7c6869b9cf2 100644 --- a/tests/unit/client-eviction.tcl +++ b/tests/unit/client-eviction.tcl @@ -242,7 +242,7 @@ start_server {} { r debug pause-cron 0 $rr close $redirected_c close - } {0} {needs:debug} + } {0} {needs:debug scripting} test "client evicted due to client tracking prefixes" { r flushdb diff --git a/tests/unit/cluster/cli.tcl b/tests/unit/cluster/cli.tcl index 3f1f0e9ffa1..263b879abfb 100644 --- a/tests/unit/cluster/cli.tcl +++ b/tests/unit/cluster/cli.tcl @@ -245,7 +245,7 @@ start_multiple_servers 5 [list overrides $base_conf] { 127.0.0.1:[srv 0 port] } e assert_match {*node already contains functions*} $e - } + } {} {scripting} } ;# stop servers # Test valkey-cli --cluster create, add-node. diff --git a/tests/unit/cluster/manual-failover.tcl b/tests/unit/cluster/manual-failover.tcl index 2a9dff934bb..fe3c403f907 100644 --- a/tests/unit/cluster/manual-failover.tcl +++ b/tests/unit/cluster/manual-failover.tcl @@ -1,5 +1,5 @@ # Check the manual failover -start_cluster 5 5 {tags {external:skip cluster}} { +start_cluster 5 5 {tags {external:skip cluster scripting}} { test "Cluster is up" { wait_for_cluster_state ok diff --git a/tests/unit/cluster/scripting.tcl b/tests/unit/cluster/scripting.tcl index 88e158afc54..533ab0d7a57 100644 --- a/tests/unit/cluster/scripting.tcl +++ b/tests/unit/cluster/scripting.tcl @@ -1,4 +1,4 @@ -start_cluster 1 0 {tags {external:skip cluster}} { +start_cluster 1 0 {tags {external:skip cluster scripting}} { test {Eval scripts with shebangs and functions default to no cross slots} { # Test that scripts with shebang block cross slot operations diff --git a/tests/unit/cluster/slot-stats.tcl b/tests/unit/cluster/slot-stats.tcl index 3e3487a612c..0d514b08374 100644 --- a/tests/unit/cluster/slot-stats.tcl +++ b/tests/unit/cluster/slot-stats.tcl @@ -286,7 +286,7 @@ start_cluster 1 0 {tags {external:skip cluster} overrides {cluster-slot-stats-en ] ] assert_empty_slot_stats_with_exception $slot_stats $expected_slot_stats $metrics_to_assert - } + } {} {scripting} R 0 CONFIG RESETSTAT R 0 FLUSHALL @@ -298,7 +298,7 @@ start_cluster 1 0 {tags {external:skip cluster} overrides {cluster-slot-stats-en # For cross-slot, we do not accumulate at all. set slot_stats [R 0 CLUSTER SLOT-STATS SLOTSRANGE 0 16383] assert_empty_slot_stats $slot_stats $metrics_to_assert - } + } {} {scripting} R 0 CONFIG RESETSTAT R 0 FLUSHALL @@ -320,7 +320,7 @@ start_cluster 1 0 {tags {external:skip cluster} overrides {cluster-slot-stats-en ] ] assert_empty_slot_stats_with_exception $slot_stats $expected_slot_stats $metrics_to_assert - } + } {} {scripting} R 0 CONFIG RESETSTAT R 0 FLUSHALL @@ -337,7 +337,7 @@ start_cluster 1 0 {tags {external:skip cluster} overrides {cluster-slot-stats-en # For cross-slot, we do not accumulate at all. set slot_stats [R 0 CLUSTER SLOT-STATS SLOTSRANGE 0 16383] assert_empty_slot_stats $slot_stats $metrics_to_assert - } + } {} {scripting} R 0 CONFIG RESETSTAT R 0 FLUSHALL } diff --git a/tests/unit/cluster/transactions-on-replica.tcl b/tests/unit/cluster/transactions-on-replica.tcl index 5bca9e6a373..0dccdba5284 100644 --- a/tests/unit/cluster/transactions-on-replica.tcl +++ b/tests/unit/cluster/transactions-on-replica.tcl @@ -102,6 +102,6 @@ test "reply MOVED when eval from replica for update" { } 1 a ]} err assert {[string range $err 0 4] eq {MOVED}} -} +} {} {scripting} } ;# start_cluster diff --git a/tests/unit/functions.tcl b/tests/unit/functions.tcl index 7ddd36dd7d8..70ea3cc78cd 100644 --- a/tests/unit/functions.tcl +++ b/tests/unit/functions.tcl @@ -281,7 +281,7 @@ start_server {tags {"scripting"}} { assert_equal [r ping] "PONG" assert_error {ERR Script killed by user with SCRIPT KILL*} {$rd read} $rd close - } + } {0} {scripting} test {FUNCTION - test function flush} { r function load REPLACE [get_function_code lua test test {local a = 1 while true do a = a + 1 end}] @@ -461,7 +461,7 @@ test {FUNCTION can processes create, delete and flush commands in AOF when doing r slaveof no one assert_equal [r function list] {} } -} {} {needs:debug external:skip} +} {} {needs:debug scripting external:skip} start_server {tags {"scripting"}} { test {LIBRARIES - test shared function can access default globals} { diff --git a/tests/unit/info.tcl b/tests/unit/info.tcl index 61d1acd1f8e..0c7a0f70fde 100644 --- a/tests/unit/info.tcl +++ b/tests/unit/info.tcl @@ -151,7 +151,7 @@ start_server {tags {"info" "external:skip"}} { assert_match {*calls=1,*,rejected_calls=1,failed_calls=0} [cmdstat eval] assert_match {*count=2*} [errorstat ERR] assert_equal [s total_error_replies] 2 - } + } {} {scripting} test {errorstats: failed call NOSCRIPT error} { r config resetstat @@ -164,7 +164,7 @@ start_server {tags {"info" "external:skip"}} { assert_equal [s total_error_replies] 1 r config resetstat assert_match {} [errorstat NOSCRIPT] - } + } {} {scripting} test {errorstats: failed call NOGROUP error} { r config resetstat @@ -306,7 +306,7 @@ start_server {tags {"info" "external:skip"}} { assert_error "ERR Wrong number of args*" {r fcall invalidgetcmd 0} assert_equal "count=975" [errorstat ERRORSTATS_OVERFLOW] assert_equal "count=2" [errorstat ERR] - } + } {} {scripting} test {stats: eventloop metrics} { set info1 [r info stats] diff --git a/tests/unit/introspection-2.tcl b/tests/unit/introspection-2.tcl index b8f4e0aed4b..1a0b99500d5 100644 --- a/tests/unit/introspection-2.tcl +++ b/tests/unit/introspection-2.tcl @@ -116,7 +116,7 @@ start_server {tags {"introspection"}} { assert_match {*calls=2,*} [cmdstat set] assert_match {*calls=1,*} [cmdstat expire] assert_match {*calls=1,*} [cmdstat geoadd] - } {} {needs:config-resetstat} + } {} {needs:config-resetstat scripting} test {COMMAND COUNT get total number of commands} { assert_morethan [r command count] 0 diff --git a/tests/unit/introspection.tcl b/tests/unit/introspection.tcl index 352f5f183e1..6c58d42965e 100644 --- a/tests/unit/introspection.tcl +++ b/tests/unit/introspection.tcl @@ -102,7 +102,7 @@ start_server {tags {"introspection"}} { set info [r client info] set cmd7 [get_field_in_client_info $info "tot-cmds"] assert_equal [expr $cmd6+3] $cmd7 - } + } {} {scripting} test {CLIENT KILL with illegal arguments} { assert_error "ERR wrong number of arguments for 'client|kill' command" {r client kill} @@ -307,7 +307,7 @@ start_server {tags {"introspection"}} { assert_match {*eval*} [$rd read] assert_match {*lua*"set"*"foo"*"bar"*} [$rd read] $rd close - } + } {0} {scripting} test {MONITOR can log commands issued by functions} { r function load replace {#!lua name=test @@ -320,7 +320,7 @@ start_server {tags {"introspection"}} { assert_match {*fcall*test*} [$rd read] assert_match {*lua*"set"*"foo"*"bar"*} [$rd read] $rd close - } + } {0} {scripting} test {MONITOR supports redacting command arguments} { set rd [valkey_deferring_client] @@ -671,7 +671,7 @@ start_server {tags {"introspection"}} { # Restore backup assert_equal [eval "r config set $backups"] "OK" - } + } {} {scripting} test {CONFIG SET rollback on set error} { # This test passes an invalid percent value to maxmemory-clients which should cause an @@ -755,7 +755,7 @@ start_server {tags {"introspection"}} { set r1 [valkey_client] assert_equal [$r1 ping] "PONG" $r1 close - } + } {0} {scripting} test {CONFIG SET duplicate configs} { assert_error "ERR *duplicate*" {r config set maxmemory 10000001 maxmemory 10000002} diff --git a/tests/unit/latency-monitor.tcl b/tests/unit/latency-monitor.tcl index 9048192a44c..9ab2c979dfb 100644 --- a/tests/unit/latency-monitor.tcl +++ b/tests/unit/latency-monitor.tcl @@ -168,7 +168,7 @@ tags {"needs:debug"} { r config set latency-monitor-threshold 200 r config set lazyfree-lazy-expire yes - } + } {OK} {scripting} test {LATENCY HISTORY / RESET with wrong event name is fine} { assert {[llength [r latency history blabla]] == 0} diff --git a/tests/unit/memefficiency.tcl b/tests/unit/memefficiency.tcl index d5a6a6efe25..b8d210d9c74 100644 --- a/tests/unit/memefficiency.tcl +++ b/tests/unit/memefficiency.tcl @@ -261,7 +261,7 @@ run_solo {defrag} { } # Flush all script to make sure we don't crash after defragging them r script flush sync - } {OK} + } {OK} {scripting} test "Active defrag big keys: $type" { r flushdb sync diff --git a/tests/unit/moduleapi/commandfilter.tcl b/tests/unit/moduleapi/commandfilter.tcl index bad68189a0c..99808715e8c 100644 --- a/tests/unit/moduleapi/commandfilter.tcl +++ b/tests/unit/moduleapi/commandfilter.tcl @@ -42,13 +42,13 @@ start_server {tags {"modules"}} { r del log-key r eval "redis.call('ping', '@log')" 0 r lrange log-key 0 -1 - } "{ping @log}" + } "{ping @log}" {scripting} test {Command Filter applies on Lua redis.call() that calls a module} { r del log-key r eval "redis.call('commandfilter.ping')" 0 r lrange log-key 0 -1 - } "{ping @log}" + } "{ping @log}" {scripting} test {Command Filter strings can be retained} { r commandfilter.retained @@ -90,7 +90,7 @@ start_server {tags {"modules"}} { r eval "redis.call('commandfilter.ping')" 0 assert_equal {} [r lrange log-key 0 -1] - } + } {} {scripting} test "Unload the module - commandfilter" { assert_equal {OK} [r module unload commandfilter] @@ -114,7 +114,7 @@ test {RM_CommandFilterArgInsert and script argv caching} { r eval {redis.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} } -} +} {} {scripting} # previously, there was a bug that command filters would be rerun (which would cause args to swap back) # this test is meant to protect against that bug diff --git a/tests/unit/moduleapi/keyspace_events.tcl b/tests/unit/moduleapi/keyspace_events.tcl index 9c1cfa8ba4d..1cb8b2463f8 100644 --- a/tests/unit/moduleapi/keyspace_events.tcl +++ b/tests/unit/moduleapi/keyspace_events.tcl @@ -66,7 +66,7 @@ tags "modules" { assert_equal {} [r get multi] assert_equal {1} [r get lua] r get x - } {3} + } {3} {scripting} test {Test module key space event} { r keyspace.notify x diff --git a/tests/unit/moduleapi/misc.tcl b/tests/unit/moduleapi/misc.tcl index 9e0ea724561..e2d8f89f9bb 100644 --- a/tests/unit/moduleapi/misc.tcl +++ b/tests/unit/moduleapi/misc.tcl @@ -51,7 +51,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { r test.flushall assert_equal [r function list] {{library_name lib engine LUA functions {{name test description {} flags {}}}}} r function flush - } + } {OK} {scripting} test {test module keyexists} { r set x foo @@ -145,7 +145,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { assert_equal {invalidate key1{t}} [$rd_trk read] assert_equal "PONG" [$rd_trk ping] $rd_trk close - } + } {0} {scripting} test {publish to self inside rm_call} { r hello 3 @@ -261,7 +261,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { ] r config set maxmemory 0 - } {OK} {needs:config-maxmemory} + } {OK} {needs:config-maxmemory scripting} test {rm_call write flag} { # add the W flag @@ -285,7 +285,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { return 1 } 1 x } - } + } {} {scripting} # Note: each script is unique, to check that flags are extracted correctly test {rm_call EVAL - OOM - with M flag} { @@ -326,7 +326,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { } 1 x r config set maxmemory 0 - } {OK} {needs:config-maxmemory} + } {OK} {needs:config-maxmemory scripting} # All RM_Call for script succeeds in OOM state without using the M flag test {rm_call EVAL - OOM - without M flag} { @@ -351,7 +351,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { } 1 x r config set maxmemory 0 - } {OK} {needs:config-maxmemory} + } {OK} {needs:config-maxmemory scripting} test "not enough good replicas" { r set x "some value" @@ -385,7 +385,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { } r config set min-replicas-to-write 0 - } + } {OK} {scripting} test {rm_call EVAL - read-only replica} { r replicaof 127.0.0.1 1 @@ -418,7 +418,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { } 1 x r replicaof no one - } {OK} {needs:config-maxmemory} + } {OK} {needs:config-maxmemory scripting} test {rm_call EVAL - stale replica} { r replicaof 127.0.0.1 1 @@ -445,7 +445,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { r replicaof no one r config set replica-serve-stale-data yes - } {OK} {needs:config-maxmemory} + } {OK} {needs:config-maxmemory scripting} test "rm_call EVAL - failed bgsave prevents writes" { r config set rdb-key-save-delay 10000000 @@ -491,7 +491,7 @@ start_server {overrides {save {900 1}} tags {"modules"}} { # server is writable again r set x y - } {OK} + } {OK} {scripting} test "malloc API" { assert_equal {OK} [r test.malloc_api 0] diff --git a/tests/unit/moduleapi/propagate.tcl b/tests/unit/moduleapi/propagate.tcl index 89f79998f06..72667fc14f8 100644 --- a/tests/unit/moduleapi/propagate.tcl +++ b/tests/unit/moduleapi/propagate.tcl @@ -288,7 +288,7 @@ tags "modules" { {exec} } close_replication_stream $repl - } + } {} {scripting} test {module propagates nested ctx case1} { set repl [attach_to_replication_stream] @@ -466,7 +466,7 @@ tags "modules" { {exec} } close_replication_stream $repl - } + } {} {scripting} test {module propagates from command after good EVAL} { set repl [attach_to_replication_stream] @@ -491,7 +491,7 @@ tags "modules" { {exec} } close_replication_stream $repl - } + } {} {scripting} test {module propagates from command after bad EVAL} { set repl [attach_to_replication_stream] @@ -517,7 +517,7 @@ tags "modules" { {exec} } close_replication_stream $repl - } + } {} {scripting} test {module propagates from multi-exec} { set repl [attach_to_replication_stream] @@ -758,6 +758,6 @@ tags "modules aof" { assert_no_match {*calls=*} [cmdrstat set r] } - } + } {} {scripting} } } diff --git a/tests/unit/moduleapi/usercall.tcl b/tests/unit/moduleapi/usercall.tcl index d5cd533be6a..d6ef33a8882 100644 --- a/tests/unit/moduleapi/usercall.tcl +++ b/tests/unit/moduleapi/usercall.tcl @@ -92,7 +92,7 @@ start_server {tags {"modules usercall"}} { assert_equal [r usercall.call_without_user evalsha $sha_set 0] 1 assert_equal [r usercall.call_without_user evalsha $sha_get 0] 1 - } + } {} {scripting} # baseline script test, call without user on script test {test module check eval script with user being set, but not acl testing} { @@ -107,7 +107,7 @@ start_server {tags {"modules usercall"}} { # passes as not checking ACL assert_equal [r usercall.call_with_user_flag {} evalsha $sha_set 0] 1 assert_equal [r usercall.call_with_user_flag {} evalsha $sha_get 0] 1 - } + } {} {scripting} # call with user on script (without rm_call acl check) to ensure user carries through to script execution # we already tested the check in rm_call above, here we are checking the script itself will enforce ACL @@ -132,7 +132,7 @@ start_server {tags {"modules usercall"}} { assert_equal [dict get $entry object] {set} assert_equal [dict get $entry reason] {command} assert_match {*cmd=usercall.call_with_user_flag*} [dict get $entry client-info] - } + } {} {scripting} start_server {tags {"wait aof network external:skip"}} { set slave [srv 0 client] diff --git a/tests/unit/multi.tcl b/tests/unit/multi.tcl index ffdaa3edd47..cc5b6cae563 100644 --- a/tests/unit/multi.tcl +++ b/tests/unit/multi.tcl @@ -555,7 +555,7 @@ start_server {tags {"multi"}} { set pong [$r2 ping asdf] assert_equal $pong "asdf" $rd1 close; $r2 close - } + } {0} {scripting} test {EXEC and script timeout} { # check that if EXEC arrives during timeout, we don't end up executing @@ -580,7 +580,7 @@ start_server {tags {"multi"}} { set pong [$r2 ping asdf] assert_equal $pong "asdf" $rd1 close; $r2 close - } + } {0} {scripting} test {MULTI-EXEC body and script timeout} { # check that we don't run an incomplete transaction due to some commands @@ -605,7 +605,7 @@ start_server {tags {"multi"}} { set pong [$r2 ping asdf] assert_equal $pong "asdf" $rd1 close; $r2 close - } + } {0} {scripting} test {just EXEC and script timeout} { # check that if EXEC arrives during timeout, we don't end up executing @@ -629,7 +629,7 @@ start_server {tags {"multi"}} { set pong [$r2 ping asdf] assert_equal $pong "asdf" $rd1 close; $r2 close - } + } {0} {scripting} test {exec with write commands and state change} { # check that exec that contains write commands fails if server state changed since they were queued @@ -764,7 +764,7 @@ start_server {tags {"multi"}} { {set foo bar} } close_replication_stream $repl - } {} {needs:repl} + } {} {needs:repl scripting} test {MULTI propagation of EVAL} { set repl [attach_to_replication_stream] @@ -779,7 +779,7 @@ start_server {tags {"multi"}} { {set bar bar} } close_replication_stream $repl - } {} {needs:repl} + } {} {needs:repl scripting} test {MULTI propagation of SCRIPT FLUSH} { set repl [attach_to_replication_stream] @@ -795,7 +795,7 @@ start_server {tags {"multi"}} { {set foo bar} } close_replication_stream $repl - } {} {needs:repl} + } {} {needs:repl scripting} tags {"stream"} { test {MULTI propagation of XREADGROUP} { diff --git a/tests/unit/pause.tcl b/tests/unit/pause.tcl index 38c13afc46f..5b829bb5b48 100644 --- a/tests/unit/pause.tcl +++ b/tests/unit/pause.tcl @@ -127,7 +127,7 @@ start_server {tags {"pause network"}} { assert_match "1" [$rd2 read] $rd close $rd2 close - } + } {0} {scripting} test "Test RO scripts are not blocked by pause RO" { r set x y @@ -172,7 +172,7 @@ start_server {tags {"pause network"}} { r client unpause $rr close - } + } {0} {scripting} test "Test read-only scripts in multi-exec are not blocked by pause RO" { r SET FOO BAR @@ -191,7 +191,7 @@ start_server {tags {"pause network"}} { assert_equal [s 0 blocked_clients] 0 r client unpause $rr close - } + } {0} {scripting} test "Test write scripts in multi-exec are blocked by pause RO" { set rd [valkey_deferring_client] @@ -222,7 +222,7 @@ start_server {tags {"pause network"}} { assert_match "13" [$rd2 read] $rd close $rd2 close - } + } {0} {scripting} test "Test may-replicate commands are rejected in RO scripts" { # that's specifically important for CLIENT PAUSE WRITE @@ -236,7 +236,7 @@ start_server {tags {"pause network"}} { } # make sure that publish isn't blocked from a non-RO script assert_equal [r EVAL "return redis.call('publish','ch','msg')" 0] 0 - } + } {} {scripting} test "Test multiple clients can be queued up and unblocked" { r client PAUSE 60000 WRITE diff --git a/tests/unit/pubsub.tcl b/tests/unit/pubsub.tcl index 68dc79a4a42..3fcd15fc053 100644 --- a/tests/unit/pubsub.tcl +++ b/tests/unit/pubsub.tcl @@ -473,7 +473,7 @@ start_server {tags {"pubsub network"}} { assert_equal $res {bla} assert_equal [r read] {message foo bar} assert_equal [r read] {message foo vaz} - } {} {resp3} + } {} {resp3 scripting} test "unsubscribe inside multi, and publish to self" { r hello 3 diff --git a/tests/unit/slowlog.tcl b/tests/unit/slowlog.tcl index 1be530d37fa..d5a984c4bda 100644 --- a/tests/unit/slowlog.tcl +++ b/tests/unit/slowlog.tcl @@ -284,6 +284,6 @@ start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} { assert_equal [lindex $script_cmd 4] [lindex $ping_cmd 4] assert_equal {test-client} [lindex $script_cmd 5] assert_equal {test-client} [lindex $ping_cmd 5] - } + } {} {scripting} } } diff --git a/tests/unit/sort.tcl b/tests/unit/sort.tcl index cd171ee51ec..0f0cfbf165c 100644 --- a/tests/unit/sort.tcl +++ b/tests/unit/sort.tcl @@ -182,7 +182,7 @@ foreach command {SORT SORT_RO} { return {redis.call('sort',KEYS[1],'by','nosort','asc'), redis.call('sort',KEYS[1],'by','nosort','desc')} } 1 zset - } {{a c e b d} {d b e c a}} + } {{a c e b d} {d b e c a}} {scripting} test "SORT sorted set: +inf and -inf handling" { r del zset diff --git a/tests/unit/tracking.tcl b/tests/unit/tracking.tcl index 313293dcb71..bd3cfa4e84f 100644 --- a/tests/unit/tracking.tcl +++ b/tests/unit/tracking.tcl @@ -220,7 +220,7 @@ start_server {tags {"tracking network logreqres:skip"}} { $rd_sg eval "return redis.call('set', 'key1', '2')" 1 key1 assert_equal "2" [$rd_sg GET key1] $rd_sg CLIENT TRACKING off - } + } {OK} {scripting} test {Tracking only occurs for scripts when a command calls a read-only command} { r CLIENT TRACKING off @@ -250,7 +250,7 @@ start_server {tags {"tracking network logreqres:skip"}} { $rd_sg MSET key2{t} 2 key3{t} 2 assert_equal {invalidate key2{t}} [r read] assert_equal "PONG" [r ping] - } + } {} {scripting} test {RESP3 Client gets tracking-redir-broken push message after cached key changed when rediretion client is terminated} { r CLIENT TRACKING on REDIRECT $redir_id diff --git a/tests/unit/wait.tcl b/tests/unit/wait.tcl index 34bea8014af..2fbe0b962cb 100644 --- a/tests/unit/wait.tcl +++ b/tests/unit/wait.tcl @@ -125,7 +125,7 @@ start_server {} { } resume_process $slave_pid - } + } {} {scripting} } }}