Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
70469b76
Unverified
Commit
70469b76
authored
Nov 21, 2019
by
Salvatore Sanfilippo
Committed by
GitHub
Nov 21, 2019
Browse files
Merge branch 'unstable' into expose_zmalloc_capabilities
parents
e45239e3
c697edf4
Changes
31
Show whitespace changes
Inline
Side-by-side
tests/modules/Makefile
View file @
70469b76
...
@@ -19,7 +19,9 @@ TEST_MODULES = \
...
@@ -19,7 +19,9 @@ TEST_MODULES = \
propagate.so
\
propagate.so
\
misc.so
\
misc.so
\
hooks.so
\
hooks.so
\
blockonkeys.so
blockonkeys.so
\
scan.so
\
datatype.so
.PHONY
:
all
.PHONY
:
all
...
...
tests/modules/datatype.c
0 → 100644
View file @
70469b76
/* This module current tests a small subset but should be extended in the future
* for general ModuleDataType coverage.
*/
#include "redismodule.h"
static
RedisModuleType
*
datatype
=
NULL
;
typedef
struct
{
long
long
intval
;
RedisModuleString
*
strval
;
}
DataType
;
static
void
*
datatype_load
(
RedisModuleIO
*
io
,
int
encver
)
{
(
void
)
encver
;
int
intval
=
RedisModule_LoadSigned
(
io
);
if
(
RedisModule_IsIOError
(
io
))
return
NULL
;
RedisModuleString
*
strval
=
RedisModule_LoadString
(
io
);
if
(
RedisModule_IsIOError
(
io
))
return
NULL
;
DataType
*
dt
=
(
DataType
*
)
RedisModule_Alloc
(
sizeof
(
DataType
));
dt
->
intval
=
intval
;
dt
->
strval
=
strval
;
return
dt
;
}
static
void
datatype_save
(
RedisModuleIO
*
io
,
void
*
value
)
{
DataType
*
dt
=
(
DataType
*
)
value
;
RedisModule_SaveSigned
(
io
,
dt
->
intval
);
RedisModule_SaveString
(
io
,
dt
->
strval
);
}
static
void
datatype_free
(
void
*
value
)
{
if
(
value
)
{
DataType
*
dt
=
(
DataType
*
)
value
;
if
(
dt
->
strval
)
RedisModule_FreeString
(
NULL
,
dt
->
strval
);
RedisModule_Free
(
dt
);
}
}
static
int
datatype_set
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
!=
4
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
long
long
intval
;
if
(
RedisModule_StringToLongLong
(
argv
[
2
],
&
intval
)
!=
REDISMODULE_OK
)
{
RedisModule_ReplyWithError
(
ctx
,
"Invalid integr value"
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
argv
[
1
],
REDISMODULE_WRITE
);
DataType
*
dt
=
RedisModule_Calloc
(
sizeof
(
DataType
),
1
);
dt
->
intval
=
intval
;
dt
->
strval
=
argv
[
3
];
RedisModule_RetainString
(
ctx
,
dt
->
strval
);
RedisModule_ModuleTypeSetValue
(
key
,
datatype
,
dt
);
RedisModule_CloseKey
(
key
);
RedisModule_ReplyWithSimpleString
(
ctx
,
"OK"
);
return
REDISMODULE_OK
;
}
static
int
datatype_restore
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
!=
3
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
DataType
*
dt
=
RedisModule_LoadDataTypeFromString
(
argv
[
2
],
datatype
);
if
(
!
dt
)
{
RedisModule_ReplyWithError
(
ctx
,
"Invalid data"
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
argv
[
1
],
REDISMODULE_WRITE
);
RedisModule_ModuleTypeSetValue
(
key
,
datatype
,
dt
);
RedisModule_CloseKey
(
key
);
RedisModule_ReplyWithSimpleString
(
ctx
,
"OK"
);
return
REDISMODULE_OK
;
}
static
int
datatype_get
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
!=
2
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
argv
[
1
],
REDISMODULE_READ
);
DataType
*
dt
=
RedisModule_ModuleTypeGetValue
(
key
);
RedisModule_CloseKey
(
key
);
RedisModule_ReplyWithArray
(
ctx
,
2
);
RedisModule_ReplyWithLongLong
(
ctx
,
dt
->
intval
);
RedisModule_ReplyWithString
(
ctx
,
dt
->
strval
);
return
REDISMODULE_OK
;
}
static
int
datatype_dump
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
!=
2
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
argv
[
1
],
REDISMODULE_READ
);
DataType
*
dt
=
RedisModule_ModuleTypeGetValue
(
key
);
RedisModule_CloseKey
(
key
);
RedisModuleString
*
reply
=
RedisModule_SaveDataTypeToString
(
ctx
,
dt
,
datatype
);
if
(
!
reply
)
{
RedisModule_ReplyWithError
(
ctx
,
"Failed to save"
);
return
REDISMODULE_OK
;
}
RedisModule_ReplyWithString
(
ctx
,
reply
);
RedisModule_FreeString
(
ctx
,
reply
);
return
REDISMODULE_OK
;
}
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
REDISMODULE_NOT_USED
(
argv
);
REDISMODULE_NOT_USED
(
argc
);
if
(
RedisModule_Init
(
ctx
,
"datatype"
,
1
,
REDISMODULE_APIVER_1
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
RedisModule_SetModuleOptions
(
ctx
,
REDISMODULE_OPTIONS_HANDLE_IO_ERRORS
);
RedisModuleTypeMethods
datatype_methods
=
{
.
version
=
REDISMODULE_TYPE_METHOD_VERSION
,
.
rdb_load
=
datatype_load
,
.
rdb_save
=
datatype_save
,
.
free
=
datatype_free
,
};
datatype
=
RedisModule_CreateDataType
(
ctx
,
"test___dt"
,
1
,
&
datatype_methods
);
if
(
datatype
==
NULL
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"datatype.set"
,
datatype_set
,
"deny-oom"
,
1
,
1
,
1
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"datatype.get"
,
datatype_get
,
""
,
1
,
1
,
1
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"datatype.restore"
,
datatype_restore
,
"deny-oom"
,
1
,
1
,
1
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"datatype.dump"
,
datatype_dump
,
""
,
1
,
1
,
1
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_OK
;
}
tests/modules/misc.c
View file @
70469b76
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
#include <unistd.h>
#include <unistd.h>
#include <errno.h>
#include <errno.h>
#define UNUSED(x) (void)(x)
int
test_call_generic
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
int
test_call_generic
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
{
if
(
argc
<
2
)
{
if
(
argc
<
2
)
{
...
@@ -40,6 +42,45 @@ int test_call_info(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -40,6 +42,45 @@ int test_call_info(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
int
test_ld_conv
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
UNUSED
(
argv
);
UNUSED
(
argc
);
long
double
ld
=
0
.
00000000000000001L
;
const
char
*
ldstr
=
"0.00000000000000001"
;
RedisModuleString
*
s1
=
RedisModule_CreateStringFromLongDouble
(
ctx
,
ld
,
1
);
RedisModuleString
*
s2
=
RedisModule_CreateString
(
ctx
,
ldstr
,
strlen
(
ldstr
));
if
(
RedisModule_StringCompare
(
s1
,
s2
)
!=
0
)
{
char
err
[
4096
];
snprintf
(
err
,
4096
,
"Failed to convert long double to string ('%s' != '%s')"
,
RedisModule_StringPtrLen
(
s1
,
NULL
),
RedisModule_StringPtrLen
(
s2
,
NULL
));
RedisModule_ReplyWithError
(
ctx
,
err
);
goto
final
;
}
long
double
ld2
=
0
;
if
(
RedisModule_StringToLongDouble
(
s2
,
&
ld2
)
==
REDISMODULE_ERR
)
{
RedisModule_ReplyWithError
(
ctx
,
"Failed to convert string to long double"
);
goto
final
;
}
if
(
ld2
!=
ld
)
{
char
err
[
4096
];
snprintf
(
err
,
4096
,
"Failed to convert string to long double (%.40Lf != %.40Lf)"
,
ld2
,
ld
);
RedisModule_ReplyWithError
(
ctx
,
err
);
goto
final
;
}
RedisModule_ReplyWithLongDouble
(
ctx
,
ld2
);
final:
RedisModule_FreeString
(
ctx
,
s1
);
RedisModule_FreeString
(
ctx
,
s2
);
return
REDISMODULE_OK
;
}
int
test_flushall
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
int
test_flushall
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
{
REDISMODULE_NOT_USED
(
argv
);
REDISMODULE_NOT_USED
(
argv
);
...
@@ -68,16 +109,24 @@ int test_randomkey(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -68,16 +109,24 @@ int test_randomkey(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
RedisModuleKey
*
open_key_or_reply
(
RedisModuleCtx
*
ctx
,
RedisModuleString
*
keyname
,
int
mode
)
{
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
keyname
,
mode
);
if
(
!
key
)
{
RedisModule_ReplyWithError
(
ctx
,
"key not found"
);
return
NULL
;
}
return
key
;
}
int
test_getlru
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
int
test_getlru
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
{
if
(
argc
<
2
)
{
if
(
argc
<
2
)
{
RedisModule_WrongArity
(
ctx
);
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
RedisModuleString
*
keyname
=
argv
[
1
];
RedisModuleKey
*
key
=
open_key_or_reply
(
ctx
,
argv
[
1
],
REDISMODULE_READ
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
keyname
,
REDISMODULE_READ
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
mstime_t
lru
;
long
long
lru
,
lfu
;
RedisModule_GetLRU
(
key
,
&
lru
);
RedisModule_GetLRUOrLFU
(
key
,
&
lfu
,
&
lru
);
RedisModule_ReplyWithLongLong
(
ctx
,
lru
);
RedisModule_ReplyWithLongLong
(
ctx
,
lru
);
RedisModule_CloseKey
(
key
);
RedisModule_CloseKey
(
key
);
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
...
@@ -89,12 +138,46 @@ int test_setlru(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -89,12 +138,46 @@ int test_setlru(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
RedisModule_WrongArity
(
ctx
);
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
RedisModuleString
*
keyname
=
argv
[
1
];
RedisModuleKey
*
key
=
open_key_or_reply
(
ctx
,
argv
[
1
],
REDISMODULE_READ
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
RedisModuleKey
*
key
=
RedisModule_OpenKey
(
ctx
,
keyname
,
REDISMODULE_WRITE
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
mstime_t
lru
;
long
long
lru
;
if
(
RedisModule_StringToLongLong
(
argv
[
2
],
&
lru
)
!=
REDISMODULE_OK
)
{
RedisModule_StringToLongLong
(
argv
[
2
],
&
lru
);
RedisModule_ReplyWithError
(
ctx
,
"invalid idle time"
);
RedisModule_SetLRUOrLFU
(
key
,
-
1
,
lru
);
return
REDISMODULE_OK
;
RedisModule_ReplyWithCString
(
ctx
,
"Ok"
);
}
int
was_set
=
RedisModule_SetLRU
(
key
,
lru
)
==
REDISMODULE_OK
;
RedisModule_ReplyWithLongLong
(
ctx
,
was_set
);
RedisModule_CloseKey
(
key
);
return
REDISMODULE_OK
;
}
int
test_getlfu
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
<
2
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
open_key_or_reply
(
ctx
,
argv
[
1
],
REDISMODULE_READ
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
mstime_t
lfu
;
RedisModule_GetLFU
(
key
,
&
lfu
);
RedisModule_ReplyWithLongLong
(
ctx
,
lfu
);
RedisModule_CloseKey
(
key
);
return
REDISMODULE_OK
;
}
int
test_setlfu
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
<
3
)
{
RedisModule_WrongArity
(
ctx
);
return
REDISMODULE_OK
;
}
RedisModuleKey
*
key
=
open_key_or_reply
(
ctx
,
argv
[
1
],
REDISMODULE_READ
|
REDISMODULE_OPEN_KEY_NOTOUCH
);
mstime_t
lfu
;
if
(
RedisModule_StringToLongLong
(
argv
[
2
],
&
lfu
)
!=
REDISMODULE_OK
)
{
RedisModule_ReplyWithError
(
ctx
,
"invalid freq"
);
return
REDISMODULE_OK
;
}
int
was_set
=
RedisModule_SetLFU
(
key
,
lfu
)
==
REDISMODULE_OK
;
RedisModule_ReplyWithLongLong
(
ctx
,
was_set
);
RedisModule_CloseKey
(
key
);
RedisModule_CloseKey
(
key
);
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
...
@@ -109,6 +192,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -109,6 +192,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.call_info"
,
test_call_info
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.call_info"
,
test_call_info
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.ld_conversion"
,
test_ld_conv
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.flushall"
,
test_flushall
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.flushall"
,
test_flushall
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.dbsize"
,
test_dbsize
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.dbsize"
,
test_dbsize
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
...
@@ -119,6 +204,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -119,6 +204,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getlru"
,
test_getlru
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getlru"
,
test_getlru
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.setlfu"
,
test_setlfu
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getlfu"
,
test_getlfu
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
tests/modules/scan.c
0 → 100644
View file @
70469b76
#include "redismodule.h"
#include <string.h>
#include <assert.h>
#include <unistd.h>
typedef
struct
{
size_t
nkeys
;
}
scan_strings_pd
;
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
;
}
if
(
RedisModule_KeyType
(
key
)
==
REDISMODULE_KEYTYPE_STRING
)
{
size_t
len
;
char
*
data
=
RedisModule_StringDMA
(
key
,
&
len
,
REDISMODULE_READ
);
RedisModule_ReplyWithArray
(
ctx
,
2
);
RedisModule_ReplyWithString
(
ctx
,
keyname
);
RedisModule_ReplyWithStringBuffer
(
ctx
,
data
,
len
);
pd
->
nkeys
++
;
}
if
(
was_opened
)
RedisModule_CloseKey
(
key
);
}
int
scan_strings
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
REDISMODULE_NOT_USED
(
argv
);
REDISMODULE_NOT_USED
(
argc
);
scan_strings_pd
pd
=
{
.
nkeys
=
0
,
};
RedisModule_ReplyWithArray
(
ctx
,
REDISMODULE_POSTPONED_ARRAY_LEN
);
RedisModuleScanCursor
*
cursor
=
RedisModule_ScanCursorCreate
();
while
(
RedisModule_Scan
(
ctx
,
cursor
,
scan_strings_callback
,
&
pd
));
RedisModule_ScanCursorDestroy
(
cursor
);
RedisModule_ReplySetArrayLength
(
ctx
,
pd
.
nkeys
);
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
)
{
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.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
;
}
tests/modules/testrdb.c
View file @
70469b76
...
@@ -18,8 +18,11 @@ void *testrdb_type_load(RedisModuleIO *rdb, int encver) {
...
@@ -18,8 +18,11 @@ void *testrdb_type_load(RedisModuleIO *rdb, int encver) {
RedisModuleString
*
str
=
RedisModule_LoadString
(
rdb
);
RedisModuleString
*
str
=
RedisModule_LoadString
(
rdb
);
float
f
=
RedisModule_LoadFloat
(
rdb
);
float
f
=
RedisModule_LoadFloat
(
rdb
);
long
double
ld
=
RedisModule_LoadLongDouble
(
rdb
);
long
double
ld
=
RedisModule_LoadLongDouble
(
rdb
);
if
(
RedisModule_IsIOError
(
rdb
))
if
(
RedisModule_IsIOError
(
rdb
))
{
RedisModuleCtx
*
ctx
=
RedisModule_GetContextFromIO
(
rdb
);
RedisModule_FreeString
(
ctx
,
str
);
return
NULL
;
return
NULL
;
}
/* Using the values only after checking for io errors. */
/* Using the values only after checking for io errors. */
assert
(
count
==
1
);
assert
(
count
==
1
);
assert
(
encver
==
1
);
assert
(
encver
==
1
);
...
...
tests/support/test.tcl
View file @
70469b76
...
@@ -11,28 +11,55 @@ proc fail {msg} {
...
@@ -11,28 +11,55 @@ proc fail {msg} {
proc assert
{
condition
}
{
proc assert
{
condition
}
{
if
{
!
[
uplevel 1
[
list expr $condition
]]}
{
if
{
!
[
uplevel 1
[
list expr $condition
]]}
{
error
"assertion:Expected condition '
$condition
' to be true (
[
uplevel 1
[
list subst -nocommands $condition
]]
)"
set context
"(context:
[
info frame -1
]
)"
error
"assertion:Expected
[
uplevel 1
[
list subst -nocommands $condition
]]
$context
"
}
}
}
}
proc assert_no_match
{
pattern value
}
{
proc assert_no_match
{
pattern value
}
{
if
{[
string match $pattern $value
]}
{
if
{[
string match $pattern $value
]}
{
error
"assertion:Expected '
$value
' to not match '
$pattern
'"
set context
"(context:
[
info frame -1
]
)"
error
"assertion:Expected '
$value
' to not match '
$pattern
'
$context
"
}
}
}
}
proc assert_match
{
pattern value
}
{
proc assert_match
{
pattern value
}
{
if
{
!
[
string match $pattern $value
]}
{
if
{
!
[
string match $pattern $value
]}
{
error
"assertion:Expected '
$value
' to match '
$pattern
'"
set context
"(context:
[
info frame -1
]
)"
error
"assertion:Expected '
$value
' to match '
$pattern
'
$context
"
}
}
}
}
proc assert_equal
{
expected
value
{
detail
""
}}
{
proc assert_equal
{
value
expected
{
detail
""
}}
{
if
{
$expected
ne $value
}
{
if
{
$expected
ne $value
}
{
if
{
$detail
ne
""
}
{
if
{
$detail
ne
""
}
{
set detail
" (detail:
$detail
)"
set detail
"(detail:
$detail
)"
}
else
{
set detail
"(context:
[
info frame -1
]
)"
}
error
"assertion:Expected '
$value
' to be equal to '
$expected
'
$detail
"
}
}
proc assert_lessthan
{
value expected
{
detail
""
}}
{
if
{
!
(
$value
< $expected
)}
{
if
{
$detail
ne
""
}
{
set detail
"(detail:
$detail
)"
}
else
{
set detail
"(context:
[
info frame -1
]
)"
}
error
"assertion:Expected '
$value
' to be lessthan to '
$expected
'
$detail
"
}
}
proc assert_range
{
value min max
{
detail
""
}}
{
if
{
!
(
$value
<= $max && $value >= $min
)}
{
if
{
$detail
ne
""
}
{
set detail
"(detail:
$detail
)"
}
else
{
set detail
"(context:
[
info frame -1
]
)"
}
}
error
"assertion:Expected '
$value
' to be
equal to '
$expected
'
$detail
"
error
"assertion:Expected '
$value
' to be
between to '
$min
' and '
$max
'
$detail
"
}
}
}
}
...
...
tests/unit/moduleapi/datatype.tcl
0 → 100644
View file @
70469b76
set testmodule
[
file normalize tests/modules/datatype.so
]
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
test
{
DataType: Test module is sane, GET/SET work.
}
{
r datatype.set dtkey 100 stringval
assert
{[
r datatype.get dtkey
]
eq
{
100 stringval
}}
}
test
{
DataType: RM_SaveDataTypeToString
()
, RM_LoadDataTypeFromString
()
work
}
{
r datatype.set dtkey -1111 MyString
set encoded
[
r datatype.dump dtkey
]
r datatype.restore dtkeycopy $encoded
assert
{[
r datatype.get dtkeycopy
]
eq
{
-1111 MyString
}}
}
test
{
DataType: Handle truncated RM_LoadDataTypeFromString
()}
{
r datatype.set dtkey -1111 MyString
set encoded
[
r datatype.dump dtkey
]
set truncated
[
string range $encoded 0 end-1
]
catch
{
r datatype.restore dtkeycopy $truncated
}
e
set e
}
{
*Invalid*
}
}
tests/unit/moduleapi/misc.tcl
View file @
70469b76
...
@@ -16,6 +16,11 @@ start_server {tags {"modules"}} {
...
@@ -16,6 +16,11 @@ start_server {tags {"modules"}} {
assert
{
[
string match
"*cmdstat_module*"
$info
]
}
assert
{
[
string match
"*cmdstat_module*"
$info
]
}
}
}
test
{
test long double conversions
}
{
set ld
[
r test.ld_conversion
]
assert
{[
string match $ld
"0.00000000000000001"
]}
}
test
{
test module db commands
}
{
test
{
test module db commands
}
{
r set x foo
r set x foo
set key
[
r test.randomkey
]
set key
[
r test.randomkey
]
...
@@ -26,13 +31,40 @@ start_server {tags {"modules"}} {
...
@@ -26,13 +31,40 @@ start_server {tags {"modules"}} {
}
}
test
{
test modle lru api
}
{
test
{
test modle lru api
}
{
r config set maxmemory-policy allkeys-lru
r set x foo
r set x foo
set lru
[
r test.getlru x
]
set lru
[
r test.getlru x
]
assert
{
$lru <= 1
}
assert
{
$lru <= 1000
}
r test.setlru x 100
set was_set
[
r test.setlru x 100000
]
assert
{
$was_set == 1
}
set idle
[
r object idletime x
]
set idle
[
r object idletime x
]
assert
{
$idle >= 100
}
assert
{
$idle >= 100
}
set lru
[
r test.getlru x
]
set lru
[
r test.getlru x
]
assert
{
$lru >= 100
}
assert
{
$lru >= 100000
}
r config set maxmemory-policy allkeys-lfu
set lru
[
r test.getlru x
]
assert
{
$lru == -1
}
set was_set
[
r test.setlru x 100000
]
assert
{
$was_set == 0
}
}
}
r config set maxmemory-policy allkeys-lru
test
{
test modle lfu api
}
{
r config set maxmemory-policy allkeys-lfu
r set x foo
set lfu
[
r test.getlfu x
]
assert
{
$lfu >= 1
}
set was_set
[
r test.setlfu x 100
]
assert
{
$was_set == 1
}
set freq
[
r object freq x
]
assert
{
$freq <= 100
}
set lfu
[
r test.getlfu x
]
assert
{
$lfu <= 100
}
r config set maxmemory-policy allkeys-lru
set lfu
[
r test.getlfu x
]
assert
{
$lfu == -1
}
set was_set
[
r test.setlfu x 100
]
assert
{
$was_set == 0
}
}
}
}
tests/unit/moduleapi/scan.tcl
0 → 100644
View file @
70469b76
set testmodule
[
file normalize tests/modules/scan.so
]
start_server
{
tags
{
"modules"
}}
{
r module load $testmodule
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
r hset h f v
lsort
[
r scan.scan_strings
]
}
{{
x 1
}
{
y 2
}
{
z 3
}}
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
{}}}
}
tests/unit/scripting.tcl
View file @
70469b76
...
@@ -536,7 +536,7 @@ foreach cmdrepl {0 1} {
...
@@ -536,7 +536,7 @@ foreach cmdrepl {0 1} {
start_server
{
tags
{
"scripting repl"
}}
{
start_server
{
tags
{
"scripting repl"
}}
{
start_server
{}
{
start_server
{}
{
if
{
$cmdrepl
== 1
}
{
if
{
$cmdrepl
== 1
}
{
set rt
"(comm
m
ands replication)"
set rt
"(commands replication)"
}
else
{
}
else
{
set rt
"(scripts replication)"
set rt
"(scripts replication)"
r debug lua-always-replicate-commands 1
r debug lua-always-replicate-commands 1
...
...
tests/unit/type/stream.tcl
View file @
70469b76
...
@@ -123,6 +123,12 @@ start_server {
...
@@ -123,6 +123,12 @@ start_server {
assert
{[
r xlen mystream
]
== $j
}
assert
{[
r xlen mystream
]
== $j
}
}
}
test
{
XADD with ID 0-0
}
{
r DEL otherstream
catch
{
r XADD otherstream 0-0 k v
}
err
assert
{[
r EXISTS otherstream
]
== 0
}
}
test
{
XRANGE COUNT works as expected
}
{
test
{
XRANGE COUNT works as expected
}
{
assert
{[
llength
[
r xrange mystream - + COUNT 10
]]
== 10
}
assert
{[
llength
[
r xrange mystream - + COUNT 10
]]
== 10
}
}
}
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment