summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2019-11-11 13:30:37 +0200
committermeir@redislabs.com <meir@redislabs.com>2019-11-11 16:05:55 +0200
commit0f8692b4646013b7d98d4b21f86da0686546d43a (patch)
tree6c34bdd5f3a281635c2258b90eca35882f021719 /tests
parent11c6ce812aa32cf6a6011697cbfe8881ff9450fa (diff)
downloadredis-0f8692b4646013b7d98d4b21f86da0686546d43a.tar.gz
Add RM_ScanKey to scan hash, set, zset, changes to RM_Scan API
- Adding RM_ScanKey - Adding tests for RM_ScanKey - Refactoring RM_Scan API Changes in RM_Scan - cleanup in docs and coding convention - Moving out of experimantal Api - Adding ctx to scan callback - Dont use cursor of -1 as an indication of done (can be a valid cursor) - Set errno when returning 0 for various reasons - Rename Cursor to ScanCursor - Test filters key that are not strings, and opens a key if NULL
Diffstat (limited to 'tests')
-rw-r--r--tests/modules/scan.c107
-rw-r--r--tests/unit/moduleapi/scan.tcl45
2 files changed, 114 insertions, 38 deletions
diff --git a/tests/modules/scan.c b/tests/modules/scan.c
index 21071720a..afede244b 100644
--- a/tests/modules/scan.c
+++ b/tests/modules/scan.c
@@ -1,62 +1,109 @@
-#define REDISMODULE_EXPERIMENTAL_API
#include "redismodule.h"
#include <string.h>
#include <assert.h>
#include <unistd.h>
-#define UNUSED(V) ((void) V)
+typedef struct {
+ size_t nkeys;
+} scan_strings_pd;
-typedef struct scan_pd{
- size_t nkeys;
- RedisModuleCtx *ctx;
-} scan_pd;
-
-void scan_callback(void *privdata, RedisModuleString* keyname, RedisModuleKey* key){
- scan_pd* pd = privdata;
- RedisModule_ReplyWithArray(pd->ctx, 2);
+void scan_strings_callback(RedisModuleCtx *ctx, RedisModuleString* keyname, RedisModuleKey* key, void *privdata) {
+ scan_strings_pd* pd = privdata;
+ int was_opened = 0;
+ if (!key) {
+ key = RedisModule_OpenKey(ctx, keyname, REDISMODULE_READ);
+ was_opened = 1;
+ }
- RedisModule_ReplyWithString(pd->ctx, keyname);
- if(key && RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_STRING){
+ if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_STRING) {
size_t len;
char * data = RedisModule_StringDMA(key, &len, REDISMODULE_READ);
- RedisModule_ReplyWithStringBuffer(pd->ctx, data, len);
- }else{
- RedisModule_ReplyWithNull(pd->ctx);
+ RedisModule_ReplyWithArray(ctx, 2);
+ RedisModule_ReplyWithString(ctx, keyname);
+ RedisModule_ReplyWithStringBuffer(ctx, data, len);
+ pd->nkeys++;
}
- pd->nkeys++;
+ if (was_opened)
+ RedisModule_CloseKey(key);
}
-int scan_keys_values(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+int scan_strings(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
{
- scan_pd pd = {
- .nkeys = 0,
- .ctx = ctx,
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+ scan_strings_pd pd = {
+ .nkeys = 0,
};
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN);
- RedisModuleCursor* cursor = RedisModule_CursorCreate();
- while(RedisModule_Scan(ctx, cursor, scan_callback, &pd));
- RedisModule_CursorDestroy(cursor);
+ RedisModuleScanCursor* cursor = RedisModule_ScanCursorCreate();
+ while(RedisModule_Scan(ctx, cursor, scan_strings_callback, &pd));
+ RedisModule_ScanCursorDestroy(cursor);
RedisModule_ReplySetArrayLength(ctx, pd.nkeys);
- return 0;
+ return REDISMODULE_OK;
+}
+
+typedef struct {
+ RedisModuleCtx *ctx;
+ size_t nreplies;
+} scan_key_pd;
+
+void scan_key_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata) {
+ REDISMODULE_NOT_USED(key);
+ scan_key_pd* pd = privdata;
+ RedisModule_ReplyWithArray(pd->ctx, 2);
+ RedisModule_ReplyWithString(pd->ctx, field);
+ if (value)
+ RedisModule_ReplyWithString(pd->ctx, value);
+ else
+ RedisModule_ReplyWithNull(pd->ctx);
+ pd->nreplies++;
+}
+
+int scan_key(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
+{
+ if (argc != 2) {
+ RedisModule_WrongArity(ctx);
+ return REDISMODULE_OK;
+ }
+ scan_key_pd pd = {
+ .ctx = ctx,
+ .nreplies = 0,
+ };
+
+ RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ);
+ if (!key) {
+ RedisModule_ReplyWithError(ctx, "not found");
+ return REDISMODULE_OK;
+ }
+
+ RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN);
+
+ RedisModuleScanCursor* cursor = RedisModule_ScanCursorCreate();
+ while(RedisModule_ScanKey(key, cursor, scan_key_callback, &pd));
+ RedisModule_ScanCursorDestroy(cursor);
+
+ RedisModule_ReplySetArrayLength(ctx, pd.nreplies);
+ RedisModule_CloseKey(key);
+ return REDISMODULE_OK;
}
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
- UNUSED(argv);
- UNUSED(argc);
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
if (RedisModule_Init(ctx, "scan", 1, REDISMODULE_APIVER_1)== REDISMODULE_ERR)
return REDISMODULE_ERR;
- if (RedisModule_CreateCommand(ctx, "scan.scankeysvalues", scan_keys_values, "", 0, 0, 0) == REDISMODULE_ERR)
+ if (RedisModule_CreateCommand(ctx, "scan.scan_strings", scan_strings, "", 0, 0, 0) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
+ if (RedisModule_CreateCommand(ctx, "scan.scan_key", scan_key, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
return REDISMODULE_OK;
}
-
-
-
diff --git a/tests/unit/moduleapi/scan.tcl b/tests/unit/moduleapi/scan.tcl
index 5a77e8195..de1672e0a 100644
--- a/tests/unit/moduleapi/scan.tcl
+++ b/tests/unit/moduleapi/scan.tcl
@@ -1,18 +1,47 @@
set testmodule [file normalize tests/modules/scan.so]
-proc count_log_message {pattern} {
- set result [exec grep -c $pattern < [srv 0 stdout]]
-}
-
start_server {tags {"modules"}} {
r module load $testmodule
- test {Module scan} {
- # the module create a scan command which also return values
+ test {Module scan keyspace} {
+ # the module create a scan command with filtering which also return values
r set x 1
r set y 2
r set z 3
- lsort [r scan.scankeysvalues]
+ r hset h f v
+ lsort [r scan.scan_strings]
} {{x 1} {y 2} {z 3}}
-} \ No newline at end of file
+ test {Module scan hash ziplist} {
+ r hmset hh f1 v1 f2 v2
+ lsort [r scan.scan_key hh]
+ } {{f1 v1} {f2 v2}}
+
+ test {Module scan hash dict} {
+ r config set hash-max-ziplist-entries 2
+ r hmset hh f3 v3
+ lsort [r scan.scan_key hh]
+ } {{f1 v1} {f2 v2} {f3 v3}}
+
+ test {Module scan zset ziplist} {
+ r zadd zz 1 f1 2 f2
+ lsort [r scan.scan_key zz]
+ } {{f1 1} {f2 2}}
+
+ test {Module scan zset dict} {
+ r config set zset-max-ziplist-entries 2
+ r zadd zz 3 f3
+ lsort [r scan.scan_key zz]
+ } {{f1 1} {f2 2} {f3 3}}
+
+ test {Module scan set intset} {
+ r sadd ss 1 2
+ lsort [r scan.scan_key ss]
+ } {{1 {}} {2 {}}}
+
+ test {Module scan set dict} {
+ r config set set-max-intset-entries 2
+ r sadd ss 3
+ lsort [r scan.scan_key ss]
+ } {{1 {}} {2 {}} {3 {}}}
+}