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
05833959
Unverified
Commit
05833959
authored
Jun 12, 2022
by
Oran Agra
Committed by
GitHub
Jun 12, 2022
Browse files
Merge pull request #10851 from oranagra/release702
Release 7.0.2
parents
2667c412
1973558b
Changes
12
Hide whitespace changes
Inline
Side-by-side
00-RELEASENOTES
View file @
05833959
...
...
@@ -11,6 +11,23 @@ CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
SECURITY: There are security fixes in the release.
--------------------------------------------------------------------------------
================================================================================
Redis 7.0.2 Released Sunday Jun 12 12:00:00 IST 2022
================================================================================
Upgrade urgency: MODERATE, specifically if you're using a previous release of
Redis 7.0, contains fixes for bugs in previous 7.0 releases.
Bug Fixes
=========
* Fixed SET and BITFIELD commands being wrongly marked movablekeys (#10837)
Regression in 7.0 possibly resulting in excessive roundtrip from cluster clients.
* Fix crash when /proc/sys/vm/overcommit_memory is inaccessible (#10848)
Regression in 7.0.1 resulting in crash on startup on some configurations.
================================================================================
Redis 7.0.1 Released Wed Jun 8 12:00:00 IST 2022
================================================================================
...
...
@@ -79,8 +96,8 @@ Bug Fixes
* Replica fail and retry the PSYNC if the master is unresponsive (#10726)
* Fix ZRANGESTORE crash when zset_max_listpack_entries is 0 (#10767)
Fixes for issues in previous release
candidate
s of Redis 7.0
--------------------------------------------------
----------
Fixes for issues in previous releases of Redis 7.0
--------------------------------------------------
* CONFIG REWRITE could cause a config change to be dropped for aliased configs (#10811)
* CONFIG REWRITE would omit rename-command and include lines (#10761)
...
...
src/module.c
View file @
05833959
...
...
@@ -1154,15 +1154,10 @@ RedisModuleCommand *moduleCreateCommandProxy(struct RedisModule *module, sds dec
cp
->
rediscmd
->
key_specs
[
0
].
fk
.
range
.
lastkey
=
lastkey
<
0
?
lastkey
:
(
lastkey
-
firstkey
);
cp
->
rediscmd
->
key_specs
[
0
].
fk
.
range
.
keystep
=
keystep
;
cp
->
rediscmd
->
key_specs
[
0
].
fk
.
range
.
limit
=
0
;
/* Copy the default range to legacy_range_key_spec */
cp
->
rediscmd
->
legacy_range_key_spec
=
cp
->
rediscmd
->
key_specs
[
0
];
}
else
{
cp
->
rediscmd
->
key_specs_num
=
0
;
cp
->
rediscmd
->
legacy_range_key_spec
.
begin_search_type
=
KSPEC_BS_INVALID
;
cp
->
rediscmd
->
legacy_range_key_spec
.
find_keys_type
=
KSPEC_FK_INVALID
;
}
populateCommand
MovableKeys
(
cp
->
rediscmd
);
populateCommand
LegacyRangeSpec
(
cp
->
rediscmd
);
cp
->
rediscmd
->
microseconds
=
0
;
cp
->
rediscmd
->
calls
=
0
;
cp
->
rediscmd
->
rejected_calls
=
0
;
...
...
@@ -1697,10 +1692,9 @@ int RM_SetCommandInfo(RedisModuleCommand *command, const RedisModuleCommandInfo
}
}
/* Update the legacy (first,last,step) spec used by the COMMAND command,
/* Update the legacy (first,last,step) spec
and "movablekeys" flag
used by the COMMAND command,
* by trying to "glue" consecutive range key specs. */
populateCommandLegacyRangeSpec
(
cmd
);
populateCommandMovableKeys
(
cmd
);
}
if
(
info
->
args
)
{
...
...
src/server.c
View file @
05833959
...
...
@@ -372,7 +372,7 @@ int dictExpandAllowed(size_t moreMem, double usedRatio) {
* belonging to the same cluster slot. See the Slot to Key API in cluster.c. */
size_t
dictEntryMetadataSize
(
dict
*
d
)
{
UNUSED
(
d
);
/* NOTICE: this also affect overhead_ht_slot_to_keys in getMemoryOverheadData.
/* NOTICE: this also affect
s
overhead_ht_slot_to_keys in getMemoryOverheadData.
* If we ever add non-cluster related data here, that code must be modified too. */
return
server
.
cluster_enabled
?
sizeof
(
clusterDictEntryMetadata
)
:
0
;
}
...
...
@@ -774,7 +774,7 @@ int clientsCronResizeOutputBuffer(client *c, mstime_t now_ms) {
*
* This is how it works. We have an array of CLIENTS_PEAK_MEM_USAGE_SLOTS slots
* where we track, for each, the biggest client output and input buffers we
* saw in that slot. Every slot correspond to one of the latest seconds, since
* saw in that slot. Every slot correspond
s
to one of the latest seconds, since
* the array is indexed by doing UNIXTIME % CLIENTS_PEAK_MEM_USAGE_SLOTS.
*
* When we want to know what was recently the peak memory usage, we just scan
...
...
@@ -2643,9 +2643,12 @@ void InitServerLast() {
* By far the most common case is just one range spec (e.g. SET)
* but some commands' ranges were split into two or more ranges
* in order to have different flags for different keys (e.g. SMOVE,
* first key is "
read write
", second key is "
write
").
* first key is "
RW ACCESS DELETE
", second key is "
RW INSERT
").
*
* This functions uses very basic heuristics and is "best effort":
* Additionally set the CMD_MOVABLE_KEYS flag for commands that may have key
* names in their arguments, but the legacy range spec doesn't cover all of them.
*
* This function uses very basic heuristics and is "best effort":
* 1. Only commands which have only "range" specs are considered.
* 2. Only range specs with keystep of 1 are considered.
* 3. The order of the range specs must be ascending (i.e.
...
...
@@ -2667,15 +2670,26 @@ void InitServerLast() {
void
populateCommandLegacyRangeSpec
(
struct
redisCommand
*
c
)
{
memset
(
&
c
->
legacy_range_key_spec
,
0
,
sizeof
(
c
->
legacy_range_key_spec
));
if
(
c
->
key_specs_num
==
0
)
/* Set the movablekeys flag if we have a GETKEYS flag for modules.
* Note that for native redis commands, we always have keyspecs,
* with enough information to rely on for movablekeys. */
if
(
c
->
flags
&
CMD_MODULE_GETKEYS
)
c
->
flags
|=
CMD_MOVABLE_KEYS
;
/* no key-specs, no keys, exit. */
if
(
c
->
key_specs_num
==
0
)
{
return
;
}
if
(
c
->
key_specs_num
==
1
&&
c
->
key_specs
[
0
].
begin_search_type
==
KSPEC_BS_INDEX
&&
c
->
key_specs
[
0
].
find_keys_type
==
KSPEC_FK_RANGE
)
{
/* Quick win */
/* Quick win
, exactly one range spec.
*/
c
->
legacy_range_key_spec
=
c
->
key_specs
[
0
];
/* If it has the incomplete flag, set the movablekeys flag on the command. */
if
(
c
->
key_specs
[
0
].
flags
&
CMD_KEY_INCOMPLETE
)
c
->
flags
|=
CMD_MOVABLE_KEYS
;
return
;
}
...
...
@@ -2684,11 +2698,23 @@ void populateCommandLegacyRangeSpec(struct redisCommand *c) {
for
(
int
i
=
0
;
i
<
c
->
key_specs_num
;
i
++
)
{
if
(
c
->
key_specs
[
i
].
begin_search_type
!=
KSPEC_BS_INDEX
||
c
->
key_specs
[
i
].
find_keys_type
!=
KSPEC_FK_RANGE
)
{
/* Found an incompatible (non range) spec, skip it, and set the movablekeys flag. */
c
->
flags
|=
CMD_MOVABLE_KEYS
;
continue
;
if
(
c
->
key_specs
[
i
].
fk
.
range
.
keystep
!=
1
)
return
;
if
(
prev_lastkey
&&
prev_lastkey
!=
c
->
key_specs
[
i
].
bs
.
index
.
pos
-
1
)
return
;
}
if
(
c
->
key_specs
[
i
].
fk
.
range
.
keystep
!=
1
||
(
prev_lastkey
&&
prev_lastkey
!=
c
->
key_specs
[
i
].
bs
.
index
.
pos
-
1
))
{
/* Found a range spec that's not plain (step of 1) or not consecutive to the previous one.
* Skip it, and we set the movablekeys flag. */
c
->
flags
|=
CMD_MOVABLE_KEYS
;
continue
;
}
if
(
c
->
key_specs
[
i
].
flags
&
CMD_KEY_INCOMPLETE
)
{
/* The spec we're using is incomplete, we can use it, but we also have to set the movablekeys flag. */
c
->
flags
|=
CMD_MOVABLE_KEYS
;
}
firstkey
=
min
(
firstkey
,
c
->
key_specs
[
i
].
bs
.
index
.
pos
);
/* Get the absolute index for lastkey (in the "range" spec, lastkey is relative to firstkey) */
int
lastkey_abs_index
=
c
->
key_specs
[
i
].
fk
.
range
.
lastkey
;
...
...
@@ -2696,10 +2722,14 @@ void populateCommandLegacyRangeSpec(struct redisCommand *c) {
lastkey_abs_index
+=
c
->
key_specs
[
i
].
bs
.
index
.
pos
;
/* For lastkey we use unsigned comparison to handle negative values correctly */
lastkey
=
max
((
unsigned
)
lastkey
,
(
unsigned
)
lastkey_abs_index
);
prev_lastkey
=
lastkey
;
}
if
(
firstkey
==
INT_MAX
)
if
(
firstkey
==
INT_MAX
)
{
/* Couldn't find range specs, the legacy range spec will remain empty, and we set the movablekeys flag. */
c
->
flags
|=
CMD_MOVABLE_KEYS
;
return
;
}
serverAssert
(
firstkey
!=
0
);
serverAssert
(
lastkey
!=
0
);
...
...
@@ -2787,11 +2817,9 @@ void populateCommandStructure(struct redisCommand *c) {
c
->
num_tips
++
;
c
->
num_args
=
populateArgsStructure
(
c
->
args
);
/* Handle the legacy range spec and the "movablekeys" flag (must be done after populating all key specs). */
populateCommandLegacyRangeSpec
(
c
);
/* Handle the "movablekeys" flag (must be done after populating all key specs). */
populateCommandMovableKeys
(
c
);
/* Assign the ID used for ACL. */
c
->
id
=
ACLGetCommandID
(
c
->
fullname
);
...
...
@@ -2812,7 +2840,7 @@ void populateCommandStructure(struct redisCommand *c) {
extern
struct
redisCommand
redisCommandTable
[];
/* Populates the Redis Command Table dict from
from
the static table in commands.c
/* Populates the Redis Command Table dict from the static table in commands.c
* which is auto generated from the json files in the commands folder. */
void
populateCommandTable
(
void
)
{
int
j
;
...
...
@@ -3498,31 +3526,6 @@ void afterCommand(client *c) {
}
}
/* Returns 1 for commands that may have key names in their arguments, but the legacy range
* spec doesn't cover all of them. */
void
populateCommandMovableKeys
(
struct
redisCommand
*
cmd
)
{
int
movablekeys
=
0
;
if
(
cmd
->
getkeys_proc
||
(
cmd
->
flags
&
CMD_MODULE_GETKEYS
))
{
/* Command with getkeys proc */
movablekeys
=
1
;
}
else
{
/* Redis command without getkeys proc, but possibly has
* movable keys because of a keys spec. */
for
(
int
i
=
0
;
i
<
cmd
->
key_specs_num
;
i
++
)
{
if
(
cmd
->
key_specs
[
i
].
begin_search_type
!=
KSPEC_BS_INDEX
||
cmd
->
key_specs
[
i
].
find_keys_type
!=
KSPEC_FK_RANGE
)
{
/* If we have a non-range spec it means we have movable keys */
movablekeys
=
1
;
break
;
}
}
}
if
(
movablekeys
)
cmd
->
flags
|=
CMD_MOVABLE_KEYS
;
}
/* Check if c->cmd exists, fills `err` with details in case it doesn't.
* Return 1 if exists. */
int
commandCheckExistence
(
client
*
c
,
sds
*
err
)
{
...
...
@@ -6028,7 +6031,7 @@ static int THPDisable(void) {
}
void
linuxMemoryWarnings
(
void
)
{
sds
err_msg
;
sds
err_msg
=
NULL
;
if
(
checkOvercommit
(
&
err_msg
)
<
0
)
{
serverLog
(
LL_WARNING
,
"WARNING %s"
,
err_msg
);
sdsfree
(
err_msg
);
...
...
@@ -6939,7 +6942,7 @@ int main(int argc, char **argv) {
serverLog
(
LL_WARNING
,
"Server initialized"
);
#ifdef __linux__
linuxMemoryWarnings
();
sds
err_msg
;
sds
err_msg
=
NULL
;
if
(
checkXenClocksource
(
&
err_msg
)
<
0
)
{
serverLog
(
LL_WARNING
,
"WARNING %s"
,
err_msg
);
sdsfree
(
err_msg
);
...
...
src/server.h
View file @
05833959
...
...
@@ -215,7 +215,8 @@ extern int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT];
#define CMD_MODULE_NO_CLUSTER (1ULL<<22)
/* Deny on Redis Cluster. */
#define CMD_NO_ASYNC_LOADING (1ULL<<23)
#define CMD_NO_MULTI (1ULL<<24)
#define CMD_MOVABLE_KEYS (1ULL<<25)
/* populated by populateCommandMovableKeys */
#define CMD_MOVABLE_KEYS (1ULL<<25)
/* The legacy range spec doesn't cover all keys.
* Populated by populateCommandLegacyRangeSpec. */
#define CMD_ALLOW_BUSY ((1ULL<<26))
#define CMD_MODULE_GETCHANNELS (1ULL<<27)
/* Use the modules getchannels interface. */
...
...
@@ -3550,7 +3551,6 @@ void mixDigest(unsigned char *digest, const void *ptr, size_t len);
void
xorDigest
(
unsigned
char
*
digest
,
const
void
*
ptr
,
size_t
len
);
sds
catSubCommandFullname
(
const
char
*
parent_name
,
const
char
*
sub_name
);
void
commandAddSubcommand
(
struct
redisCommand
*
parent
,
struct
redisCommand
*
subcommand
,
const
char
*
declared_name
);
void
populateCommandMovableKeys
(
struct
redisCommand
*
cmd
);
void
debugDelay
(
int
usec
);
void
killIOThreads
(
void
);
void
killThreads
(
void
);
...
...
src/syscheck.c
View file @
05833959
...
...
@@ -143,7 +143,7 @@ int checkOvercommit(sds *error_msg) {
FILE
*
fp
=
fopen
(
"/proc/sys/vm/overcommit_memory"
,
"r"
);
char
buf
[
64
];
if
(
!
fp
)
return
-
1
;
if
(
!
fp
)
return
0
;
if
(
fgets
(
buf
,
64
,
fp
)
==
NULL
)
{
fclose
(
fp
);
return
0
;
...
...
@@ -152,7 +152,7 @@ int checkOvercommit(sds *error_msg) {
if
(
atoi
(
buf
))
{
*
error_msg
=
sdsnew
(
"
WARNING
overcommit_memory is set to 0! Background save may fail under low memory condition. "
"overcommit_memory is set to 0! Background save may fail under low memory condition. "
"To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the "
"command 'sysctl vm.overcommit_memory=1' for this to take effect."
);
return
-
1
;
...
...
@@ -351,7 +351,7 @@ check checks[] = {
int
syscheck
(
void
)
{
check
*
cur_check
=
checks
;
int
ret
=
1
;
sds
err_msg
;
sds
err_msg
=
NULL
;
while
(
cur_check
->
check_fn
)
{
int
res
=
cur_check
->
check_fn
(
&
err_msg
);
printf
(
"[%s]..."
,
cur_check
->
name
);
...
...
src/t_stream.c
View file @
05833959
...
...
@@ -2144,7 +2144,7 @@ void xrevrangeCommand(client *c) {
xrangeGenericCommand
(
c
,
1
);
}
/* XLEN */
/* XLEN
key
*/
void
xlenCommand
(
client
*
c
)
{
robj
*
o
;
if
((
o
=
lookupKeyReadOrReply
(
c
,
c
->
argv
[
1
],
shared
.
czero
))
==
NULL
...
...
@@ -2156,10 +2156,10 @@ void xlenCommand(client *c) {
/* XREAD [BLOCK <milliseconds>] [COUNT <count>] STREAMS key_1 key_2 ... key_N
* ID_1 ID_2 ... ID_N
*
* This function also implements the XREAD
-
GROUP command, which is like XREAD
* This function also implements the XREADGROUP command, which is like XREAD
* but accepting the [GROUP group-name consumer-name] additional option.
* This is useful because while XREAD is a read command and can be called
* on slaves, XREAD
-
GROUP is not. */
* on slaves, XREADGROUP is not. */
#define XREAD_BLOCKED_DEFAULT_COUNT 1000
void
xreadCommand
(
client
*
c
)
{
long
long
timeout
=
-
1
;
/* -1 means, no BLOCK argument given. */
...
...
@@ -2566,8 +2566,8 @@ void streamDelConsumer(streamCG *cg, streamConsumer *consumer) {
* Consumer groups commands
* ----------------------------------------------------------------------- */
/* XGROUP CREATE <key> <groupname> <id or $> [MKSTREAM] [ENTRIES
ADDED count
]
* XGROUP SETID <key> <groupname> <id or $> [ENTRIES
ADDED count
]
/* XGROUP CREATE <key> <groupname> <id or $> [MKSTREAM] [ENTRIES
READ entries_read
]
* XGROUP SETID <key> <groupname> <id or $> [ENTRIES
READ entries_read
]
* XGROUP DESTROY <key> <groupname>
* XGROUP CREATECONSUMER <key> <groupname> <consumer>
* XGROUP DELCONSUMER <key> <groupname> <consumername> */
...
...
@@ -2805,7 +2805,6 @@ void xsetidCommand(client *c) {
}
/* XACK <key> <group> <id> <id> ... <id>
*
* Acknowledge a message as processed. In practical terms we just check the
* pending entries list (PEL) of the group, and delete the PEL entry both from
* the group and the consumer (pending messages are referenced in both places).
...
...
@@ -3050,7 +3049,7 @@ void xpendingCommand(client *c) {
* [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
* [FORCE] [JUSTID]
*
*
Get
s ownership of one or multiple messages in the Pending Entries List
*
Change
s ownership of one or multiple messages in the Pending Entries List
* of a given stream consumer group.
*
* If the message ID (among the specified ones) exists, and its idle
...
...
@@ -3316,7 +3315,7 @@ cleanup:
/* XAUTOCLAIM <key> <group> <consumer> <min-idle-time> <start> [COUNT <count>] [JUSTID]
*
*
Get
s ownership of one or multiple messages in the Pending Entries List
*
Change
s ownership of one or multiple messages in the Pending Entries List
* of a given stream consumer group.
*
* For each PEL entry, if its idle time greater or equal to <min-idle-time>,
...
...
src/version.h
View file @
05833959
#define REDIS_VERSION "7.0.
1
"
#define REDIS_VERSION_NUM 0x0007000
1
#define REDIS_VERSION "7.0.
2
"
#define REDIS_VERSION_NUM 0x0007000
2
tests/integration/logging.tcl
View file @
05833959
...
...
@@ -8,9 +8,12 @@ if {$system_name eq {darwin}} {
set backtrace_supported 1
}
elseif
{
$system
_name eq
{
linux
}}
{
# Avoid the test on libmusl, which does not support backtrace
set ldd
[
exec ldd src/redis-server
]
if
{
!
[
string match
{
*libc.*musl*
}
$ldd
]}
{
set backtrace_supported 1
# and on static binaries
(
ldd exit code 1
)
where we can't detect libmusl
catch
{
set ldd
[
exec ldd src/redis-server
]
if
{
!
[
string match
{
*libc.*musl*
}
$ldd
]}
{
set backtrace_supported 1
}
}
}
...
...
tests/modules/keyspecs.c
View file @
05833959
...
...
@@ -18,6 +18,13 @@ int createKspecNone(RedisModuleCtx *ctx) {
return
REDISMODULE_OK
;
}
int
createKspecNoneWithGetkeys
(
RedisModuleCtx
*
ctx
)
{
/* A command without keyspecs; only the legacy (first,last,step) triple (MSET like spec), but also has a getkeys callback */
if
(
RedisModule_CreateCommand
(
ctx
,
"kspec.nonewithgetkeys"
,
kspec_impl
,
"getkeys-api"
,
1
,
-
1
,
2
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_OK
;
}
int
createKspecTwoRanges
(
RedisModuleCtx
*
ctx
)
{
/* Test that two position/range-based key specs are combined to produce the
* legacy (first,last,step) values representing both keys. */
...
...
@@ -51,6 +58,39 @@ int createKspecTwoRanges(RedisModuleCtx *ctx) {
return
REDISMODULE_OK
;
}
int
createKspecTwoRangesWithGap
(
RedisModuleCtx
*
ctx
)
{
/* Test that two position/range-based key specs are combined to produce the
* legacy (first,last,step) values representing just one key. */
if
(
RedisModule_CreateCommand
(
ctx
,
"kspec.tworangeswithgap"
,
kspec_impl
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
RedisModuleCommand
*
command
=
RedisModule_GetCommand
(
ctx
,
"kspec.tworangeswithgap"
);
RedisModuleCommandInfo
info
=
{
.
version
=
REDISMODULE_COMMAND_INFO_VERSION
,
.
arity
=
-
2
,
.
key_specs
=
(
RedisModuleCommandKeySpec
[]){
{
.
flags
=
REDISMODULE_CMD_KEY_RO
|
REDISMODULE_CMD_KEY_ACCESS
,
.
begin_search_type
=
REDISMODULE_KSPEC_BS_INDEX
,
.
bs
.
index
.
pos
=
1
,
.
find_keys_type
=
REDISMODULE_KSPEC_FK_RANGE
,
.
fk
.
range
=
{
0
,
1
,
0
}
},
{
.
flags
=
REDISMODULE_CMD_KEY_RW
|
REDISMODULE_CMD_KEY_UPDATE
,
.
begin_search_type
=
REDISMODULE_KSPEC_BS_INDEX
,
.
bs
.
index
.
pos
=
3
,
/* Omitted find_keys_type is shorthand for RANGE {0,1,0} */
},
{
0
}
}
};
if
(
RedisModule_SetCommandInfo
(
command
,
&
info
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_OK
;
}
int
createKspecKeyword
(
RedisModuleCtx
*
ctx
)
{
/* Only keyword-based specs. The legacy triple is wiped and set to (0,0,0). */
if
(
RedisModule_CreateCommand
(
ctx
,
"kspec.keyword"
,
kspec_impl
,
""
,
3
,
-
1
,
1
)
==
REDISMODULE_ERR
)
...
...
@@ -177,7 +217,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_ERR
;
if
(
createKspecNone
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecNoneWithGetkeys
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecTwoRanges
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecTwoRangesWithGap
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecKeyword
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecComplex1
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
createKspecComplex2
(
ctx
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
...
...
tests/unit/introspection-2.tcl
View file @
05833959
...
...
@@ -176,4 +176,19 @@ start_server {tags {"introspection"}} {
assert_equal
{{}}
[
r command info get|key
]
assert_equal
{{}}
[
r command info config|get|key
]
}
foreach cmd
{
SET GET MSET BITFIELD LMOVE LPOP BLPOP PING MEMORY MEMORY|USAGE RENAME GEORADIUS_RO
}
{
test
"
$cmd
command will not be marked with movablekeys"
{
set info
[
lindex
[
r command info $cmd
]
0
]
assert_no_match
{
*movablekeys*
}
[
lindex $info 2
]
}
}
foreach cmd
{
ZUNIONSTORE XREAD EVAL SORT SORT_RO MIGRATE GEORADIUS
}
{
test
"
$cmd
command is marked with movablekeys"
{
set info
[
lindex
[
r command info $cmd
]
0
]
assert_match
{
*movablekeys*
}
[
lindex $info 2
]
}
}
}
tests/unit/moduleapi/keyspecs.tcl
View file @
05833959
...
...
@@ -31,6 +31,20 @@ start_server {tags {"modules"}} {
assert_equal
[
r command getkeys kspec.tworanges foo bar baz quux
]
{
foo bar
}
}
test
"Module key specs: Two ranges with gap"
{
set reply
[
lindex
[
r command info kspec.tworangeswithgap
]
0
]
# Verify
(
first, last, step
)
and movablekeys
assert_equal
[
lindex $reply 2
]
{
module movablekeys
}
assert_equal
[
lindex $reply 3
]
1
assert_equal
[
lindex $reply 4
]
1
assert_equal
[
lindex $reply 5
]
1
# Verify key-specs
set keyspecs
[
lindex $reply 8
]
assert_equal
[
lindex $keyspecs 0
]
{
flags
{
RO access
}
begin_search
{
type index spec
{
index 1
}}
find_keys
{
type range spec
{
lastkey 0 keystep 1 limit 0
}}}
assert_equal
[
lindex $keyspecs 1
]
{
flags
{
RW update
}
begin_search
{
type index spec
{
index 3
}}
find_keys
{
type range spec
{
lastkey 0 keystep 1 limit 0
}}}
assert_equal
[
r command getkeys kspec.tworangeswithgap foo bar baz quux
]
{
foo baz
}
}
test
"Module key specs: Keyword-only spec clears the legacy triple"
{
set reply
[
lindex
[
r command info kspec.keyword
]
0
]
# Verify
(
first, last, step
)
and movablekeys
...
...
@@ -79,7 +93,7 @@ start_server {tags {"modules"}} {
test
"Module command list filtering"
{
;
# Note: we piggyback this tcl file to test the general functionality of command list filtering
set reply
[
r command list filterby module keyspecs
]
assert_equal
[
lsort $reply
]
{
kspec.complex1 kspec.complex2 kspec.keyword kspec.none kspec.
tworanges
}
assert_equal
[
lsort $reply
]
{
kspec.complex1 kspec.complex2 kspec.keyword kspec.none kspec.
nonewithgetkeys kspec.tworanges kspec.tworangeswithgap
}
assert_equal
[
r command getkeys kspec.complex2 foo bar 2 baz quux banana STORE dst dummy MOREKEYS hey ho
]
{
dst foo bar baz quux hey ho
}
}
...
...
@@ -108,6 +122,20 @@ start_server {tags {"modules"}} {
assert_equal
"This user has no permissions to access the 'write' key"
[
r ACL DRYRUN testuser kspec.tworanges write rw
]
}
foreach cmd
{
kspec.none kspec.tworanges
}
{
test
"
$cmd
command will not be marked with movablekeys"
{
set info
[
lindex
[
r command info $cmd
]
0
]
assert_no_match
{
*movablekeys*
}
[
lindex $info 2
]
}
}
foreach cmd
{
kspec.keyword kspec.complex1 kspec.complex2 kspec.nonewithgetkeys
}
{
test
"
$cmd
command is marked with movablekeys"
{
set info
[
lindex
[
r command info $cmd
]
0
]
assert_match
{
*movablekeys*
}
[
lindex $info 2
]
}
}
test
"Unload the module - keyspecs"
{
assert_equal
{
OK
}
[
r module unload keyspecs
]
}
...
...
utils/generate-module-api-doc.rb
View file @
05833959
...
...
@@ -20,7 +20,7 @@ def markdown(s)
# Add backquotes around RedisModule functions and type where missing.
l
=
l
.
gsub
(
/(?<!`)RedisModule[A-z]+(?:\*?\(\))?/
){
|
x
|
"`
#{
x
}
`"
}
# Add backquotes around c functions like malloc() where missing.
l
=
l
.
gsub
(
/(?<![`A-z])[a-z_]+\(\)/
,
'`\0`'
)
l
=
l
.
gsub
(
/(?<![`A-z
.
])[a-z_]+\(\)/
,
'`\0`'
)
# Add backquotes around macro and var names containing underscores.
l
=
l
.
gsub
(
/(?<![`A-z\*])[A-Za-z]+_[A-Za-z0-9_]+/
){
|
x
|
"`
#{
x
}
`"
}
# Link URLs preceded by space or newline (not already linked)
...
...
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