diff --git a/runtest-moduleapi b/runtest-moduleapi index 444204919..9301002c9 100755 --- a/runtest-moduleapi +++ b/runtest-moduleapi @@ -13,4 +13,12 @@ then fi make -C tests/modules && \ -$TCLSH tests/test_helper.tcl --single unit/moduleapi/commandfilter --single unit/moduleapi/fork --single unit/moduleapi/testrdb --single unit/moduleapi/infotest --single unit/moduleapi/propagate --single unit/moduleapi/hooks "${@}" +$TCLSH tests/test_helper.tcl \ +--single unit/moduleapi/commandfilter \ +--single unit/moduleapi/fork \ +--single unit/moduleapi/testrdb \ +--single unit/moduleapi/infotest \ +--single unit/moduleapi/propagate \ +--single unit/moduleapi/hooks \ +--single unit/moduleapi/misc \ +"${@}" diff --git a/src/module.c b/src/module.c index 55568aca8..d5f9a50cb 100644 --- a/src/module.c +++ b/src/module.c @@ -3067,7 +3067,10 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch /* We handle the above format error only when the client is setup so that * we can free it normally. */ - if (argv == NULL) goto cleanup; + if (argv == NULL) { + errno = EINVAL; + goto cleanup; + } /* Call command filters */ moduleCallCommandFilters(c); diff --git a/src/redismodule.h b/src/redismodule.h index 434849c77..b464bc3eb 100644 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -186,7 +186,7 @@ typedef struct RedisModuleEvent { struct RedisModuleCtx; typedef void (*RedisModuleEventCallback)(struct RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data); -static RedisModuleEvent +static const RedisModuleEvent RedisModuleEvent_ReplicationRoleChanged = { REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED, 1 diff --git a/tests/modules/Makefile b/tests/modules/Makefile index f357faad2..71c0b5ef8 100644 --- a/tests/modules/Makefile +++ b/tests/modules/Makefile @@ -17,6 +17,7 @@ TEST_MODULES = \ fork.so \ infotest.so \ propagate.so \ + misc.so \ hooks.so .PHONY: all diff --git a/tests/modules/fork.c b/tests/modules/fork.c index 0804e4355..1a139ef1b 100644 --- a/tests/modules/fork.c +++ b/tests/modules/fork.c @@ -1,6 +1,10 @@ #define REDISMODULE_EXPERIMENTAL_API -#include "redismodule.h" +/* define macros for having usleep */ +#define _BSD_SOURCE +#define _DEFAULT_SOURCE + +#include "redismodule.h" #include #include #include diff --git a/tests/modules/misc.c b/tests/modules/misc.c new file mode 100644 index 000000000..fd892f52c --- /dev/null +++ b/tests/modules/misc.c @@ -0,0 +1,55 @@ +#define REDISMODULE_EXPERIMENTAL_API +#include "redismodule.h" + +#include +#include +#include +#include + +int test_call_generic(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) +{ + if (argc<2) { + RedisModule_WrongArity(ctx); + return REDISMODULE_OK; + } + + const char* cmdname = RedisModule_StringPtrLen(argv[1], NULL); + RedisModuleCallReply *reply = RedisModule_Call(ctx, cmdname, "v", argv+2, argc-2); + if (reply) { + RedisModule_ReplyWithCallReply(ctx, reply); + RedisModule_FreeCallReply(reply); + } else { + RedisModule_ReplyWithError(ctx, strerror(errno)); + } + return REDISMODULE_OK; +} + +int test_call_info(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) +{ + RedisModuleCallReply *reply; + if (argc>1) + reply = RedisModule_Call(ctx, "info", "s", argv[1]); + else + reply = RedisModule_Call(ctx, "info", ""); + if (reply) { + RedisModule_ReplyWithCallReply(ctx, reply); + RedisModule_FreeCallReply(reply); + } else { + RedisModule_ReplyWithError(ctx, strerror(errno)); + } + return REDISMODULE_OK; +} + +int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + REDISMODULE_NOT_USED(argv); + REDISMODULE_NOT_USED(argc); + if (RedisModule_Init(ctx,"misc",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx,"test.call_generic", test_call_generic,"",0,0,0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,"test.call_info", test_call_info,"",0,0,0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + return REDISMODULE_OK; +} diff --git a/tests/unit/moduleapi/misc.tcl b/tests/unit/moduleapi/misc.tcl new file mode 100644 index 000000000..d392aeab0 --- /dev/null +++ b/tests/unit/moduleapi/misc.tcl @@ -0,0 +1,19 @@ +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] } + } + +}