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
76b9c13d
Unverified
Commit
76b9c13d
authored
Jul 11, 2022
by
Oran Agra
Committed by
GitHub
Jul 11, 2022
Browse files
Merge pull request #10962 from oranagra/release-7.0.3
Release 7.0.3
parents
05833959
85abb7cf
Changes
86
Hide whitespace changes
Inline
Side-by-side
src/syscheck.c
View file @
76b9c13d
...
@@ -150,7 +150,7 @@ int checkOvercommit(sds *error_msg) {
...
@@ -150,7 +150,7 @@ int checkOvercommit(sds *error_msg) {
}
}
fclose
(
fp
);
fclose
(
fp
);
if
(
a
to
i
(
buf
)
)
{
if
(
str
to
l
(
buf
,
NULL
,
10
)
==
0
)
{
*
error_msg
=
sdsnew
(
*
error_msg
=
sdsnew
(
"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 "
"To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the "
...
...
src/t_zset.c
View file @
76b9c13d
...
@@ -2952,8 +2952,10 @@ static void zrangeResultFinalizeClient(zrange_result_handler *handler,
...
@@ -2952,8 +2952,10 @@ static void zrangeResultFinalizeClient(zrange_result_handler *handler,
/* Result handler methods for storing the ZRANGESTORE to a zset. */
/* Result handler methods for storing the ZRANGESTORE to a zset. */
static
void
zrangeResultBeginStore
(
zrange_result_handler
*
handler
,
long
length
)
static
void
zrangeResultBeginStore
(
zrange_result_handler
*
handler
,
long
length
)
{
{
UNUSED
(
length
);
if
(
length
>
(
long
)
server
.
zset_max_listpack_entries
)
handler
->
dstobj
=
createZsetListpackObject
();
handler
->
dstobj
=
createZsetObject
();
else
handler
->
dstobj
=
createZsetListpackObject
();
}
}
static
void
zrangeResultEmitCBufferForStore
(
zrange_result_handler
*
handler
,
static
void
zrangeResultEmitCBufferForStore
(
zrange_result_handler
*
handler
,
...
...
src/tls.c
View file @
76b9c13d
...
@@ -722,6 +722,8 @@ static void connTLSClose(connection *conn_) {
...
@@ -722,6 +722,8 @@ static void connTLSClose(connection *conn_) {
tls_connection
*
conn
=
(
tls_connection
*
)
conn_
;
tls_connection
*
conn
=
(
tls_connection
*
)
conn_
;
if
(
conn
->
ssl
)
{
if
(
conn
->
ssl
)
{
if
(
conn
->
c
.
state
==
CONN_STATE_CONNECTED
)
SSL_shutdown
(
conn
->
ssl
);
SSL_free
(
conn
->
ssl
);
SSL_free
(
conn
->
ssl
);
conn
->
ssl
=
NULL
;
conn
->
ssl
=
NULL
;
}
}
...
@@ -834,12 +836,12 @@ static int connTLSWritev(connection *conn_, const struct iovec *iov, int iovcnt)
...
@@ -834,12 +836,12 @@ static int connTLSWritev(connection *conn_, const struct iovec *iov, int iovcnt)
* which is not worth doing so much memory copying to reduce system calls,
* which is not worth doing so much memory copying to reduce system calls,
* therefore, invoke connTLSWrite() multiple times to avoid memory copies. */
* therefore, invoke connTLSWrite() multiple times to avoid memory copies. */
if
(
iov_bytes_len
>
NET_MAX_WRITES_PER_EVENT
)
{
if
(
iov_bytes_len
>
NET_MAX_WRITES_PER_EVENT
)
{
size_t
tot_sent
=
0
;
s
size_t
tot_sent
=
0
;
for
(
int
i
=
0
;
i
<
iovcnt
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iovcnt
;
i
++
)
{
size_t
sent
=
connTLSWrite
(
conn_
,
iov
[
i
].
iov_base
,
iov
[
i
].
iov_len
);
s
size_t
sent
=
connTLSWrite
(
conn_
,
iov
[
i
].
iov_base
,
iov
[
i
].
iov_len
);
if
(
sent
<=
0
)
return
tot_sent
>
0
?
tot_sent
:
sent
;
if
(
sent
<=
0
)
return
tot_sent
>
0
?
tot_sent
:
sent
;
tot_sent
+=
sent
;
tot_sent
+=
sent
;
if
(
sent
!=
iov
[
i
].
iov_len
)
break
;
if
(
(
size_t
)
sent
!=
iov
[
i
].
iov_len
)
break
;
}
}
return
tot_sent
;
return
tot_sent
;
}
}
...
...
src/util.c
View file @
76b9c13d
...
@@ -43,6 +43,7 @@
...
@@ -43,6 +43,7 @@
#include <sys/stat.h>
#include <sys/stat.h>
#include <dirent.h>
#include <dirent.h>
#include <fcntl.h>
#include <fcntl.h>
#include <libgen.h>
#include "util.h"
#include "util.h"
#include "sha256.h"
#include "sha256.h"
...
@@ -923,6 +924,54 @@ sds makePath(char *path, char *filename) {
...
@@ -923,6 +924,54 @@ sds makePath(char *path, char *filename) {
return
sdscatfmt
(
sdsempty
(),
"%s/%s"
,
path
,
filename
);
return
sdscatfmt
(
sdsempty
(),
"%s/%s"
,
path
,
filename
);
}
}
/* Given the filename, sync the corresponding directory.
*
* Usually a portable and safe pattern to overwrite existing files would be like:
* 1. create a new temp file (on the same file system!)
* 2. write data to the temp file
* 3. fsync() the temp file
* 4. rename the temp file to the appropriate name
* 5. fsync() the containing directory */
int
fsyncFileDir
(
const
char
*
filename
)
{
#ifdef _AIX
/* AIX is unable to fsync a directory */
return
0
;
#endif
char
temp_filename
[
PATH_MAX
+
1
];
char
*
dname
;
int
dir_fd
;
if
(
strlen
(
filename
)
>
PATH_MAX
)
{
errno
=
ENAMETOOLONG
;
return
-
1
;
}
/* In the glibc implementation dirname may modify their argument. */
memcpy
(
temp_filename
,
filename
,
strlen
(
filename
)
+
1
);
dname
=
dirname
(
temp_filename
);
dir_fd
=
open
(
dname
,
O_RDONLY
);
if
(
dir_fd
==
-
1
)
{
/* Some OSs don't allow us to open directories at all, just
* ignore the error in that case */
if
(
errno
==
EISDIR
)
{
return
0
;
}
return
-
1
;
}
/* Some OSs don't allow us to fsync directories at all, so we can ignore
* those errors. */
if
(
redis_fsync
(
dir_fd
)
==
-
1
&&
!
(
errno
==
EBADF
||
errno
==
EINVAL
))
{
int
save_errno
=
errno
;
close
(
dir_fd
);
errno
=
save_errno
;
return
-
1
;
}
close
(
dir_fd
);
return
0
;
}
#ifdef REDIS_TEST
#ifdef REDIS_TEST
#include <assert.h>
#include <assert.h>
...
...
src/util.h
View file @
76b9c13d
...
@@ -85,6 +85,7 @@ int dirExists(char *dname);
...
@@ -85,6 +85,7 @@ int dirExists(char *dname);
int
dirRemove
(
char
*
dname
);
int
dirRemove
(
char
*
dname
);
int
fileExist
(
char
*
filename
);
int
fileExist
(
char
*
filename
);
sds
makePath
(
char
*
path
,
char
*
filename
);
sds
makePath
(
char
*
path
,
char
*
filename
);
int
fsyncFileDir
(
const
char
*
filename
);
#ifdef REDIS_TEST
#ifdef REDIS_TEST
int
utilTest
(
int
argc
,
char
**
argv
,
int
flags
);
int
utilTest
(
int
argc
,
char
**
argv
,
int
flags
);
...
...
src/version.h
View file @
76b9c13d
#define REDIS_VERSION "7.0.
2
"
#define REDIS_VERSION "7.0.
3
"
#define REDIS_VERSION_NUM 0x0007000
2
#define REDIS_VERSION_NUM 0x0007000
3
tests/cluster/tests/00-base.tcl
View file @
76b9c13d
...
@@ -80,3 +80,16 @@ test "Script no-cluster flag" {
...
@@ -80,3 +80,16 @@ test "Script no-cluster flag" {
assert_match
{
*Can not run script on cluster, 'no-cluster' flag is set*
}
$e
assert_match
{
*Can not run script on cluster, 'no-cluster' flag is set*
}
$e
}
}
test
"CLUSTER RESET SOFT test"
{
set last_epoch_node0
[
get_info_field
[
R 0 cluster info
]
cluster_current_epoch
]
R 0 FLUSHALL
R 0 CLUSTER RESET
assert
{[
get_info_field
[
R 0 cluster info
]
cluster_current_epoch
]
eq $last_epoch_node0
}
set last_epoch_node1
[
get_info_field
[
R 1 cluster info
]
cluster_current_epoch
]
R 1 FLUSHALL
R 1 CLUSTER RESET SOFT
assert
{[
get_info_field
[
R 1 cluster info
]
cluster_current_epoch
]
eq $last_epoch_node1
}
}
tests/cluster/tests/28-cluster-shards.tcl
View file @
76b9c13d
...
@@ -182,4 +182,21 @@ test "Test the replica reports a loading state while it's loading" {
...
@@ -182,4 +182,21 @@ test "Test the replica reports a loading state while it's loading" {
# Final sanity, the replica agrees it is online.
# Final sanity, the replica agrees it is online.
assert_equal
"online"
[
dict get
[
get_node_info_from_shard $replica_cluster_id $replica_id
"node"
]
health
]
assert_equal
"online"
[
dict get
[
get_node_info_from_shard $replica_cluster_id $replica_id
"node"
]
health
]
}
}
\ No newline at end of file
test
"Regression test for a crash when calling SHARDS during handshake"
{
# Reset forget a node, so we can use it to establish handshaking connections
set id
[
R 19 CLUSTER MYID
]
R 19 CLUSTER RESET HARD
for
{
set i 0
}
{
$i
< 19
}
{
incr i
}
{
R $i CLUSTER FORGET $id
}
R 19 cluster meet 127.0.0.1
[
get_instance_attrib redis 0 port
]
# This should line would previously crash, since all the outbound
# connections were in handshake state.
R 19 CLUSTER SHARDS
}
test
"Cluster is up"
{
assert_cluster_state ok
}
tests/cluster/tests/29-slot-migration-response.tcl
0 → 100644
View file @
76b9c13d
# Tests for the response of slot migrations.
source
"../tests/includes/init-tests.tcl"
source
"../tests/includes/utils.tcl"
test
"Create a 2 nodes cluster"
{
create_cluster 2 0
config_set_all_nodes cluster-allow-replica-migration no
}
test
"Cluster is up"
{
assert_cluster_state ok
}
set cluster
[
redis_cluster 127.0.0.1:
[
get_instance_attrib redis 0 port
]]
catch
{
unset nodefrom
}
catch
{
unset nodeto
}
$cluster
refresh_nodes_map
test
"Set many keys in the cluster"
{
for
{
set i 0
}
{
$i
< 5000
}
{
incr i
}
{
$cluster set $i $i
assert
{
[
$cluster
get $i
]
eq $i
}
}
}
test
"Test cluster responses during migration of slot x"
{
set slot 10
array set nodefrom
[
$cluster
masternode_for_slot $slot
]
array set nodeto
[
$cluster
masternode_notfor_slot $slot
]
$nodeto
(
link
)
cluster setslot $slot importing $nodefrom
(
id
)
$nodefrom
(
link
)
cluster setslot $slot migrating $nodeto
(
id
)
# Get a key from that slot
set key
[
$nodefrom
(
link
)
cluster GETKEYSINSLOT $slot
"1"
]
# MOVED REPLY
assert_error
"*MOVED*"
{
$nodeto
(
link
)
set $key
"newVal"
}
# ASK REPLY
assert_error
"*ASK*"
{
$nodefrom
(
link
)
set
"abc{
$key
}"
"newVal"
}
# UNSTABLE REPLY
assert_error
"*TRYAGAIN*"
{
$nodefrom
(
link
)
mset
"a{
$key
}"
"newVal"
$key
"newVal2"
}
}
config_set_all_nodes cluster-allow-replica-migration yes
tests/integration/redis-benchmark.tcl
View file @
76b9c13d
...
@@ -116,6 +116,15 @@ start_server {tags {"benchmark network external:skip"}} {
...
@@ -116,6 +116,15 @@ start_server {tags {"benchmark network external:skip"}} {
# ensure the keyspace has the desired size
# ensure the keyspace has the desired size
assert_match
{
50
}
[
scan
[
regexp -inline
{
keys
\=
([
\d
]
*
)}
[
r info keyspace
]]
keys=%d
]
assert_match
{
50
}
[
scan
[
regexp -inline
{
keys
\=
([
\d
]
*
)}
[
r info keyspace
]]
keys=%d
]
}
}
test
{
benchmark: clients idle mode should return error when reached maxclients limit
}
{
set cmd
[
redisbenchmark $master_host $master_port
"-c 10 -I"
]
set original_maxclients
[
lindex
[
r config get maxclients
]
1
]
r config set maxclients 5
catch
{
exec
{*}
$cmd
}
error
assert_match
"*Error*"
$error
r config set maxclients $original_maxclients
}
# tls specific tests
# tls specific tests
if
{
$::tls
}
{
if
{
$::tls
}
{
...
...
tests/modules/blockedclient.c
View file @
76b9c13d
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include <assert.h>
#include <assert.h>
#include <stdio.h>
#include <stdio.h>
#include <pthread.h>
#include <pthread.h>
#include <strings.h>
#define UNUSED(V) ((void) V)
#define UNUSED(V) ((void) V)
...
@@ -119,8 +120,20 @@ void *bg_call_worker(void *arg) {
...
@@ -119,8 +120,20 @@ void *bg_call_worker(void *arg) {
}
}
// Call the command
// Call the command
const
char
*
cmd
=
RedisModule_StringPtrLen
(
bg
->
argv
[
1
],
NULL
);
const
char
*
module_cmd
=
RedisModule_StringPtrLen
(
bg
->
argv
[
0
],
NULL
);
RedisModuleCallReply
*
rep
=
RedisModule_Call
(
ctx
,
cmd
,
"v"
,
bg
->
argv
+
2
,
bg
->
argc
-
2
);
int
cmd_pos
=
1
;
RedisModuleString
*
format_redis_str
=
RedisModule_CreateString
(
NULL
,
"v"
,
1
);
if
(
!
strcasecmp
(
module_cmd
,
"do_bg_rm_call_format"
))
{
cmd_pos
=
2
;
size_t
format_len
;
const
char
*
format
=
RedisModule_StringPtrLen
(
bg
->
argv
[
1
],
&
format_len
);
RedisModule_StringAppendBuffer
(
NULL
,
format_redis_str
,
format
,
format_len
);
RedisModule_StringAppendBuffer
(
NULL
,
format_redis_str
,
"E"
,
1
);
}
const
char
*
format
=
RedisModule_StringPtrLen
(
format_redis_str
,
NULL
);
const
char
*
cmd
=
RedisModule_StringPtrLen
(
bg
->
argv
[
cmd_pos
],
NULL
);
RedisModuleCallReply
*
rep
=
RedisModule_Call
(
ctx
,
cmd
,
format
,
bg
->
argv
+
cmd_pos
+
1
,
bg
->
argc
-
cmd_pos
-
1
);
RedisModule_FreeString
(
NULL
,
format_redis_str
);
// Release GIL
// Release GIL
RedisModule_ThreadSafeContextUnlock
(
ctx
);
RedisModule_ThreadSafeContextUnlock
(
ctx
);
...
@@ -306,6 +319,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -306,6 +319,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
if
(
RedisModule_CreateCommand
(
ctx
,
"do_bg_rm_call"
,
do_bg_rm_call
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"do_bg_rm_call"
,
do_bg_rm_call
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"do_bg_rm_call_format"
,
do_bg_rm_call
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"do_fake_bg_true"
,
do_fake_bg_true
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"do_fake_bg_true"
,
do_fake_bg_true
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
...
...
tests/modules/misc.c
View file @
76b9c13d
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#include <assert.h>
#include <assert.h>
#include <unistd.h>
#include <unistd.h>
#include <errno.h>
#include <errno.h>
#include <limits.h>
#define UNUSED(x) (void)(x)
#define UNUSED(x) (void)(x)
...
@@ -239,9 +240,17 @@ int test_clientinfo(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -239,9 +240,17 @@ int test_clientinfo(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
(
void
)
argv
;
(
void
)
argv
;
(
void
)
argc
;
(
void
)
argc
;
RedisModuleClientInfo
ci
=
{
.
version
=
REDISMODULE_CLIENTINFO_VERSION
};
RedisModuleClientInfoV1
ci
=
REDISMODULE_CLIENTINFO_INITIALIZER_V1
;
uint64_t
client_id
=
RedisModule_GetClientId
(
ctx
);
if
(
RedisModule_GetClientInfoById
(
&
ci
,
RedisModule_GetClientId
(
ctx
))
==
REDISMODULE_ERR
)
{
/* Check expected result from the V1 initializer. */
assert
(
ci
.
version
==
1
);
/* Trying to populate a future version of the struct should fail. */
ci
.
version
=
REDISMODULE_CLIENTINFO_VERSION
+
1
;
assert
(
RedisModule_GetClientInfoById
(
&
ci
,
client_id
)
==
REDISMODULE_ERR
);
ci
.
version
=
1
;
if
(
RedisModule_GetClientInfoById
(
&
ci
,
client_id
)
==
REDISMODULE_ERR
)
{
RedisModule_ReplyWithError
(
ctx
,
"failed to get client info"
);
RedisModule_ReplyWithError
(
ctx
,
"failed to get client info"
);
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
...
@@ -270,6 +279,27 @@ int test_clientinfo(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -270,6 +279,27 @@ int test_clientinfo(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
int
test_getname
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
(
void
)
argv
;
if
(
argc
!=
1
)
return
RedisModule_WrongArity
(
ctx
);
unsigned
long
long
id
=
RedisModule_GetClientId
(
ctx
);
RedisModuleString
*
name
=
RedisModule_GetClientNameById
(
ctx
,
id
);
if
(
name
==
NULL
)
return
RedisModule_ReplyWithError
(
ctx
,
"-ERR No name"
);
RedisModule_ReplyWithString
(
ctx
,
name
);
RedisModule_FreeString
(
ctx
,
name
);
return
REDISMODULE_OK
;
}
int
test_setname
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
if
(
argc
!=
2
)
return
RedisModule_WrongArity
(
ctx
);
unsigned
long
long
id
=
RedisModule_GetClientId
(
ctx
);
if
(
RedisModule_SetClientNameById
(
id
,
argv
[
1
])
==
REDISMODULE_OK
)
return
RedisModule_ReplyWithSimpleString
(
ctx
,
"OK"
);
else
return
RedisModule_ReplyWithError
(
ctx
,
strerror
(
errno
));
}
int
test_log_tsctx
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
int
test_log_tsctx
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
{
RedisModuleCtx
*
tsctx
=
RedisModule_GetDetachedThreadSafeContext
(
ctx
);
RedisModuleCtx
*
tsctx
=
RedisModule_GetDetachedThreadSafeContext
(
ctx
);
...
@@ -354,6 +384,68 @@ int test_rm_call_flags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
...
@@ -354,6 +384,68 @@ int test_rm_call_flags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc){
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
int
test_ull_conv
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
UNUSED
(
argv
);
UNUSED
(
argc
);
unsigned
long
long
ull
=
18446744073709551615ULL
;
const
char
*
ullstr
=
"18446744073709551615"
;
RedisModuleString
*
s1
=
RedisModule_CreateStringFromULongLong
(
ctx
,
ull
);
RedisModuleString
*
s2
=
RedisModule_CreateString
(
ctx
,
ullstr
,
strlen
(
ullstr
));
if
(
RedisModule_StringCompare
(
s1
,
s2
)
!=
0
)
{
char
err
[
4096
];
snprintf
(
err
,
4096
,
"Failed to convert unsigned long long to string ('%s' != '%s')"
,
RedisModule_StringPtrLen
(
s1
,
NULL
),
RedisModule_StringPtrLen
(
s2
,
NULL
));
RedisModule_ReplyWithError
(
ctx
,
err
);
goto
final
;
}
unsigned
long
long
ull2
=
0
;
if
(
RedisModule_StringToULongLong
(
s2
,
&
ull2
)
==
REDISMODULE_ERR
)
{
RedisModule_ReplyWithError
(
ctx
,
"Failed to convert string to unsigned long long"
);
goto
final
;
}
if
(
ull2
!=
ull
)
{
char
err
[
4096
];
snprintf
(
err
,
4096
,
"Failed to convert string to unsigned long long (%llu != %llu)"
,
ull2
,
ull
);
RedisModule_ReplyWithError
(
ctx
,
err
);
goto
final
;
}
/* Make sure we can't convert a string more than ULLONG_MAX or less than 0 */
ullstr
=
"18446744073709551616"
;
RedisModuleString
*
s3
=
RedisModule_CreateString
(
ctx
,
ullstr
,
strlen
(
ullstr
));
unsigned
long
long
ull3
;
if
(
RedisModule_StringToULongLong
(
s3
,
&
ull3
)
==
REDISMODULE_OK
)
{
RedisModule_ReplyWithError
(
ctx
,
"Invalid string successfully converted to unsigned long long"
);
RedisModule_FreeString
(
ctx
,
s3
);
goto
final
;
}
RedisModule_FreeString
(
ctx
,
s3
);
ullstr
=
"-1"
;
RedisModuleString
*
s4
=
RedisModule_CreateString
(
ctx
,
ullstr
,
strlen
(
ullstr
));
unsigned
long
long
ull4
;
if
(
RedisModule_StringToULongLong
(
s4
,
&
ull4
)
==
REDISMODULE_OK
)
{
RedisModule_ReplyWithError
(
ctx
,
"Invalid string successfully converted to unsigned long long"
);
RedisModule_FreeString
(
ctx
,
s4
);
goto
final
;
}
RedisModule_FreeString
(
ctx
,
s4
);
RedisModule_ReplyWithSimpleString
(
ctx
,
"ok"
);
final:
RedisModule_FreeString
(
ctx
,
s1
);
RedisModule_FreeString
(
ctx
,
s2
);
return
REDISMODULE_OK
;
}
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
REDISMODULE_NOT_USED
(
argv
);
REDISMODULE_NOT_USED
(
argv
);
REDISMODULE_NOT_USED
(
argc
);
REDISMODULE_NOT_USED
(
argc
);
...
@@ -366,6 +458,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -366,6 +458,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.ld_conversion"
,
test_ld_conv
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.ld_conversion"
,
test_ld_conv
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.ull_conversion"
,
test_ull_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
)
...
@@ -384,6 +478,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
...
@@ -384,6 +478,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.clientinfo"
,
test_clientinfo
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.clientinfo"
,
test_clientinfo
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getname"
,
test_getname
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.setname"
,
test_setname
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.redisversion"
,
test_redisversion
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.redisversion"
,
test_redisversion
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
return
REDISMODULE_ERR
;
return
REDISMODULE_ERR
;
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getclientcert"
,
test_getclientcert
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
if
(
RedisModule_CreateCommand
(
ctx
,
"test.getclientcert"
,
test_getclientcert
,
""
,
0
,
0
,
0
)
==
REDISMODULE_ERR
)
...
...
tests/sentinel/tests/00-base.tcl
View file @
76b9c13d
...
@@ -12,6 +12,13 @@ if {$::simulate_error} {
...
@@ -12,6 +12,13 @@ if {$::simulate_error} {
}
}
}
}
test
"Sentinel commands sanity check"
{
foreach_sentinel_id id
{
assert_equal
{
72
}
[
llength
[
S $id command list
]]
assert_equal
{
15
}
[
S $id command count
]
}
}
test
"Basic failover works if the master is down"
{
test
"Basic failover works if the master is down"
{
set old_port
[
RPort $master_id
]
set old_port
[
RPort $master_id
]
set addr
[
S 0 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster
]
set addr
[
S 0 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster
]
...
...
tests/sentinel/tests/03-runtime-reconf.tcl
View file @
76b9c13d
...
@@ -126,7 +126,7 @@ test "Sentinels (re)connection following master ACL change" {
...
@@ -126,7 +126,7 @@ test "Sentinels (re)connection following master ACL change" {
wait_for_condition 100 50
{
wait_for_condition 100 50
{
[
string match
"*disconnected*"
[
dict get
[
S $sent2re SENTINEL MASTER mymaster
]
flags
]]
!= 0
[
string match
"*disconnected*"
[
dict get
[
S $sent2re SENTINEL MASTER mymaster
]
flags
]]
!= 0
}
else
{
}
else
{
fail
"Expected:
S
entinel to be disconnected from master due to
wrong
password"
fail
"Expected:
Restarted s
entinel to be disconnected from master due to
obsolete
password"
}
}
# Verify sentinel with updated password managed to connect
(
wait for sentinelTimer to reconnect
)
# Verify sentinel with updated password managed to connect
(
wait for sentinelTimer to reconnect
)
...
@@ -137,8 +137,10 @@ test "Sentinels (re)connection following master ACL change" {
...
@@ -137,8 +137,10 @@ test "Sentinels (re)connection following master ACL change" {
}
}
# Verify sentinel untouched gets failed to connect master
# Verify sentinel untouched gets failed to connect master
if
{
!
[
string match
"*disconnected*"
[
dict get
[
S $sent2un SENTINEL MASTER mymaster
]
flags
]]}
{
wait_for_condition 100 50
{
fail
"Expected: Sentinel to be disconnected from master due to wrong password"
[
string match
"*disconnected*"
[
dict get
[
S $sent2un SENTINEL MASTER mymaster
]
flags
]]
!= 0
}
else
{
fail
"Expected: Sentinel to be disconnected from master due to obsolete password"
}
}
# Now update all sentinels with new password
# Now update all sentinels with new password
...
@@ -167,14 +169,14 @@ test "Set parameters in normal case" {
...
@@ -167,14 +169,14 @@ test "Set parameters in normal case" {
set origin_down_after_milliseconds
[
dict get $info down-after-milliseconds
]
set origin_down_after_milliseconds
[
dict get $info down-after-milliseconds
]
set update_quorum
[
expr $origin_quorum+1
]
set update_quorum
[
expr $origin_quorum+1
]
set update_down_after_milliseconds
[
expr $origin_down_after_milliseconds+1000
]
set update_down_after_milliseconds
[
expr $origin_down_after_milliseconds+1000
]
assert_equal
[
S 0 SENTINEL SET mymaster quorum $update_quorum
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster quorum $update_quorum
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster down-after-milliseconds $update_down_after_milliseconds
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster down-after-milliseconds $update_down_after_milliseconds
]
"OK"
set update_info
[
S 0 SENTINEL master mymaster
]
set update_info
[
S 0 SENTINEL master mymaster
]
assert
{[
dict get $update_info quorum
]
!= $origin_quorum
}
assert
{[
dict get $update_info quorum
]
!= $origin_quorum
}
assert
{[
dict get $update_info down-after-milliseconds
]
!= $origin_down_after_milliseconds
}
assert
{[
dict get $update_info down-after-milliseconds
]
!= $origin_down_after_milliseconds
}
#restore to origin config parameters
#restore to origin config parameters
assert_equal
[
S 0 SENTINEL SET mymaster quorum $origin_quorum
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster quorum $origin_quorum
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster down-after-milliseconds $origin_down_after_milliseconds
]
"OK"
assert_equal
[
S 0 SENTINEL SET mymaster down-after-milliseconds $origin_down_after_milliseconds
]
"OK"
...
...
tests/support/redis.tcl
View file @
76b9c13d
...
@@ -67,6 +67,33 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}} {re
...
@@ -67,6 +67,33 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}} {re
interp alias
{}
::redis::redisHandle$id
{}
::redis::__dispatch__ $id
interp alias
{}
::redis::redisHandle$id
{}
::redis::__dispatch__ $id
}
}
# On recent versions of tcl-tls/OpenSSL, reading from a dropped connection
# results with an error we need to catch and mimic the old behavior.
proc ::redis::redis_safe_read
{
fd len
}
{
if
{
$len
== -1
}
{
set err
[
catch
{
set val
[
read $fd
]}
msg
]
}
else
{
set err
[
catch
{
set val
[
read $fd $len
]}
msg
]
}
if
{
!$err
}
{
return $val
}
if
{[
string match
"*connection abort*"
$msg
]}
{
return
{}
}
error $msg
}
proc ::redis::redis_safe_gets
{
fd
}
{
if
{[
catch
{
set val
[
gets $fd
]}
msg
]}
{
if
{[
string match
"*connection abort*"
$msg
]}
{
return
{}
}
error $msg
}
return $val
}
# This is a wrapper to the actual dispatching procedure that handles
# This is a wrapper to the actual dispatching procedure that handles
# reconnection if needed.
# reconnection if needed.
proc ::redis::__dispatch__
{
id method args
}
{
proc ::redis::__dispatch__
{
id method args
}
{
...
@@ -148,8 +175,8 @@ proc ::redis::__method__read {id fd} {
...
@@ -148,8 +175,8 @@ proc ::redis::__method__read {id fd} {
::redis::redis_read_reply $id $fd
::redis::redis_read_reply $id $fd
}
}
proc ::redis::__method__rawread
{
id fd len
}
{
proc ::redis::__method__rawread
{
id fd
{
len
-1
}
}
{
return
[
read $fd $len
]
return
[
redis_safe_
read $fd $len
]
}
}
proc ::redis::__method__write
{
id fd buf
}
{
proc ::redis::__method__write
{
id fd buf
}
{
...
@@ -207,8 +234,8 @@ proc ::redis::redis_writenl {fd buf} {
...
@@ -207,8 +234,8 @@ proc ::redis::redis_writenl {fd buf} {
}
}
proc ::redis::redis_readnl
{
fd len
}
{
proc ::redis::redis_readnl
{
fd len
}
{
set buf
[
read $fd $len
]
set buf
[
redis_safe_
read $fd $len
]
read $fd 2
;
# discard CR LF
redis_safe_
read $fd 2
;
# discard CR LF
return $buf
return $buf
}
}
...
@@ -254,11 +281,11 @@ proc ::redis::redis_read_map {id fd} {
...
@@ -254,11 +281,11 @@ proc ::redis::redis_read_map {id fd} {
}
}
proc ::redis::redis_read_line fd
{
proc ::redis::redis_read_line fd
{
string trim
[
gets $fd
]
string trim
[
redis_safe_
gets $fd
]
}
}
proc ::redis::redis_read_null fd
{
proc ::redis::redis_read_null fd
{
gets $fd
redis_safe_
gets $fd
return
{}
return
{}
}
}
...
@@ -281,7 +308,7 @@ proc ::redis::redis_read_reply {id fd} {
...
@@ -281,7 +308,7 @@ proc ::redis::redis_read_reply {id fd} {
}
}
while
{
1
}
{
while
{
1
}
{
set type
[
read $fd 1
]
set type
[
redis_safe_
read $fd 1
]
switch -exact -- $type
{
switch -exact -- $type
{
_
{
return
[
redis_read_null $fd
]}
_
{
return
[
redis_read_null $fd
]}
: -
: -
...
...
tests/support/util.tcl
View file @
76b9c13d
...
@@ -72,8 +72,8 @@ proc sanitizer_errors_from_file {filename} {
...
@@ -72,8 +72,8 @@ proc sanitizer_errors_from_file {filename} {
}
}
proc getInfoProperty
{
infostr property
}
{
proc getInfoProperty
{
infostr property
}
{
if
{[
regexp
"
\r\n
$property:
(.*?)
\r\n
"
$infostr _ value
]}
{
if
{[
regexp
-lineanchor
"^
$property:
(.*?)
\r\n
"
$infostr _ value
]}
{
s
et
_
$value
r
et
urn
$value
}
}
}
}
...
...
tests/unit/client-eviction.tcl
View file @
76b9c13d
...
@@ -156,13 +156,13 @@ start_server {} {
...
@@ -156,13 +156,13 @@ start_server {} {
test
"client evicted due to pubsub subscriptions"
{
test
"client evicted due to pubsub subscriptions"
{
r flushdb
r flushdb
# Since pubsub subscriptions cause a small overhea
t
d this test uses a minimal maxmemory-clients config
# Since pubsub subscriptions cause a small overhead this test uses a minimal maxmemory-clients config
set temp_maxmemory_clients 200000
set temp_maxmemory_clients 200000
r config set maxmemory-clients $temp_maxmemory_clients
r config set maxmemory-clients $temp_maxmemory_clients
# Test eviction due to pubsub patterns
# Test eviction due to pubsub patterns
set rr
[
redis_client
]
set rr
[
redis_client
]
# Add patterns until list maxes out maxmem
r
oy clients and causes client eviction
# Add patterns until list maxes out maxmemo
r
y clients and causes client eviction
catch
{
catch
{
for
{
set j 0
}
{
$j
< $temp_maxmemory_clients
}
{
incr j
}
{
for
{
set j 0
}
{
$j
< $temp_maxmemory_clients
}
{
incr j
}
{
$rr psubscribe $j
$rr psubscribe $j
...
@@ -173,7 +173,7 @@ start_server {} {
...
@@ -173,7 +173,7 @@ start_server {} {
# Test eviction due to pubsub channels
# Test eviction due to pubsub channels
set rr
[
redis_client
]
set rr
[
redis_client
]
#
Add pattern
s until list maxes out maxmem
r
oy clients and causes client eviction
#
Subscribe to global channel
s until list maxes out maxmemo
r
y clients and causes client eviction
catch
{
catch
{
for
{
set j 0
}
{
$j
< $temp_maxmemory_clients
}
{
incr j
}
{
for
{
set j 0
}
{
$j
< $temp_maxmemory_clients
}
{
incr j
}
{
$rr subscribe $j
$rr subscribe $j
...
@@ -181,6 +181,17 @@ start_server {} {
...
@@ -181,6 +181,17 @@ start_server {} {
}
e
}
e
assert_match
{
I/O error reading reply
}
$e
assert_match
{
I/O error reading reply
}
$e
$rr close
$rr close
# Test eviction due to sharded pubsub channels
set rr
[
redis_client
]
# Subscribe to sharded pubsub channels until list maxes out maxmemory clients and causes client eviction
catch
{
for
{
set j 0
}
{
$j
< $temp_maxmemory_clients
}
{
incr j
}
{
$rr ssubscribe $j
}
}
e
assert_match
{
I/O error reading reply
}
$e
$rr close
# Restore config for next tests
# Restore config for next tests
r config set maxmemory-clients $maxmemory_clients
r config set maxmemory-clients $maxmemory_clients
...
...
tests/unit/cluster.tcl
View file @
76b9c13d
...
@@ -3,9 +3,7 @@
...
@@ -3,9 +3,7 @@
source tests/support/cli.tcl
source tests/support/cli.tcl
proc cluster_info
{
r field
}
{
proc cluster_info
{
r field
}
{
if
{[
regexp
"^
$field:
(.*?)
\r\n
"
[
$r
cluster info
]
_ value
]}
{
set _
[
getInfoProperty
[
$r
cluster info
]
$field
]
set _ $value
}
}
}
# Provide easy access to CLUSTER INFO properties. Same semantic as
"proc s"
.
# Provide easy access to CLUSTER INFO properties. Same semantic as
"proc s"
.
...
@@ -110,7 +108,7 @@ start_multiple_servers 3 [list overrides $base_conf] {
...
@@ -110,7 +108,7 @@ start_multiple_servers 3 [list overrides $base_conf] {
}
}
$node3_rd close
$node3_rd close
test
"Run blocking command again on cluster node1"
{
test
"Run blocking command again on cluster node1"
{
$node1 del key9184688
$node1 del key9184688
# key9184688 is mapped to slot 10923 which has been moved to node1
# key9184688 is mapped to slot 10923 which has been moved to node1
...
@@ -123,9 +121,9 @@ start_multiple_servers 3 [list overrides $base_conf] {
...
@@ -123,9 +121,9 @@ start_multiple_servers 3 [list overrides $base_conf] {
fail
"Client not blocked"
fail
"Client not blocked"
}
}
}
}
test
"Kill a cluster node and wait for fail state"
{
test
"Kill a cluster node and wait for fail state"
{
# kill node3 in cluster
# kill node3 in cluster
exec kill -SIGSTOP $node3_pid
exec kill -SIGSTOP $node3_pid
wait_for_condition 1000 50
{
wait_for_condition 1000 50
{
...
@@ -135,7 +133,7 @@ start_multiple_servers 3 [list overrides $base_conf] {
...
@@ -135,7 +133,7 @@ start_multiple_servers 3 [list overrides $base_conf] {
fail
"Cluster doesn't fail"
fail
"Cluster doesn't fail"
}
}
}
}
test
"Verify command got unblocked after cluster failure"
{
test
"Verify command got unblocked after cluster failure"
{
assert_error
{
*CLUSTERDOWN*
}
{
$node1
_rd read
}
assert_error
{
*CLUSTERDOWN*
}
{
$node1
_rd read
}
...
@@ -208,7 +206,7 @@ start_multiple_servers 5 [list overrides $base_conf] {
...
@@ -208,7 +206,7 @@ start_multiple_servers 5 [list overrides $base_conf] {
127.0.0.1:
[
srv -4 port
]
\
127.0.0.1:
[
srv -4 port
]
\
127.0.0.1:
[
srv 0 port
]
127.0.0.1:
[
srv 0 port
]
}
e
}
e
assert_match
{
*node already contains functions*
}
$e
assert_match
{
*node already contains functions*
}
$e
}
}
}
;
# stop servers
}
;
# stop servers
...
@@ -315,6 +313,86 @@ test {Migrate the last slot away from a node using redis-cli} {
...
@@ -315,6 +313,86 @@ test {Migrate the last slot away from a node using redis-cli} {
}
}
}
}
# Test redis-cli --cluster create, add-node with cluster-port.
# Create five nodes, three with custom cluster_port and two with default values.
start_server
[
list overrides
[
list cluster-enabled yes cluster-node-timeout 1 cluster-port
[
find_available_port $::baseport $::portcount
]]]
{
start_server
[
list overrides
[
list cluster-enabled yes cluster-node-timeout 1
]]
{
start_server
[
list overrides
[
list cluster-enabled yes cluster-node-timeout 1 cluster-port
[
find_available_port $::baseport $::portcount
]]]
{
start_server
[
list overrides
[
list cluster-enabled yes cluster-node-timeout 1
]]
{
start_server
[
list overrides
[
list cluster-enabled yes cluster-node-timeout 1 cluster-port
[
find_available_port $::baseport $::portcount
]]]
{
# The first three are used to test --cluster create.
# The last two are used to test --cluster add-node
set node1_rd
[
redis_client 0
]
set node2_rd
[
redis_client -1
]
set node3_rd
[
redis_client -2
]
set node4_rd
[
redis_client -3
]
set node5_rd
[
redis_client -4
]
test
{
redis-cli --cluster create with cluster-port
}
{
exec src/redis-cli --cluster-yes --cluster create
\
127.0.0.1:
[
srv 0 port
]
\
127.0.0.1:
[
srv -1 port
]
\
127.0.0.1:
[
srv -2 port
]
wait_for_condition 1000 50
{
[
csi 0 cluster_state
]
eq
{
ok
}
&&
[
csi -1 cluster_state
]
eq
{
ok
}
&&
[
csi -2 cluster_state
]
eq
{
ok
}
}
else
{
fail
"Cluster doesn't stabilize"
}
# Make sure each node can meet other nodes
assert_equal 3
[
csi 0 cluster_known_nodes
]
assert_equal 3
[
csi -1 cluster_known_nodes
]
assert_equal 3
[
csi -2 cluster_known_nodes
]
}
test
{
redis-cli --cluster add-node with cluster-port
}
{
# Adding node to the cluster
(
without cluster-port
)
exec src/redis-cli --cluster-yes --cluster add-node
\
127.0.0.1:
[
srv -3 port
]
\
127.0.0.1:
[
srv 0 port
]
wait_for_condition 1000 50
{
[
csi 0 cluster_state
]
eq
{
ok
}
&&
[
csi -1 cluster_state
]
eq
{
ok
}
&&
[
csi -2 cluster_state
]
eq
{
ok
}
&&
[
csi -3 cluster_state
]
eq
{
ok
}
}
else
{
fail
"Cluster doesn't stabilize"
}
# Adding node to the cluster
(
with cluster-port
)
exec src/redis-cli --cluster-yes --cluster add-node
\
127.0.0.1:
[
srv -4 port
]
\
127.0.0.1:
[
srv 0 port
]
wait_for_condition 1000 50
{
[
csi 0 cluster_state
]
eq
{
ok
}
&&
[
csi -1 cluster_state
]
eq
{
ok
}
&&
[
csi -2 cluster_state
]
eq
{
ok
}
&&
[
csi -3 cluster_state
]
eq
{
ok
}
&&
[
csi -4 cluster_state
]
eq
{
ok
}
}
else
{
fail
"Cluster doesn't stabilize"
}
# Make sure each node can meet other nodes
assert_equal 5
[
csi 0 cluster_known_nodes
]
assert_equal 5
[
csi -1 cluster_known_nodes
]
assert_equal 5
[
csi -2 cluster_known_nodes
]
assert_equal 5
[
csi -3 cluster_known_nodes
]
assert_equal 5
[
csi -4 cluster_known_nodes
]
}
# stop 5 servers
}
}
}
}
}
}
;
# tags
}
;
# tags
set ::singledb $old_singledb
set ::singledb $old_singledb
tests/unit/introspection.tcl
View file @
76b9c13d
...
@@ -7,7 +7,7 @@ start_server {tags {"introspection"}} {
...
@@ -7,7 +7,7 @@ start_server {tags {"introspection"}} {
test
{
CLIENT LIST
}
{
test
{
CLIENT LIST
}
{
r client list
r client list
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=2*
}
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0
ssub=0
multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=2*
}
test
{
CLIENT LIST with IDs
}
{
test
{
CLIENT LIST with IDs
}
{
set myid
[
r client id
]
set myid
[
r client id
]
...
@@ -17,7 +17,7 @@ start_server {tags {"introspection"}} {
...
@@ -17,7 +17,7 @@ start_server {tags {"introspection"}} {
test
{
CLIENT INFO
}
{
test
{
CLIENT INFO
}
{
r client info
r client info
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=2*
}
}
{
id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0
ssub=0
multi=-1 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=2*
}
test
{
CLIENT KILL with illegal arguments
}
{
test
{
CLIENT KILL with illegal arguments
}
{
assert_error
"ERR wrong number of arguments for 'client|kill' command"
{
r client kill
}
assert_error
"ERR wrong number of arguments for 'client|kill' command"
{
r client kill
}
...
@@ -503,6 +503,21 @@ start_server {tags {"introspection"}} {
...
@@ -503,6 +503,21 @@ start_server {tags {"introspection"}} {
assert_match
{
*'replicaof
"--127.0.0.1"
'*wrong number of arguments*
}
$err
assert_match
{
*'replicaof
"--127.0.0.1"
'*wrong number of arguments*
}
$err
}
{}
{
external:skip
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - allow passing option name and option value in the same arg
}
{
start_server
{
config
"default.conf"
args
{
"--maxmemory 700mb"
"--maxmemory-policy volatile-lru"
}}
{
assert_match
[
r config get maxmemory
]
{
maxmemory 734003200
}
assert_match
[
r config get maxmemory-policy
]
{
maxmemory-policy volatile-lru
}
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - wrong usage that we support anyway
}
{
start_server
{
config
"default.conf"
args
{
loglevel verbose
"--maxmemory '700mb'"
"--maxmemory-policy 'volatile-lru'"
}}
{
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
assert_match
[
r config get maxmemory
]
{
maxmemory 734003200
}
assert_match
[
r config get maxmemory-policy
]
{
maxmemory-policy volatile-lru
}
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - allow option value to use the `--` prefix
}
{
test
{
redis-server command line arguments - allow option value to use the `--` prefix
}
{
start_server
{
config
"default.conf"
args
{
--proc-title-template --my--title--template --loglevel verbose
}}
{
start_server
{
config
"default.conf"
args
{
--proc-title-template --my--title--template --loglevel verbose
}}
{
assert_match
[
r config get proc-title-template
]
{
proc-title-template --my--title--template
}
assert_match
[
r config get proc-title-template
]
{
proc-title-template --my--title--template
}
...
@@ -510,15 +525,40 @@ start_server {tags {"introspection"}} {
...
@@ -510,15 +525,40 @@ start_server {tags {"introspection"}} {
}
}
}
{}
{
external:skip
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - option name and option value in the same arg and `--` prefix
}
{
start_server
{
config
"default.conf"
args
{
"--proc-title-template --my--title--template"
"--loglevel verbose"
}}
{
assert_match
[
r config get proc-title-template
]
{
proc-title-template --my--title--template
}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - save with empty input
}
{
test
{
redis-server command line arguments - save with empty input
}
{
# Take `--loglevel` as the save option value.
start_server
{
config
"default.conf"
args
{
--save --loglevel verbose
}}
{
catch
{
exec src/redis-server --save --loglevel verbose
}
err
assert_match
[
r config get save
]
{
save
{}}
assert_match
{
*'save
"--loglevel"
"verbose"
'*Invalid save parameters*
}
$err
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
start_server
{
config
"default.conf"
args
{
--loglevel verbose --save
}}
{
assert_match
[
r config get save
]
{
save
{}}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
start_server
{
config
"default.conf"
args
{
--save
{}
--loglevel verbose
}}
{
start_server
{
config
"default.conf"
args
{
--save
{}
--loglevel verbose
}}
{
assert_match
[
r config get save
]
{
save
{}}
assert_match
[
r config get save
]
{
save
{}}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
}
start_server
{
config
"default.conf"
args
{
--loglevel verbose --save
{}}}
{
assert_match
[
r config get save
]
{
save
{}}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
start_server
{
config
"default.conf"
args
{
--proc-title-template --save --save
{}
--loglevel verbose
}}
{
assert_match
[
r config get proc-title-template
]
{
proc-title-template --save
}
assert_match
[
r config get save
]
{
save
{}}
assert_match
[
r config get loglevel
]
{
loglevel verbose
}
}
}
{}
{
external:skip
}
}
{}
{
external:skip
}
test
{
redis-server command line arguments - take one bulk string with spaces for MULTI_ARG configs parsing
}
{
test
{
redis-server command line arguments - take one bulk string with spaces for MULTI_ARG configs parsing
}
{
...
...
tests/unit/moduleapi/blockedclient.tcl
View file @
76b9c13d
...
@@ -76,6 +76,19 @@ start_server {tags {"modules"}} {
...
@@ -76,6 +76,19 @@ start_server {tags {"modules"}} {
r do_bg_rm_call hgetall hash
r do_bg_rm_call hgetall hash
}
{
foo bar
}
}
{
foo bar
}
test
{
RM_Call from blocked client with script mode
}
{
r do_bg_rm_call_format S hset k foo bar
}
{
1
}
test
{
RM_Call from blocked client with oom mode
}
{
r config set maxmemory 1
# will set server.pre_command_oom_state to 1
assert_error
{
OOM command not allowed*
}
{
r hset hash foo bar
}
r config set maxmemory 0
# now its should be OK to call OOM commands
r do_bg_rm_call_format M hset k1 foo bar
}
{
1
}
{
needs:config-maxmemory
}
test
{
RESP version carries through to blocked client
}
{
test
{
RESP version carries through to blocked client
}
{
for
{
set client_proto 2
}
{
$client
_proto <= 3
}
{
incr client_proto
}
{
for
{
set client_proto 2
}
{
$client
_proto <= 3
}
{
incr client_proto
}
{
r hello $client_proto
r hello $client_proto
...
...
Prev
1
2
3
4
5
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