libredismodule_la_SOURCES = \
include/redismodule.h\
- src/exstrings.c
+ src/exstrings.c
libredismodule_la_CFLAGS = \
- -std=c11 -fPIC -g \
- -I${includedir} -I${top_srcdir}/include
+ -std=c11 -fPIC -g -Wall -Werror -Wextra \
+ -DREDISMODULE_EXPERIMENTAL_API \
+ -I${includedir} -I${top_srcdir}/include
libredismodule_la_LDFLAGS = $(BASE_LDFLAGS) -avoid-version -module -shared
#pkgincludedir = ${includedir}
-#pkginclude_HEADERS = include/redismodule.h
+#pkginclude_HEADERS = include/redismodule.h
-clean-local:
+clean-local:
rm -rf ${builddir}/libredismodule.pc
+if UNIT_TEST_ENABLED
# UT
CPP_U_TEST=$(CPP_U_TEST_LATEST)
check_PROGRAMS = redismodule_ut
-#TESTS = ${check_PROGRAMS}
+#TESTS = ${check_PROGRAMS}
redismodule_ut_SOURCES = \
- tst/mock/include/redismodule.h \
- tst/mock/include/exstringsStub.h \
src/exstrings.c \
+ tst/mock/include/commonStub.h \
+ tst/mock/include/exstringsStub.h \
+ tst/mock/include/redismodule.h \
+ tst/mock/src/commonStub.cpp \
tst/mock/src/redismoduleStub.cpp \
- tst/src/main.cpp \
- tst/src/exstrings_test.cpp
+ tst/src/exstrings_test.cpp \
+ tst/src/main.cpp
redismodule_ut_CFLAGS = \
- -std=c11 -g -Wall \
- -fprofile-arcs -ftest-coverage \
- -D__UT__ \
+ -std=c11 -g -Wall \
+ -fprofile-arcs -ftest-coverage \
+ -D__UT__ \
+ $(LIBCPPUTEST_CFLAGS) \
-I${top_srcdir}/tst/mock/include \
-I${includedir} \
-I${top_srcdir}/include \
- -I${CPP_U_TEST_LATEST}/include
+ -I${CPP_U_TEST_LATEST}/include \
+ -Wall -Werror -Wextra
redismodule_ut_CXXFLAGS = \
-std=c++11 -g -Wall \
-fprofile-arcs -ftest-coverage \
-D__UT__ \
+ $(LIBCPPUTEST_CFLAGS) \
-I${top_srcdir}/tst/mock/include \
-I${includedir} \
-I${top_srcdir}/include \
- -I${CPP_U_TEST_LATEST}/include
+ -I${CPP_U_TEST_LATEST}/include \
+ -Wall -Werror -Wextra
redismodule_ut_LDFLAGS = -Wl,-rpath=${libdir} ${UT_COVERAGE_LDFLAGS}
-redismodule_ut_LDADD = -L${libdir} -L${CPP_U_TEST_LATEST}/lib -lCppUTest -lCppUTestExt -lgcov
+redismodule_ut_LDADD = -L${libdir} $(LIBCPPUTEST_LIBS) -lgcov
+
test: redismodule_ut
./run-tests.sh
TESTS = run-tests.sh
+
+else
+
+test:
+ echo 'enable ut with configure flag: --enable-unit-test'
+ exit 1
+
+endif #UNIT_TEST_ENABLED
This subdirectory provides implementation for the commands which are implemented
as a [Redis modules](https://redis.io/topics/modules-intro).
+# Compiling and UT (Unit Tests)
+
+To compile and install run standard automake commands
+in the redismodule directory:
+```
+./autogen.sh
+./configure
+make
+make install
+```
+
+To run unit tests `cpputest` and `valgrind`
+need to be installed as additional dependencies.
+To enable and run unit tests use the commands:
+```
+./autogen.sh
+./configure --enable-unit-test
+make test
+```
+
# Commands
## SETIE key value oldvalue [expiration EX seconds|PX milliseconds]
AC_PROG_INSTALL
AC_PROG_MAKE_SET
+AC_ARG_ENABLE([unit-test],
+[ --enable-unit-test Check for UT dependencies],
+[ PKG_CHECK_MODULES([LIBCPPUTEST],[cpputest])
+ AC_CHECK_PROG(VALGRIND_CHECK, valgrind, yes)
+ AS_IF([test x"$VALGRIND_CHECK" != x"yes"], [AC_MSG_ERROR([Install valgrind to run UT.])])
+ UNIT_TEST_ENABLED=true
+],
+[ UNIT_TEST_ENABLED=false ])
+AM_CONDITIONAL([UNIT_TEST_ENABLED], [$UNIT_TEST_ENABLED])
# Checks for header files.
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define REDISMODULE_HASH_CFIELDS (1<<2)
#define REDISMODULE_HASH_EXISTS (1<<3)
-/* Context Flags: Info about the current context returned by RM_GetContextFlags */
+/* Context Flags: Info about the current context returned by
+ * RM_GetContextFlags(). */
/* The command is running in the context of a Lua script */
-#define REDISMODULE_CTX_FLAGS_LUA 0x0001
+#define REDISMODULE_CTX_FLAGS_LUA (1<<0)
/* The command is running inside a Redis transaction */
-#define REDISMODULE_CTX_FLAGS_MULTI 0x0002
+#define REDISMODULE_CTX_FLAGS_MULTI (1<<1)
/* The instance is a master */
-#define REDISMODULE_CTX_FLAGS_MASTER 0x0004
+#define REDISMODULE_CTX_FLAGS_MASTER (1<<2)
/* The instance is a slave */
-#define REDISMODULE_CTX_FLAGS_SLAVE 0x0008
+#define REDISMODULE_CTX_FLAGS_SLAVE (1<<3)
/* The instance is read-only (usually meaning it's a slave as well) */
-#define REDISMODULE_CTX_FLAGS_READONLY 0x0010
+#define REDISMODULE_CTX_FLAGS_READONLY (1<<4)
/* The instance is running in cluster mode */
-#define REDISMODULE_CTX_FLAGS_CLUSTER 0x0020
+#define REDISMODULE_CTX_FLAGS_CLUSTER (1<<5)
/* The instance has AOF enabled */
-#define REDISMODULE_CTX_FLAGS_AOF 0x0040 //
+#define REDISMODULE_CTX_FLAGS_AOF (1<<6)
/* The instance has RDB enabled */
-#define REDISMODULE_CTX_FLAGS_RDB 0x0080 //
+#define REDISMODULE_CTX_FLAGS_RDB (1<<7)
/* The instance has Maxmemory set */
-#define REDISMODULE_CTX_FLAGS_MAXMEMORY 0x0100
+#define REDISMODULE_CTX_FLAGS_MAXMEMORY (1<<8)
/* Maxmemory is set and has an eviction policy that may delete keys */
-#define REDISMODULE_CTX_FLAGS_EVICT 0x0200
+#define REDISMODULE_CTX_FLAGS_EVICT (1<<9)
+/* Redis is out of memory according to the maxmemory flag. */
+#define REDISMODULE_CTX_FLAGS_OOM (1<<10)
+/* Less than 25% of memory available according to maxmemory. */
+#define REDISMODULE_CTX_FLAGS_OOM_WARNING (1<<11)
+/* The command was sent over the replication link. */
+#define REDISMODULE_CTX_FLAGS_REPLICATED (1<<12)
+/* Redis is currently loading either from AOF or RDB. */
+#define REDISMODULE_CTX_FLAGS_LOADING (1<<13)
#define REDISMODULE_NOTIFY_GENERIC (1<<2) /* g */
#define REDISMODULE_NOTIFY_ZSET (1<<7) /* z */
#define REDISMODULE_NOTIFY_EXPIRED (1<<8) /* x */
#define REDISMODULE_NOTIFY_EVICTED (1<<9) /* e */
-#define REDISMODULE_NOTIFY_ALL (REDISMODULE_NOTIFY_GENERIC | REDISMODULE_NOTIFY_STRING | REDISMODULE_NOTIFY_LIST | REDISMODULE_NOTIFY_SET | REDISMODULE_NOTIFY_HASH | REDISMODULE_NOTIFY_ZSET | REDISMODULE_NOTIFY_EXPIRED | REDISMODULE_NOTIFY_EVICTED) /* A */
+#define REDISMODULE_NOTIFY_STREAM (1<<10) /* t */
+#define REDISMODULE_NOTIFY_ALL (REDISMODULE_NOTIFY_GENERIC | REDISMODULE_NOTIFY_STRING | REDISMODULE_NOTIFY_LIST | REDISMODULE_NOTIFY_SET | REDISMODULE_NOTIFY_HASH | REDISMODULE_NOTIFY_ZSET | REDISMODULE_NOTIFY_EXPIRED | REDISMODULE_NOTIFY_EVICTED | REDISMODULE_NOTIFY_STREAM) /* A */
/* A special pointer that we can use between the core and the module to signal
#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0)
#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0)
+/* Cluster API defines. */
+#define REDISMODULE_NODE_ID_LEN 40
+#define REDISMODULE_NODE_MYSELF (1<<0)
+#define REDISMODULE_NODE_MASTER (1<<1)
+#define REDISMODULE_NODE_SLAVE (1<<2)
+#define REDISMODULE_NODE_PFAIL (1<<3)
+#define REDISMODULE_NODE_FAIL (1<<4)
+#define REDISMODULE_NODE_NOFAILOVER (1<<5)
+
+#define REDISMODULE_CLUSTER_FLAG_NONE 0
+#define REDISMODULE_CLUSTER_FLAG_NO_FAILOVER (1<<1)
+#define REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION (1<<2)
+
#define REDISMODULE_NOT_USED(V) ((void) V)
+/* Bit flags for aux_save_triggers and the aux_load and aux_save callbacks */
+#define REDISMODULE_AUX_BEFORE_RDB (1<<0)
+#define REDISMODULE_AUX_AFTER_RDB (1<<1)
+
+/* This type represents a timer handle, and is returned when a timer is
+ * registered and used in order to invalidate a timer. It's just a 64 bit
+ * number, because this is how each timer is represented inside the radix tree
+ * of timers that are going to expire, sorted by expire time. */
+typedef uint64_t RedisModuleTimerID;
+
+/* CommandFilter Flags */
+
+/* Do filter RedisModule_Call() commands initiated by module itself. */
+#define REDISMODULE_CMDFILTER_NOSELF (1<<0)
+
/* ------------------------- End of common defines ------------------------ */
#ifndef REDISMODULE_CORE
typedef struct RedisModuleType RedisModuleType;
typedef struct RedisModuleDigest RedisModuleDigest;
typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
-
-typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
-
-typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
+typedef struct RedisModuleClusterInfo RedisModuleClusterInfo;
+typedef struct RedisModuleDict RedisModuleDict;
+typedef struct RedisModuleDictIter RedisModuleDictIter;
+typedef struct RedisModuleCommandFilterCtx RedisModuleCommandFilterCtx;
+typedef struct RedisModuleCommandFilter RedisModuleCommandFilter;
+
+typedef int (*RedisModuleCmdFunc)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
+typedef void (*RedisModuleDisconnectFunc)(RedisModuleCtx *ctx, RedisModuleBlockedClient *bc);
+typedef int (*RedisModuleNotificationFunc)(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
+typedef int (*RedisModuleTypeAuxLoadFunc)(RedisModuleIO *rdb, int encver, int when);
+typedef void (*RedisModuleTypeAuxSaveFunc)(RedisModuleIO *rdb, int when);
typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value);
typedef size_t (*RedisModuleTypeMemUsageFunc)(const void *value);
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
typedef void (*RedisModuleTypeFreeFunc)(void *value);
+typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
+typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
+typedef void (*RedisModuleCommandFilterFunc) (RedisModuleCommandFilterCtx *filter);
-#define REDISMODULE_TYPE_METHOD_VERSION 1
+#define REDISMODULE_TYPE_METHOD_VERSION 2
typedef struct RedisModuleTypeMethods {
uint64_t version;
RedisModuleTypeLoadFunc rdb_load;
RedisModuleTypeMemUsageFunc mem_usage;
RedisModuleTypeDigestFunc digest;
RedisModuleTypeFreeFunc free;
+ RedisModuleTypeAuxLoadFunc aux_load;
+ RedisModuleTypeAuxSaveFunc aux_save;
+ int aux_save_triggers;
} RedisModuleTypeMethods;
#define REDISMODULE_GET_API(name) \
int REDISMODULE_API_FUNC(RedisModule_ReplyWithArray)(RedisModuleCtx *ctx, long len);
void REDISMODULE_API_FUNC(RedisModule_ReplySetArrayLength)(RedisModuleCtx *ctx, long len);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithStringBuffer)(RedisModuleCtx *ctx, const char *buf, size_t len);
+int REDISMODULE_API_FUNC(RedisModule_ReplyWithCString)(RedisModuleCtx *ctx, const char *buf);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithString)(RedisModuleCtx *ctx, RedisModuleString *str);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithNull)(RedisModuleCtx *ctx);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithDouble)(RedisModuleCtx *ctx, double d);
void REDISMODULE_API_FUNC(RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str);
int REDISMODULE_API_FUNC(RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b);
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetContextFromIO)(RedisModuleIO *io);
+const RedisModuleString *REDISMODULE_API_FUNC(RedisModule_GetKeyNameFromIO)(RedisModuleIO *io);
long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void);
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
void REDISMODULE_API_FUNC(RedisModule_DigestEndSequence)(RedisModuleDigest *md);
+RedisModuleDict *REDISMODULE_API_FUNC(RedisModule_CreateDict)(RedisModuleCtx *ctx);
+void REDISMODULE_API_FUNC(RedisModule_FreeDict)(RedisModuleCtx *ctx, RedisModuleDict *d);
+uint64_t REDISMODULE_API_FUNC(RedisModule_DictSize)(RedisModuleDict *d);
+int REDISMODULE_API_FUNC(RedisModule_DictSetC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr);
+int REDISMODULE_API_FUNC(RedisModule_DictReplaceC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr);
+int REDISMODULE_API_FUNC(RedisModule_DictSet)(RedisModuleDict *d, RedisModuleString *key, void *ptr);
+int REDISMODULE_API_FUNC(RedisModule_DictReplace)(RedisModuleDict *d, RedisModuleString *key, void *ptr);
+void *REDISMODULE_API_FUNC(RedisModule_DictGetC)(RedisModuleDict *d, void *key, size_t keylen, int *nokey);
+void *REDISMODULE_API_FUNC(RedisModule_DictGet)(RedisModuleDict *d, RedisModuleString *key, int *nokey);
+int REDISMODULE_API_FUNC(RedisModule_DictDelC)(RedisModuleDict *d, void *key, size_t keylen, void *oldval);
+int REDISMODULE_API_FUNC(RedisModule_DictDel)(RedisModuleDict *d, RedisModuleString *key, void *oldval);
+RedisModuleDictIter *REDISMODULE_API_FUNC(RedisModule_DictIteratorStartC)(RedisModuleDict *d, const char *op, void *key, size_t keylen);
+RedisModuleDictIter *REDISMODULE_API_FUNC(RedisModule_DictIteratorStart)(RedisModuleDict *d, const char *op, RedisModuleString *key);
+void REDISMODULE_API_FUNC(RedisModule_DictIteratorStop)(RedisModuleDictIter *di);
+int REDISMODULE_API_FUNC(RedisModule_DictIteratorReseekC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
+int REDISMODULE_API_FUNC(RedisModule_DictIteratorReseek)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
+void *REDISMODULE_API_FUNC(RedisModule_DictNextC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr);
+void *REDISMODULE_API_FUNC(RedisModule_DictPrevC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr);
+RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictNext)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr);
+RedisModuleString *REDISMODULE_API_FUNC(RedisModule_DictPrev)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr);
+int REDISMODULE_API_FUNC(RedisModule_DictCompareC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen);
+int REDISMODULE_API_FUNC(RedisModule_DictCompare)(RedisModuleDictIter *di, const char *op, RedisModuleString *key);
/* Experimental APIs */
#ifdef REDISMODULE_EXPERIMENTAL_API
-RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(void*), long long timeout_ms);
+#define REDISMODULE_EXPERIMENTAL_API_VERSION 3
+RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms);
int REDISMODULE_API_FUNC(RedisModule_UnblockClient)(RedisModuleBlockedClient *bc, void *privdata);
int REDISMODULE_API_FUNC(RedisModule_IsBlockedReplyRequest)(RedisModuleCtx *ctx);
int REDISMODULE_API_FUNC(RedisModule_IsBlockedTimeoutRequest)(RedisModuleCtx *ctx);
void *REDISMODULE_API_FUNC(RedisModule_GetBlockedClientPrivateData)(RedisModuleCtx *ctx);
+RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_GetBlockedClientHandle)(RedisModuleCtx *ctx);
int REDISMODULE_API_FUNC(RedisModule_AbortBlock)(RedisModuleBlockedClient *bc);
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetThreadSafeContext)(RedisModuleBlockedClient *bc);
void REDISMODULE_API_FUNC(RedisModule_FreeThreadSafeContext)(RedisModuleCtx *ctx);
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextLock)(RedisModuleCtx *ctx);
void REDISMODULE_API_FUNC(RedisModule_ThreadSafeContextUnlock)(RedisModuleCtx *ctx);
int REDISMODULE_API_FUNC(RedisModule_SubscribeToKeyspaceEvents)(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc cb);
-
+int REDISMODULE_API_FUNC(RedisModule_BlockedClientDisconnected)(RedisModuleCtx *ctx);
+void REDISMODULE_API_FUNC(RedisModule_RegisterClusterMessageReceiver)(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback);
+int REDISMODULE_API_FUNC(RedisModule_SendClusterMessage)(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len);
+int REDISMODULE_API_FUNC(RedisModule_GetClusterNodeInfo)(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags);
+char **REDISMODULE_API_FUNC(RedisModule_GetClusterNodesList)(RedisModuleCtx *ctx, size_t *numnodes);
+void REDISMODULE_API_FUNC(RedisModule_FreeClusterNodesList)(char **ids);
+RedisModuleTimerID REDISMODULE_API_FUNC(RedisModule_CreateTimer)(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data);
+int REDISMODULE_API_FUNC(RedisModule_StopTimer)(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data);
+int REDISMODULE_API_FUNC(RedisModule_GetTimerInfo)(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data);
+const char *REDISMODULE_API_FUNC(RedisModule_GetMyClusterID)(void);
+size_t REDISMODULE_API_FUNC(RedisModule_GetClusterSize)(void);
+void REDISMODULE_API_FUNC(RedisModule_GetRandomBytes)(unsigned char *dst, size_t len);
+void REDISMODULE_API_FUNC(RedisModule_GetRandomHexChars)(char *dst, size_t len);
+void REDISMODULE_API_FUNC(RedisModule_SetDisconnectCallback)(RedisModuleBlockedClient *bc, RedisModuleDisconnectFunc callback);
+void REDISMODULE_API_FUNC(RedisModule_SetClusterFlags)(RedisModuleCtx *ctx, uint64_t flags);
+int REDISMODULE_API_FUNC(RedisModule_ExportSharedAPI)(RedisModuleCtx *ctx, const char *apiname, void *func);
+void *REDISMODULE_API_FUNC(RedisModule_GetSharedAPI)(RedisModuleCtx *ctx, const char *apiname);
+RedisModuleCommandFilter *REDISMODULE_API_FUNC(RedisModule_RegisterCommandFilter)(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc cb, int flags);
+int REDISMODULE_API_FUNC(RedisModule_UnregisterCommandFilter)(RedisModuleCtx *ctx, RedisModuleCommandFilter *filter);
+int REDISMODULE_API_FUNC(RedisModule_CommandFilterArgsCount)(RedisModuleCommandFilterCtx *fctx);
+const RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CommandFilterArgGet)(RedisModuleCommandFilterCtx *fctx, int pos);
+int REDISMODULE_API_FUNC(RedisModule_CommandFilterArgInsert)(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg);
+int REDISMODULE_API_FUNC(RedisModule_CommandFilterArgReplace)(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg);
+int REDISMODULE_API_FUNC(RedisModule_CommandFilterArgDelete)(RedisModuleCommandFilterCtx *fctx, int pos);
#endif
/* This is included inline inside each Redis module. */
REDISMODULE_GET_API(ReplyWithArray);
REDISMODULE_GET_API(ReplySetArrayLength);
REDISMODULE_GET_API(ReplyWithStringBuffer);
+ REDISMODULE_GET_API(ReplyWithCString);
REDISMODULE_GET_API(ReplyWithString);
REDISMODULE_GET_API(ReplyWithNull);
REDISMODULE_GET_API(ReplyWithCallReply);
REDISMODULE_GET_API(RetainString);
REDISMODULE_GET_API(StringCompare);
REDISMODULE_GET_API(GetContextFromIO);
+ REDISMODULE_GET_API(GetKeyNameFromIO);
REDISMODULE_GET_API(Milliseconds);
REDISMODULE_GET_API(DigestAddStringBuffer);
REDISMODULE_GET_API(DigestAddLongLong);
REDISMODULE_GET_API(DigestEndSequence);
+ REDISMODULE_GET_API(CreateDict);
+ REDISMODULE_GET_API(FreeDict);
+ REDISMODULE_GET_API(DictSize);
+ REDISMODULE_GET_API(DictSetC);
+ REDISMODULE_GET_API(DictReplaceC);
+ REDISMODULE_GET_API(DictSet);
+ REDISMODULE_GET_API(DictReplace);
+ REDISMODULE_GET_API(DictGetC);
+ REDISMODULE_GET_API(DictGet);
+ REDISMODULE_GET_API(DictDelC);
+ REDISMODULE_GET_API(DictDel);
+ REDISMODULE_GET_API(DictIteratorStartC);
+ REDISMODULE_GET_API(DictIteratorStart);
+ REDISMODULE_GET_API(DictIteratorStop);
+ REDISMODULE_GET_API(DictIteratorReseekC);
+ REDISMODULE_GET_API(DictIteratorReseek);
+ REDISMODULE_GET_API(DictNextC);
+ REDISMODULE_GET_API(DictPrevC);
+ REDISMODULE_GET_API(DictNext);
+ REDISMODULE_GET_API(DictPrev);
+ REDISMODULE_GET_API(DictCompare);
+ REDISMODULE_GET_API(DictCompareC);
#ifdef REDISMODULE_EXPERIMENTAL_API
REDISMODULE_GET_API(GetThreadSafeContext);
REDISMODULE_GET_API(IsBlockedReplyRequest);
REDISMODULE_GET_API(IsBlockedTimeoutRequest);
REDISMODULE_GET_API(GetBlockedClientPrivateData);
+ REDISMODULE_GET_API(GetBlockedClientHandle);
REDISMODULE_GET_API(AbortBlock);
+ REDISMODULE_GET_API(SetDisconnectCallback);
REDISMODULE_GET_API(SubscribeToKeyspaceEvents);
-
+ REDISMODULE_GET_API(BlockedClientDisconnected);
+ REDISMODULE_GET_API(RegisterClusterMessageReceiver);
+ REDISMODULE_GET_API(SendClusterMessage);
+ REDISMODULE_GET_API(GetClusterNodeInfo);
+ REDISMODULE_GET_API(GetClusterNodesList);
+ REDISMODULE_GET_API(FreeClusterNodesList);
+ REDISMODULE_GET_API(CreateTimer);
+ REDISMODULE_GET_API(StopTimer);
+ REDISMODULE_GET_API(GetTimerInfo);
+ REDISMODULE_GET_API(GetMyClusterID);
+ REDISMODULE_GET_API(GetClusterSize);
+ REDISMODULE_GET_API(GetRandomBytes);
+ REDISMODULE_GET_API(GetRandomHexChars);
+ REDISMODULE_GET_API(SetClusterFlags);
+ REDISMODULE_GET_API(ExportSharedAPI);
+ REDISMODULE_GET_API(GetSharedAPI);
+ REDISMODULE_GET_API(RegisterCommandFilter);
+ REDISMODULE_GET_API(UnregisterCommandFilter);
+ REDISMODULE_GET_API(CommandFilterArgsCount);
+ REDISMODULE_GET_API(CommandFilterArgGet);
+ REDISMODULE_GET_API(CommandFilterArgInsert);
+ REDISMODULE_GET_API(CommandFilterArgReplace);
+ REDISMODULE_GET_API(CommandFilterArgDelete);
#endif
if (RedisModule_IsModuleNameBusy && RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR;
#!/bin/sh
-./redismodule_ut
+valgrind --leak-check=full ./redismodule_ut
if [ $? != 0 ]
then
exit -1
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
#include "redismodule.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
+#include <pthread.h>
#include <stdbool.h>
-#include "../../redismodule/include/redismodule.h"
#ifdef __UT__
#include "exstringsStub.h"
+#include "commonStub.h"
#endif
+
/* make sure the response is not NULL or an error.
sends the error to the client and exit the current function if its */
#define ASSERT_NOERROR(r) \
if (r == NULL) { \
return RedisModule_ReplyWithError(ctx,"ERR reply is NULL"); \
} else if (RedisModule_CallReplyType(r) == REDISMODULE_REPLY_ERROR) { \
- RedisModule_ReplyWithCallReply(ctx,r); \
- RedisModule_FreeCallReply(r); \
- return REDISMODULE_ERR; \
+ return RedisModule_ReplyWithCallReply(ctx,r); \
}
#define OBJ_OP_NO 0
#define OBJ_OP_IE (1<<4) /* OP if equal old value */
#define OBJ_OP_NE (1<<5) /* OP if not equal old value */
+#define DEF_COUNT 50
+#define ZERO 0
+#define MATCH_STR "MATCH"
+#define COUNT_STR "COUNT"
+#define SCANARGC 5
+
+RedisModuleString *def_count_str = NULL, *match_str = NULL, *count_str = NULL, *zero_str = NULL;
+
+void InitStaticVariable()
+{
+ if (def_count_str == NULL)
+ def_count_str = RedisModule_CreateStringFromLongLong(NULL, DEF_COUNT);
+ if (match_str == NULL)
+ match_str = RedisModule_CreateString(NULL, MATCH_STR, sizeof(MATCH_STR));
+ if (count_str == NULL)
+ count_str = RedisModule_CreateString(NULL, COUNT_STR, sizeof(COUNT_STR));
+ if (zero_str == NULL)
+ zero_str = RedisModule_CreateStringFromLongLong(NULL, ZERO);
+
+ return;
+}
+
int getKeyType(RedisModuleCtx *ctx, RedisModuleString *key_str)
{
RedisModuleKey *key = RedisModule_OpenKey(ctx, key_str, REDISMODULE_READ);
int SetIE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ RedisModule_AutoMemory(ctx);
return setStringGenericCommand(ctx, argv, argc, OBJ_OP_IE);
}
int SetNE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ RedisModule_AutoMemory(ctx);
return setStringGenericCommand(ctx, argv, argc, OBJ_OP_NE);
}
int DelIE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ RedisModule_AutoMemory(ctx);
return delStringGenericCommand(ctx, argv, argc, OBJ_OP_IE);
}
int DelNE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ RedisModule_AutoMemory(ctx);
return delStringGenericCommand(ctx, argv, argc, OBJ_OP_NE);
}
-
-int NGet_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
-{
- RedisModuleCallReply *reply = NULL;
-
- if (argc != 2)
- return RedisModule_WrongArity(ctx);
-
- /* Call the command to get keys with pattern. */
- reply = RedisModule_Call(ctx, "KEYS", "s", argv[1]);
- ASSERT_NOERROR(reply)
-
- /* Prepare the arguments for the command. */
- size_t items = RedisModule_CallReplyLength(reply);
- if (items == 0) {
- //RedisModule_ReplyWithArray(ctx, items);
- RedisModule_ReplyWithCallReply(ctx, reply);
- RedisModule_FreeCallReply(reply);
- }
- else {
- RedisModuleString *cmdargv[items];
- size_t i=0, j;
- for (j = 0; j < items; j++) {
- RedisModuleString *rms = RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j));
- cmdargv[i++] = rms;
-
- /*Assume all keys via SDL is string type for sake of saving time*/
-#if 0
- /*Check if key type is string*/
- RedisModuleKey *key = RedisModule_OpenKey(ctx, rms ,REDISMODULE_READ);
-
- if (key) {
- int type = RedisModule_KeyType(key);
- RedisModule_CloseKey(key);
- if (type == REDISMODULE_KEYTYPE_STRING) {
- cmdargv[i++] = rms;
- }
- } else {
- RedisModule_CloseKey(key);
- }
-#endif
- }
- RedisModule_FreeCallReply(reply);
-
- reply = RedisModule_Call(ctx, "MGET", "v", cmdargv, i);
- ASSERT_NOERROR(reply)
- items = RedisModule_CallReplyLength(reply);
- RedisModule_ReplyWithArray(ctx, i*2);
- for (j = 0; (j<items && j<i); j++) {
- RedisModule_ReplyWithString(ctx, cmdargv[j]);
- RedisModule_ReplyWithString(ctx, RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j)));
- }
-
- RedisModule_FreeCallReply(reply);
- }
-
- return REDISMODULE_OK;
-}
-
-int NDel_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
-{
- RedisModuleCallReply *reply = NULL;
-
- if (argc != 2)
- return RedisModule_WrongArity(ctx);
-
- /* Call the command to get keys with pattern. */
- reply = RedisModule_Call(ctx, "KEYS", "s", argv[1]);
- ASSERT_NOERROR(reply)
-
- /* Prepare the arguments for the command. */
- size_t items = RedisModule_CallReplyLength(reply);
- if (items == 0) {
- RedisModule_ReplyWithLongLong(ctx, 0);
- RedisModule_FreeCallReply(reply);
- }
- else {
- RedisModuleString *cmdargv[items];
- size_t i=0, j;
- for (j = 0; j < items; j++) {
- RedisModuleString *rms = RedisModule_CreateStringFromCallReply(RedisModule_CallReplyArrayElement(reply, j));
- cmdargv[i++] = rms;
-
- /*Assume all keys via SDL is string type for sake of saving time*/
-#if 0
- //Check if key type is string
- RedisModuleKey *key = RedisModule_OpenKey(ctx, rms ,REDISMODULE_READ);
-
- if (key) {
- int type = RedisModule_KeyType(key);
- RedisModule_CloseKey(key);
- if (type == REDISMODULE_KEYTYPE_STRING) {
- cmdargv[i++] = rms;
- }
- } else {
- RedisModule_CloseKey(key);
- }
-#endif
- }
- RedisModule_FreeCallReply(reply);
-
- reply = RedisModule_Call(ctx, "UNLINK", "v!", cmdargv, i);
- ASSERT_NOERROR(reply)
- RedisModule_ReplyWithCallReply(ctx, reply);
- RedisModule_FreeCallReply(reply);
-
- }
-
- return REDISMODULE_OK;
-}
-
int setPubStringCommon(RedisModuleCtx *ctx, SetParams* setParamsPtr, PubParams* pubParamsPtr)
{
RedisModuleCallReply *setReply;
setReply = RedisModule_Call(ctx, "MSET", "v!", setParamsPtr->key_val_pairs, setParamsPtr->length);
ASSERT_NOERROR(setReply)
- int replytype = RedisModule_CallReplyType(setReply);
- if (replytype == REDISMODULE_REPLY_NULL) {
- RedisModule_ReplyWithNull(ctx);
- } else {
- multiPubCommand(ctx, pubParamsPtr);
- RedisModule_ReplyWithCallReply(ctx, setReply);
- }
+ multiPubCommand(ctx, pubParamsPtr);
+ RedisModule_ReplyWithCallReply(ctx, setReply);
RedisModule_FreeCallReply(setReply);
return REDISMODULE_OK;
}
if (argc < 5 || (argc % 2) == 0)
return RedisModule_WrongArity(ctx);
+ RedisModule_AutoMemory(ctx);
SetParams setParams = {
.key_val_pairs = argv + 1,
.length = argc - 3
};
PubParams pubParams = {
- .channel_msg_pairs = argv + argc - 2,
+ .channel_msg_pairs = argv + 1 + setParams.length,
.length = 2
};
if (argc < 7 || (argc % 2) == 0)
return RedisModule_WrongArity(ctx);
+ RedisModule_AutoMemory(ctx);
long long setPairsCount, pubPairsCount;
RedisModule_StringToLongLong(argv[1], &setPairsCount);
RedisModule_StringToLongLong(argv[2], &pubPairsCount);
long long setLen, pubLen;
setLen = 2*setPairsCount;
pubLen = 2*pubPairsCount;
+
if (setLen + pubLen + 3 != argc)
return RedisModule_ReplyWithError(ctx, "ERR SET_PAIR_COUNT or PUB_PAIR_COUNT do not match the total pair count");
int setIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
{
- if (argc < 6 || (argc % 2) != 0)
- return RedisModule_WrongArity(ctx);
-
SetParams setParams = {
.key_val_pairs = argv + 1,
.length = 2
return setPubStringCommon(ctx, &setParams, &pubParams);
}
-int SetNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+int SetIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
- return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+ if (argc != 6)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
}
-int SetIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+int SetIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ if (argc < 6 || (argc % 2) != 0)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
}
-int setXXNXPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
+int SetNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
- if (argc < 5 || (argc % 2) == 0)
+ if (argc != 6)
return RedisModule_WrongArity(ctx);
+ RedisModule_AutoMemory(ctx);
+ return setIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+}
+
+int setXXNXPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
+{
SetParams setParams = {
.key_val_pairs = argv + 1,
.length = 2
int SetNXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ if (argc != 5)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_NX);
+}
+
+int SetNXMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+{
+ if (argc < 5 || (argc % 2) == 0)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_NX);
}
int SetXXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
+ if (argc != 5)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
return setXXNXPubStringCommon(ctx, argv, argc, OBJ_OP_XX);
}
if (argc < 4)
return RedisModule_WrongArity(ctx);
+ RedisModule_AutoMemory(ctx);
DelParams delParams = {
.keys = argv + 1,
.length = argc - 3
if (argc < 6)
return RedisModule_WrongArity(ctx);
+ RedisModule_AutoMemory(ctx);
long long delCount, pubPairsCount;
RedisModule_StringToLongLong(argv[1], &delCount);
RedisModule_StringToLongLong(argv[2], &pubPairsCount);
int delIENEPubStringCommon(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int flag)
{
- if (argc < 5 || (argc % 2) == 0)
- return RedisModule_WrongArity(ctx);
-
DelParams delParams = {
.keys = argv + 1,
.length = 1
int DelIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
- return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
+ if (argc != 5)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
+}
+
+int DelIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+{
+ if (argc < 5 || (argc % 2) == 0)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_IE);
}
int DelNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
- return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
+ if (argc != 5)
+ return RedisModule_WrongArity(ctx);
+
+ RedisModule_AutoMemory(ctx);
+ return delIENEPubStringCommon(ctx, argv, argc, OBJ_OP_NE);
}
/* This function must be present on each Redis module. It is used in order to
DelNE_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
- if (RedisModule_CreateCommand(ctx,"nget",
- NGet_RedisCommand,"readonly",1,1,1) == REDISMODULE_ERR)
- return REDISMODULE_ERR;
-
- if (RedisModule_CreateCommand(ctx,"ndel",
- NDel_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
- return REDISMODULE_ERR;
-
if (RedisModule_CreateCommand(ctx,"msetpub",
SetPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
SetIEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx,"setiempub",
+ SetIEMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx,"setnepub",
SetNEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
SetNXPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx,"setnxmpub",
+ SetNXMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx,"delpub",
DelPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
DelIEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx,"deliempub",
+ DelIEMPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx,"delnepub",
DelNEPub_RedisCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
--- /dev/null
+/*
+ * Copyright (c) 2018-2020 Nokia.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+ */
+
+#ifndef COMMONSTUB_H_
+#define COMMONSTUB_H_
+
+
+#include <pthread.h>
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg);
+
+
+#endif
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
-#include "../../../../redismodule/tst/mock/include/redismodule.h"
int setStringGenericCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, const int flag);
int SetIE_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
+int SetIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetNXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
+int SetNXMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int SetXXPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int DelPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int DelMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int DelIEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
+int DelIEMPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
int DelNEPub_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
-int NGet_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
-int NDel_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
-
#endif
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <stdint.h>
#include <stdio.h>
-/* ---------------- Defines common between core and modules --------------- */
-
-
-
-
/* Error status return values. */
#define REDISMODULE_OK 0
#define REDISMODULE_ERR 1
#define REDISMODULE_READ (1<<0)
#define REDISMODULE_WRITE (1<<1)
-#define REDISMODULE_LIST_HEAD 0
-#define REDISMODULE_LIST_TAIL 1
-
/* Key types. */
#define REDISMODULE_KEYTYPE_EMPTY 0
#define REDISMODULE_KEYTYPE_STRING 1
/* Postponed array length. */
#define REDISMODULE_POSTPONED_ARRAY_LEN -1
-/* Expire */
-#define REDISMODULE_NO_EXPIRE -1
-
-/* Sorted set API flags. */
-#define REDISMODULE_ZADD_XX (1<<0)
-#define REDISMODULE_ZADD_NX (1<<1)
-#define REDISMODULE_ZADD_ADDED (1<<2)
-#define REDISMODULE_ZADD_UPDATED (1<<3)
-#define REDISMODULE_ZADD_NOP (1<<4)
-
-/* Hash API flags. */
-#define REDISMODULE_HASH_NONE 0
-#define REDISMODULE_HASH_NX (1<<0)
-#define REDISMODULE_HASH_XX (1<<1)
-#define REDISMODULE_HASH_CFIELDS (1<<2)
-#define REDISMODULE_HASH_EXISTS (1<<3)
-
-/* Context Flags: Info about the current context returned by RM_GetContextFlags */
-
-/* The command is running in the context of a Lua script */
-#define REDISMODULE_CTX_FLAGS_LUA 0x0001
-/* The command is running inside a Redis transaction */
-#define REDISMODULE_CTX_FLAGS_MULTI 0x0002
-/* The instance is a master */
-#define REDISMODULE_CTX_FLAGS_MASTER 0x0004
-/* The instance is a slave */
-#define REDISMODULE_CTX_FLAGS_SLAVE 0x0008
-/* The instance is read-only (usually meaning it's a slave as well) */
-#define REDISMODULE_CTX_FLAGS_READONLY 0x0010
-/* The instance is running in cluster mode */
-#define REDISMODULE_CTX_FLAGS_CLUSTER 0x0020
-/* The instance has AOF enabled */
-#define REDISMODULE_CTX_FLAGS_AOF 0x0040 //
-/* The instance has RDB enabled */
-#define REDISMODULE_CTX_FLAGS_RDB 0x0080 //
-/* The instance has Maxmemory set */
-#define REDISMODULE_CTX_FLAGS_MAXMEMORY 0x0100
-/* Maxmemory is set and has an eviction policy that may delete keys */
-#define REDISMODULE_CTX_FLAGS_EVICT 0x0200
-
-
-/* A special pointer that we can use between the core and the module to signal
- * field deletion, and that is impossible to be a valid pointer. */
-#define REDISMODULE_HASH_DELETE ((RedisModuleString*)(long)1)
-
/* Error messages. */
#define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value"
-#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0)
-#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0)
-
#define REDISMODULE_NOT_USED(V) ((void) V)
-/* ------------------------- End of common defines ------------------------ */
-
-
-
-
-#ifndef REDISMODULE_CORE
-
-
-
typedef long long mstime_t;
-/* Incomplete structures for compiler checks but opaque access. */
-typedef struct RedisModuleCtx RedisModuleCtx;
-typedef struct RedisModuleKey RedisModuleKey;
-typedef struct RedisModuleString RedisModuleString;
-typedef struct RedisModuleCallReply RedisModuleCallReply;
-typedef struct RedisModuleIO RedisModuleIO;
-typedef struct RedisModuleType RedisModuleType;
-typedef struct RedisModuleDigest RedisModuleDigest;
-typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
-
-//typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
+/* UT dummy definitions for opaque redis types */
+typedef struct { int dummy; } RedisModuleCtx;
+typedef struct { int dummy; } RedisModuleKey;
+typedef struct { int dummy; } RedisModuleString;
+typedef struct { int dummy; } RedisModuleCallReply;
+typedef struct { int dummy; } RedisModuleIO;
+typedef struct { int dummy; } RedisModuleType;
+typedef struct { int dummy; } RedisModuleDigest;
+typedef struct { int dummy; } RedisModuleBlockedClient;
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
typedef void (*RedisModuleTypeFreeFunc)(void *value);
-#define REDISMODULE_TYPE_METHOD_VERSION 1
-typedef struct RedisModuleTypeMethods {
- uint64_t version;
- RedisModuleTypeLoadFunc rdb_load;
- RedisModuleTypeSaveFunc rdb_save;
- RedisModuleTypeRewriteFunc aof_rewrite;
- RedisModuleTypeMemUsageFunc mem_usage;
- RedisModuleTypeDigestFunc digest;
- RedisModuleTypeFreeFunc free;
-} RedisModuleTypeMethods;
-
-#define REDISMODULE_GET_API(name) \
- RedisModule_GetApi("RedisModule_" #name, ((void **)&RedisModule_ ## name))
-
-#define REDISMODULE_API_FUNC(x) (*x)
-
-#if 1
-
-
-typedef struct redisObject {
- unsigned type:4;
- unsigned encoding:4;
- int refcount;
- void *ptr;
-} robj;
-/* This structure represents a module inside the system. */
-struct RedisModule {
- void *handle; /* Module dlopen() handle. */
- char *name; /* Module name. */
- int ver; /* Module version. We use just progressive integers. */
- int apiver; /* Module API version as requested during initialization.*/
- //list *types; /* Module data types. */
-};
-typedef struct RedisModule RedisModule;
-
-//static dict *modules; /* Hash table of modules. SDS -> RedisModule ptr.*/
-
-/* Entries in the context->amqueue array, representing objects to free
- * when the callback returns. */
-struct AutoMemEntry {
- void *ptr;
- int type;
-};
-
-/* AutMemEntry type field values. */
-#define REDISMODULE_AM_KEY 0
-#define REDISMODULE_AM_STRING 1
-#define REDISMODULE_AM_REPLY 2
-#define REDISMODULE_AM_FREED 3 /* Explicitly freed by user already. */
-
-/* The pool allocator block. Redis Modules can allocate memory via this special
- * allocator that will automatically release it all once the callback returns.
- * This means that it can only be used for ephemeral allocations. However
- * there are two advantages for modules to use this API:
- *
- * 1) The memory is automatically released when the callback returns.
- * 2) This allocator is faster for many small allocations since whole blocks
- * are allocated, and small pieces returned to the caller just advancing
- * the index of the allocation.
- *
- * Allocations are always rounded to the size of the void pointer in order
- * to always return aligned memory chunks. */
-
-#define REDISMODULE_POOL_ALLOC_MIN_SIZE (1024*8)
-#define REDISMODULE_POOL_ALLOC_ALIGN (sizeof(void*))
-
-typedef struct RedisModulePoolAllocBlock {
- uint32_t size;
- uint32_t used;
- struct RedisModulePoolAllocBlock *next;
- char memory[];
-} RedisModulePoolAllocBlock;
-
-/* This structure represents the context in which Redis modules operate.
- * Most APIs module can access, get a pointer to the context, so that the API
- * implementation can hold state across calls, or remember what to free after
- * the call and so forth.
- *
- * Note that not all the context structure is always filled with actual values
- * but only the fields needed in a given context. */
-
-struct RedisModuleBlockedClient;
-
-struct RedisModuleCtx {
- void *getapifuncptr; /* NOTE: Must be the first field. */
- struct RedisModule *module; /* Module reference. */
- //client *client; /* Client calling a command. */
- struct RedisModuleBlockedClient *blocked_client; /* Blocked client for
- thread safe context. */
- struct AutoMemEntry *amqueue; /* Auto memory queue of objects to free. */
- int amqueue_len; /* Number of slots in amqueue. */
- int amqueue_used; /* Number of used slots in amqueue. */
- int flags; /* REDISMODULE_CTX_... flags. */
- void **postponed_arrays; /* To set with RM_ReplySetArrayLength(). */
- int postponed_arrays_count; /* Number of entries in postponed_arrays. */
- void *blocked_privdata; /* Privdata set when unblocking a client. */
-
- /* Used if there is the REDISMODULE_CTX_KEYS_POS_REQUEST flag set. */
- int *keys_pos;
- int keys_count;
-
- struct RedisModulePoolAllocBlock *pa_head;
-};
-typedef struct RedisModuleCtx RedisModuleCtx;
-
-#define REDISMODULE_CTX_INIT {(void*)(unsigned long)&RM_GetApi, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL, NULL, 0, NULL}
-#define REDISMODULE_CTX_MULTI_EMITTED (1<<0)
-#define REDISMODULE_CTX_AUTO_MEMORY (1<<1)
-#define REDISMODULE_CTX_KEYS_POS_REQUEST (1<<2)
-#define REDISMODULE_CTX_BLOCKED_REPLY (1<<3)
-#define REDISMODULE_CTX_BLOCKED_TIMEOUT (1<<4)
-#define REDISMODULE_CTX_THREAD_SAFE (1<<5)
-
-/* This represents a Redis key opened with RM_OpenKey(). */
-struct RedisModuleKey {
- RedisModuleCtx *ctx;
- //redisDb *db;
- robj *key; /* Key name object. */
- robj *value; /* Value object, or NULL if the key was not found. */
- void *iter; /* Iterator. */
- int mode; /* Opening mode. */
-
- /* Zset iterator. */
- uint32_t ztype; /* REDISMODULE_ZSET_RANGE_* */
- //zrangespec zrs; /* Score range. */
- //zlexrangespec zlrs; /* Lex range. */
- uint32_t zstart; /* Start pos for positional ranges. */
- uint32_t zend; /* End pos for positional ranges. */
- void *zcurrent; /* Zset iterator current node. */
- int zer; /* Zset iterator end reached flag
- (true if end was reached). */
-};
-typedef struct RedisModuleKey RedisModuleKey;
-
-/* RedisModuleKey 'ztype' values. */
-#define REDISMODULE_ZSET_RANGE_NONE 0 /* This must always be 0. */
-#define REDISMODULE_ZSET_RANGE_LEX 1
-#define REDISMODULE_ZSET_RANGE_SCORE 2
-#define REDISMODULE_ZSET_RANGE_POS 3
-
-/* Function pointer type of a function representing a command inside
- * a Redis module. */
-
typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
-
-/* This struct holds the information about a command registered by a module.*/
-struct RedisModuleCommandProxy {
- struct RedisModule *module;
- RedisModuleCmdFunc func;
- struct redisCommand *rediscmd;
-};
-typedef struct RedisModuleCommandProxy RedisModuleCommandProxy;
-
-#define REDISMODULE_REPLYFLAG_NONE 0
-#define REDISMODULE_REPLYFLAG_TOPARSE (1<<0) /* Protocol must be parsed. */
-#define REDISMODULE_REPLYFLAG_NESTED (1<<1) /* Nested reply object. No proto
- or struct free. */
-
-/* Reply of RM_Call() function. The function is filled in a lazy
- * way depending on the function called on the reply structure. By default
- * only the type, proto and protolen are filled. */
-typedef struct RedisModuleCallReply {
- RedisModuleCtx *ctx;
- int type; /* REDISMODULE_REPLY_... */
- int flags; /* REDISMODULE_REPLYFLAG_... */
- size_t len; /* Len of strings or num of elements of arrays. */
- char *proto; /* Raw reply protocol. An SDS string at top-level object. */
- size_t protolen;/* Length of protocol. */
- union {
- const char *str; /* String pointer for string and error replies. This
- does not need to be freed, always points inside
- a reply->proto buffer of the reply object or, in
- case of array elements, of parent reply objects. */
- long long ll; /* Reply value for integer reply. */
- struct RedisModuleCallReply *array; /* Array of sub-reply elements. */
- } val;
-} RedisModuleCallReply;
-
-/* Structure representing a blocked client. We get a pointer to such
- * an object when blocking from modules. */
-typedef struct RedisModuleBlockedClient {
- //client *client; /* Pointer to the blocked client. or NULL if the client
- // was destroyed during the life of this object. */
- RedisModule *module; /* Module blocking the client. */
- RedisModuleCmdFunc reply_callback; /* Reply callback on normal completion.*/
- RedisModuleCmdFunc timeout_callback; /* Reply callback on timeout. */
- void (*free_privdata)(void *); /* privdata cleanup callback. */
- void *privdata; /* Module private data that may be used by the reply
- or timeout callback. It is set via the
- RedisModule_UnblockClient() API. */
- //client *reply_client; /* Fake client used to accumulate replies
- // in thread safe contexts. */
- int dbid; /* Database number selected by the original client. */
-} RedisModuleBlockedClient;
-
-#define RedisModuleString robj
-
-#endif
-
-
-
-
int RedisModule_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep);
int RedisModule_WrongArity(RedisModuleCtx *ctx);
int RedisModule_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll);
int RedisModule_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply);
const char *RedisModule_CallReplyStringPtr(RedisModuleCallReply *reply, size_t *len);
RedisModuleString *RedisModule_CreateStringFromCallReply(RedisModuleCallReply *reply);
-int RedisModule_StringToLongLong(const RedisModuleString *str, long long *ll);
int RedisModule_KeyType(RedisModuleKey *kp);
void RedisModule_CloseKey(RedisModuleKey *kp);
-/* This is included inline inside each Redis module. */
int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver);
size_t RedisModule_CallReplyLength(RedisModuleCallReply *reply);
RedisModuleCallReply *RedisModule_CallReplyArrayElement(RedisModuleCallReply *reply, size_t idx);
int RedisModule_ReplyWithArray(RedisModuleCtx *ctx, long len);
-
-
-/* Things only defined for the modules core, not exported to modules
- * including this file. */
-
-#else
-
-/* Things only defined for the modules core, not exported to modules
- * including this file. */
-#define RedisModuleString robj
-
-#endif /* REDISMODULE_CORE */
-#endif /* REDISMOUDLE_H */
+void RedisModule_FreeString(RedisModuleCtx *ctx, RedisModuleString *str);
+RedisModuleBlockedClient *RedisModule_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms);
+int RedisModule_UnblockClient(RedisModuleBlockedClient *bc, void *privdata);
+int RedisModule_AbortBlock(RedisModuleBlockedClient *bc);
+RedisModuleString *RedisModule_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len);
+void RedisModule_FreeThreadSafeContext(RedisModuleCtx *ctx);
+int RedisModule_StringToLongLong(const RedisModuleString *str, long long *ll);
+void RedisModule_ThreadSafeContextLock(RedisModuleCtx *ctx);
+void RedisModule_ThreadSafeContextUnlock(RedisModuleCtx *ctx);
+void RedisModule_ReplySetArrayLength(RedisModuleCtx *ctx, long len);
+RedisModuleCtx *RedisModule_GetThreadSafeContext(RedisModuleBlockedClient *bc);
+RedisModuleString *RedisModule_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll);
+void RedisModule_AutoMemory(RedisModuleCtx *ctx);
+void *RedisModule_Alloc(size_t bytes);
+void RedisModule_Free(void *ptr);
+
+#endif /* REDISMODULE_H */
--- /dev/null
+/*
+ * Copyright (c) 2018-2020 Nokia.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+ */
+
+
+#include <unistd.h>
+#include <string.h>
+
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "redismodule.h"
+#include "commonStub.h"
+}
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+#include <CppUTest/MemoryLeakDetectorMallocMacros.h>
+
+typedef struct RedisModuleBlockedClientArgs {
+ RedisModuleBlockedClient *bc;
+ RedisModuleString **argv;
+ int argc;
+} RedisModuleBlockedClientArgs;
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg)
+{
+ (void)thread;
+ (void)attr;
+ (void)start_routine;
+ if (mock().getData("pthread_create_free_block_client_args").getIntValue()) {
+ RedisModuleBlockedClientArgs* bca = (RedisModuleBlockedClientArgs*)arg;
+ free(bca->bc);
+ free(bca);
+ }
+
+ return mock()
+ .actualCall("pthread_create")
+ .returnIntValueOrDefault(0);
+}
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
-#include <CppUTest/TestHarness.h>
-#include <CppUTestExt/MockSupport.h>
#include <unistd.h>
#include <string.h>
-
-
-
extern "C" {
#include "redismodule.h"
#include <stdio.h>
#include <ctype.h>
}
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
int RedisModule_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep)
{
int RedisModule_WrongArity(RedisModuleCtx *ctx)
{
(void)ctx;
+ mock().setData("RedisModule_WrongArity", 1);
return REDISMODULE_ERR;
}
mock().setData("KEYS", 1);
else if (!strcmp(cmdname, "MGET"))
mock().setData("MGET", 1);
+ else if (!strcmp(cmdname, "SCAN"))
+ mock().setData("SCAN", 1);
if (mock().hasData("RedisModule_Call_Return_Null"))
return NULL;
{
(void)str;
- *len = 5;
+ if (len) *len = 5;
if (mock().hasData("RedisModule_String_same"))
{
return "11111";
return "22222";
}
+ if (mock().hasData("RedisModule_String_count"))
+ {
+ return "COUNT";
+ }
+
+ if (mock().hasData("RedisModule_String_count1"))
+ {
+ if (len) *len = 6;
+ return "COUNT1";
+ }
+
return "11111";
}
{
(void)reply;
- *len = 5;
-
if (mock().hasData("RedisModule_String_same"))
{
+ if (len)
+ *len = 5;
return "11111";
}
-
if (mock().hasData("RedisModule_String_nosame"))
{
- *len = 6;
+ if (len)
+ *len = 6;
return "333333";
}
return REDISMODULE_OK;
}
+void RedisModule_FreeString(RedisModuleCtx *ctx, RedisModuleString *str)
+{
+ (void)ctx;
+ (void)str;
+ mock().setData("RedisModule_FreeString", mock().getData("RedisModule_FreeString").getIntValue()+1);
+ return;
+}
+
+RedisModuleBlockedClient *RedisModule_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms)
+{
+ (void)ctx;
+ (void)reply_callback;
+ (void)timeout_callback;
+ (void)free_privdata;
+ (void)timeout_ms;
+ RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)malloc(sizeof(RedisModuleBlockedClient));
+ mock().setData("RedisModule_BlockClient", 1);
+ return bc;
+}
+
+int RedisModule_UnblockClient(RedisModuleBlockedClient *bc, void *privdata)
+{
+ (void)privdata;
+ free(bc);
+ mock().setData("RedisModule_UnblockClient", mock().getData("RedisModule_UnblockClient").getIntValue()+1);
+ return REDISMODULE_OK;
+}
+
+int RedisModule_AbortBlock(RedisModuleBlockedClient *bc)
+{
+ free(bc);
+ mock().setData("RedisModule_AbortBlock", 1);
+ return REDISMODULE_OK;
+}
+
+RedisModuleString *RedisModule_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len)
+{
+ (void)ctx;
+ (void)ptr;
+ (void)len;
+ RedisModuleString *rms = (RedisModuleString*)malloc(sizeof(RedisModuleString));
+ mock().setData("RedisModule_CreateString", mock().getData("RedisModule_CreateString").getIntValue()+1);
+ return rms;
+}
+
+void RedisModule_FreeThreadSafeContext(RedisModuleCtx *ctx)
+{
+ (void)ctx;
+ mock().setData("RedisModule_FreeThreadSafeContext", 1);
+ return;
+}
+
int RedisModule_StringToLongLong(const RedisModuleString *str, long long *ll)
{
- (void) str;
+ (void)str;
+
int call_no = mock().getData("RedisModule_StringToLongLongCallCount").getIntValue();
switch(call_no) {
case 0:
mock().setData("RedisModule_StringToLongLongCallCount", call_no + 1);
return REDISMODULE_OK;
}
+
+void RedisModule_ThreadSafeContextLock(RedisModuleCtx *ctx)
+{
+ (void)ctx;
+ mock().setData("RedisModule_ThreadSafeContextLock", 1);
+ return;
+}
+
+void RedisModule_ThreadSafeContextUnlock(RedisModuleCtx *ctx)
+{
+ (void)ctx;
+ mock().setData("RedisModule_ThreadSafeContextUnlock", 1);
+ return;
+}
+
+void RedisModule_ReplySetArrayLength(RedisModuleCtx *ctx, long len)
+{
+ (void)ctx;
+ mock().setData("RedisModule_ReplySetArrayLength", (int)len);
+ return;
+}
+
+RedisModuleCtx *RedisModule_GetThreadSafeContext(RedisModuleBlockedClient *bc)
+{
+ (void) bc;
+ mock().setData("RedisModule_GetThreadSafeContext", 1);
+ return NULL;
+}
+
+RedisModuleString *RedisModule_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll)
+{
+ (void)ctx;
+ (void)ll;
+ RedisModuleString *rms = (RedisModuleString*)malloc(sizeof(RedisModuleString));
+ mock().setData("RedisModule_CreateStringFromLongLong", mock().getData("RedisModule_CreateStringFromLongLong").getIntValue()+1);
+ return rms;
+}
+
+void RedisModule_AutoMemory(RedisModuleCtx *ctx)
+{
+ (void)ctx;
+ int old = mock().getData("RedisModule_AutoMemory").getIntValue();
+ mock().setData("RedisModule_AutoMemory", old + 1);
+ return;
+}
+
+void *RedisModule_Alloc(size_t bytes)
+{
+ mock()
+ .actualCall("RedisModule_Alloc");
+ return malloc(bytes);
+}
+
+void RedisModule_Free(void *ptr)
+{
+ mock()
+ .actualCall("RedisModule_Free");
+ free(ptr);
+}
/*
- * Copyright (c) 2018-2019 Nokia.
+ * Copyright (c) 2018-2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* platform project (RICP).
*/
-#include <string>
-#include <map>
-#include <list>
-#include <set>
-#include <vector>
-#include <syslog.h>
-
-
-//#include <stdio.h>
-//#include <stdlib.h>
-//#include <ctype.h>
-
extern "C" {
#include "exstringsStub.h"
#define OBJ_OP_IE (1<<4) /* OP if equal old value */
#define OBJ_OP_NE (1<<5) /* OP if not equal old value */
+typedef struct RedisModuleBlockedClientArgs {
+ RedisModuleBlockedClient *bc;
+ RedisModuleString **argv;
+ int argc;
+} RedisModuleBlockedClientArgs;
TEST_GROUP(exstring)
{
int ret = SetIE_RedisCommand(&ctx, redisStrVec, 4);
CHECK_EQUAL(ret, 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
}
mock().setData("RedisModule_String_same", 1);
int ret = SetNE_RedisCommand(&ctx,redisStrVec, 4);
CHECK_EQUAL(ret, 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
}
int ret = DelIE_RedisCommand(&ctx, redisStrVec, 3);
CHECK_EQUAL(ret, 0);
mock().checkExpectations();
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
}
int ret = DelNE_RedisCommand(&ctx,redisStrVec, 3);
CHECK_EQUAL(ret, 0);
mock().checkExpectations();
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
}
}
-TEST(exstring, setpub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[5]);
-
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)1;
- redisStrVec[3] = (RedisModuleString *)1;
- redisStrVec[4] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- int ret = SetPub_RedisCommand(&ctx, redisStrVec, 5);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
-TEST(exstring, setmpub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[11]);
-
- for (int i = 0 ; i < 11 ; ++i)
- redisStrVec[i] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
- mock().setData("RedisModule_StringToLongLongCallCount", 0);
- mock().setData("RedisModule_StringToLongLongCall_1", 2);
- mock().setData("RedisModule_StringToLongLongCall_2", 2);
-
- int ret = SetMPub_RedisCommand(&ctx, redisStrVec, 11);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
-TEST(exstring, setxxpub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[5]);
-
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)1;
- redisStrVec[3] = (RedisModuleString *)1;
- redisStrVec[4] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- mock().expectOneCall("RedisModule_CloseKey");
- int ret = SetXXPub_RedisCommand(&ctx, redisStrVec, 5);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
-TEST(exstring, setnxpub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[5]);
-
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)1;
- redisStrVec[3] = (RedisModuleString *)1;
- redisStrVec[4] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- mock().expectOneCall("RedisModule_CloseKey");
- int ret = SetNXPub_RedisCommand(&ctx, redisStrVec, 5);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
-TEST(exstring, setiepub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[6]);
-
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)1;
- redisStrVec[3] = (RedisModuleString *)1;
- redisStrVec[4] = (RedisModuleString *)1;
- redisStrVec[5] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- mock().expectOneCall("RedisModule_CloseKey");
- int ret = SetIEPub_RedisCommand(&ctx, redisStrVec, 6);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
-TEST(exstring, setnepub)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[6]);
-
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)1;
- redisStrVec[3] = (RedisModuleString *)1;
- redisStrVec[4] = (RedisModuleString *)1;
- redisStrVec[5] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_OpenKey_have", 1);
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- mock().expectOneCall("RedisModule_CloseKey");
- int ret = SetNEPub_RedisCommand(&ctx, redisStrVec, 6);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- delete []redisStrVec;
-}
-
TEST(exstring, setpub_command_parameter_number_incorrect)
{
RedisModuleCtx ctx;
ret = SetNXPub_RedisCommand(&ctx, 0, 3);
CHECK_EQUAL(ret, REDISMODULE_ERR);
+ ret = 0;
+ ret = SetNXMPub_RedisCommand(&ctx, 0, 3);
+ CHECK_EQUAL(ret, REDISMODULE_ERR);
+
ret = 0;
ret = SetNXPub_RedisCommand(&ctx, 0, 6);
CHECK_EQUAL(ret, REDISMODULE_ERR);
ret = SetIEPub_RedisCommand(&ctx, 0, 4);
CHECK_EQUAL(ret, REDISMODULE_ERR);
+ ret = 0;
+ ret = SetIEMPub_RedisCommand(&ctx, 0, 4);
+ CHECK_EQUAL(ret, REDISMODULE_ERR);
+
ret = 0;
ret = SetIEPub_RedisCommand(&ctx, 0, 9);
CHECK_EQUAL(ret, REDISMODULE_ERR);
CHECK_EQUAL(ret, REDISMODULE_ERR);
}
-TEST(exstring, setpub_command_no_key_replynull)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[5]);
-
- redisStrVec[0] = (RedisModuleString *)0;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)2;
- redisStrVec[3] = (RedisModuleString *)3;
- redisStrVec[4] = (RedisModuleString *)4;
-
- mock().setData("RedisModule_KeyType_empty", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- int ret = SetPub_RedisCommand(&ctx, redisStrVec, 5);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- CHECK_EQUAL(mock().getData("GET").getIntValue(), 0);
- CHECK_EQUAL(mock().getData("MSET").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
-
- delete []redisStrVec;
-
-}
-
TEST(exstring, setpub_command_no_key_replystr)
{
RedisModuleCtx ctx;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 1);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
-
- delete []redisStrVec;
-
-}
-
-TEST(exstring, setmpub_command_no_key_replynull)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[9]);
-
- redisStrVec[0] = (RedisModuleString *)0;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)2;
- redisStrVec[3] = (RedisModuleString *)3;
- redisStrVec[4] = (RedisModuleString *)4;
- redisStrVec[5] = (RedisModuleString *)5;
- redisStrVec[6] = (RedisModuleString *)6;
- redisStrVec[7] = (RedisModuleString *)7;
- redisStrVec[8] = (RedisModuleString *)8;
-
- mock().setData("RedisModule_KeyType_empty", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
- mock().setData("RedisModule_StringToLongLongCall_1", 1);
- mock().setData("RedisModule_StringToLongLongCall_2", 2);
-
- int ret = SetMPub_RedisCommand(&ctx, redisStrVec, 9);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- CHECK_EQUAL(0, mock().getData("GET").getIntValue());
- CHECK_EQUAL(1, mock().getData("MSET").getIntValue());
- CHECK_EQUAL(0, mock().getData("PUBLISH").getIntValue());
- CHECK_EQUAL(1, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(0, mock().getData("PUBLISH").getIntValue());
CHECK_EQUAL(1, mock().getData("RedisModule_ReplyWithError").getIntValue());
CHECK_EQUAL(0, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(0, mock().getData("PUBLISH").getIntValue());
CHECK_EQUAL(1, mock().getData("RedisModule_ReplyWithError").getIntValue());
CHECK_EQUAL(0, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(0, mock().getData("PUBLISH").getIntValue());
CHECK_EQUAL(1, mock().getData("RedisModule_ReplyWithError").getIntValue());
CHECK_EQUAL(0, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(1, mock().getData("MSET").getIntValue());
CHECK_EQUAL(1, mock().getData("PUBLISH").getIntValue());
CHECK_EQUAL(2, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(1, mock().getData("MSET").getIntValue());
CHECK_EQUAL(2, mock().getData("PUBLISH").getIntValue());
CHECK_EQUAL(3, mock().getData("RedisModule_FreeCallReply").getIntValue());
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 1);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 1);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("MSET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
-
- delete []redisStrVec;
-
-}
-
-TEST(exstring, setiepub_command_key_same_string_replynull)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[6]);
-
- redisStrVec[0] = (RedisModuleString *)0;
- redisStrVec[1] = (RedisModuleString *)1;
- redisStrVec[2] = (RedisModuleString *)2;
- redisStrVec[3] = (RedisModuleString *)3;
- redisStrVec[4] = (RedisModuleString *)4;
- redisStrVec[5] = (RedisModuleString *)5;
-
- mock().setData("RedisModule_KeyType_str", 1);
- mock().setData("RedisModule_String_same", 1);
- mock().setData("RedisModule_CallReplyType_null", 1);
-
- mock().expectOneCall("RedisModule_CloseKey");
- int ret = SetIEPub_RedisCommand(&ctx, redisStrVec, 6);
-
- CHECK_EQUAL(ret, REDISMODULE_OK);
- mock().checkExpectations();
- CHECK_EQUAL(mock().getData("GET").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("MSET").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithNull").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 3);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 3);
+ CHECK_EQUAL(mock().getData("RedisModule_AutoMemory").getIntValue(),1);
delete []redisStrVec;
delete []redisStrVec;
}
+TEST(exstring, deliempub)
+{
+ RedisModuleCtx ctx;
+ RedisModuleString ** redisStrVec = new (RedisModuleString*[5]);
+
+ redisStrVec[0] = (RedisModuleString *)1;
+ redisStrVec[1] = (RedisModuleString *)1;
+ redisStrVec[2] = (RedisModuleString *)1;
+ redisStrVec[3] = (RedisModuleString *)1;
+ redisStrVec[4] = (RedisModuleString *)1;
+
+ mock().setData("RedisModule_OpenKey_have", 1);
+ mock().setData("RedisModule_KeyType_str", 1);
+ mock().setData("RedisModule_String_same", 1);
+ mock().setData("RedisModule_CallReplyType_null", 1);
+
+ mock().expectOneCall("RedisModule_CloseKey");
+ int ret = DelIEMPub_RedisCommand(&ctx, redisStrVec, 5);
+ CHECK_EQUAL(ret, REDISMODULE_OK);
+ mock().checkExpectations();
+ delete []redisStrVec;
+}
+
TEST(exstring, delnepub)
{
RedisModuleCtx ctx;
ret = DelIEPub_RedisCommand(&ctx, 0, 4);
CHECK_EQUAL(ret, REDISMODULE_ERR);
+ ret = 0;
+ ret = DelIEMPub_RedisCommand(&ctx, 0, 4);
+ CHECK_EQUAL(ret, REDISMODULE_ERR);
+
ret = 0;
ret = DelNEPub_RedisCommand(&ctx, 0, 8);
CHECK_EQUAL(ret, REDISMODULE_ERR);
mock().setData("RedisModule_CallReplyType_err", 1);
int ret = DelPub_RedisCommand(&ctx, redisStrVec, 5);
- CHECK_EQUAL(ret, REDISMODULE_ERR);
+ CHECK_EQUAL(ret, REDISMODULE_OK);
CHECK_EQUAL(mock().getData("GET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("UNLINK").getIntValue(), 1);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
+ CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithError").getIntValue(), 0);
delete []redisStrVec;
mock().setData("RedisModule_StringToLongLongCall_2", 1);
int ret = DelMPub_RedisCommand(&ctx, redisStrVec, 6);
- CHECK_EQUAL(ret, REDISMODULE_ERR);
+ CHECK_EQUAL(ret, REDISMODULE_OK);
CHECK_EQUAL(mock().getData("GET").getIntValue(), 0);
CHECK_EQUAL(mock().getData("UNLINK").getIntValue(), 1);
CHECK_EQUAL(mock().getData("PUBLISH").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
+ CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 0);
CHECK_EQUAL(mock().getData("RedisModule_ReplyWithError").getIntValue(), 0);
delete []redisStrVec;
delete []redisStrVec;
}
-
-TEST(exstring, nget_command_parameter_number_incorrect)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- int ret = NGet_RedisCommand(&ctx, redisStrVec, 3);
- CHECK_EQUAL(ret, REDISMODULE_ERR);
-
- delete []redisStrVec;
-}
-
-TEST(exstring, nget_command_zero_item)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_CallReplyLength", 0);
- int ret = NGet_RedisCommand(&ctx, redisStrVec, 2);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- CHECK_EQUAL(mock().getData("KEYS").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
-
- delete []redisStrVec;
-}
-
-TEST(exstring, nget_command_none_zero_items)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_CallReplyLength", 3);
- int ret = NGet_RedisCommand(&ctx, redisStrVec, 2);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- CHECK_EQUAL(mock().getData("KEYS").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("MGET").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithArray").getIntValue(), 3*2);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithString").getIntValue(), 3*2);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
-
- delete []redisStrVec;
-}
-
-TEST(exstring, ndel_command_parameter_parameter_number_incorrect)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- int ret = NDel_RedisCommand(&ctx, redisStrVec, 3);
- CHECK_EQUAL(ret, REDISMODULE_ERR);
-
- delete []redisStrVec;
-}
-
-TEST(exstring, ndel_command_zero_item)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_CallReplyLength", 0);
- int ret = NDel_RedisCommand(&ctx, redisStrVec, 2);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- CHECK_EQUAL(mock().getData("KEYS").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithLongLong").getIntValue(), 0);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 1);
-
- delete []redisStrVec;
-}
-
-TEST(exstring, ndel_command_none_zero_items)
-{
- RedisModuleCtx ctx;
- RedisModuleString ** redisStrVec = new (RedisModuleString*[2]);
- redisStrVec[0] = (RedisModuleString *)1;
- redisStrVec[1] = (RedisModuleString *)1;
-
- mock().setData("RedisModule_CallReplyLength", 3);
- int ret = NDel_RedisCommand(&ctx, redisStrVec, 2);
- CHECK_EQUAL(ret, REDISMODULE_OK);
- CHECK_EQUAL(mock().getData("KEYS").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("UNLINK").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_ReplyWithCallReply").getIntValue(), 1);
- CHECK_EQUAL(mock().getData("RedisModule_FreeCallReply").getIntValue(), 2);
-
- delete []redisStrVec;
-}