Commit f5ca1f9e authored by Oran Agra's avatar Oran Agra
Browse files

Merge unstable into 6.2

parents 92bde124 61d3fdb4
......@@ -147,7 +147,7 @@ void tlsInit(void) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OPENSSL_config(NULL);
#else
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG|OPENSSL_INIT_ATFORK, NULL);
#endif
ERR_load_crypto_strings();
SSL_load_error_strings();
......@@ -164,11 +164,43 @@ void tlsInit(void) {
pending_list = listCreate();
}
void tlsCleanup(void) {
if (redis_tls_ctx) {
SSL_CTX_free(redis_tls_ctx);
redis_tls_ctx = NULL;
}
if (redis_tls_client_ctx) {
SSL_CTX_free(redis_tls_client_ctx);
redis_tls_client_ctx = NULL;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
OPENSSL_cleanup();
#endif
}
/* Callback for passing a keyfile password stored as an sds to OpenSSL */
static int tlsPasswordCallback(char *buf, int size, int rwflag, void *u) {
UNUSED(rwflag);
const char *pass = u;
size_t pass_len;
if (!pass) return -1;
pass_len = strlen(pass);
if (pass_len > (size_t) size) return -1;
memcpy(buf, pass, pass_len);
return (int) pass_len;
}
/* Create a *base* SSL_CTX using the SSL configuration provided. The base context
* includes everything that's common for both client-side and server-side connections.
*/
static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocols,
const char *cert_file, const char *key_file) {
static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocols, int client) {
const char *cert_file = client ? ctx_config->client_cert_file : ctx_config->cert_file;
const char *key_file = client ? ctx_config->client_key_file : ctx_config->key_file;
const char *key_file_pass = client ? ctx_config->client_key_file_pass : ctx_config->key_file_pass;
char errbuf[256];
SSL_CTX *ctx = NULL;
......@@ -200,6 +232,9 @@ static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocol
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_default_passwd_cb(ctx, tlsPasswordCallback);
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) key_file_pass);
if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
serverLog(LL_WARNING, "Failed to load certificate: %s: %s", cert_file, errbuf);
......@@ -266,7 +301,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
if (protocols == -1) goto error;
/* Create server side/generla context */
ctx = createSSLContext(ctx_config, protocols, ctx_config->cert_file, ctx_config->key_file);
ctx = createSSLContext(ctx_config, protocols, 0);
if (!ctx) goto error;
if (ctx_config->session_caching) {
......@@ -317,7 +352,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
/* If a client-side certificate is configured, create an explicit client context */
if (ctx_config->client_cert_file && ctx_config->client_key_file) {
client_ctx = createSSLContext(ctx_config, protocols, ctx_config->client_cert_file, ctx_config->client_key_file);
client_ctx = createSSLContext(ctx_config, protocols, 1);
if (!client_ctx) goto error;
}
......@@ -948,6 +983,9 @@ sds connTLSGetPeerCert(connection *conn_) {
void tlsInit(void) {
}
void tlsCleanup(void) {
}
int tlsConfigure(redisTLSContextConfig *ctx_config) {
UNUSED(ctx_config);
return C_OK;
......
......@@ -946,9 +946,10 @@ static void test_ll2string(void) {
}
#define UNUSED(x) (void)(x)
int utilTest(int argc, char **argv) {
int utilTest(int argc, char **argv, int accurate) {
UNUSED(argc);
UNUSED(argv);
UNUSED(accurate);
test_string2ll();
test_string2l();
......
......@@ -66,7 +66,7 @@ long getTimeZone(void);
int pathIsBaseName(char *path);
#ifdef REDIS_TEST
int utilTest(int argc, char **argv);
int utilTest(int argc, char **argv, int accurate);
#endif
#endif
......@@ -1472,7 +1472,7 @@ void ziplistRepr(unsigned char *zl) {
printf("{end}\n\n");
}
/* Validate the integrity of the data stracture.
/* Validate the integrity of the data structure.
* when `deep` is 0, only the integrity of the header is validated.
* when `deep` is 1, we scan all the entries one by one. */
int ziplistValidateIntegrity(unsigned char *zl, size_t size, int deep,
......@@ -1823,15 +1823,17 @@ static size_t strEntryBytesLarge(size_t slen) {
return slen + zipStorePrevEntryLength(NULL, ZIP_BIG_PREVLEN) + zipStoreEntryEncoding(NULL, 0, slen);
}
int ziplistTest(int argc, char **argv) {
/* ./redis-server test ziplist <randomseed> --accurate */
int ziplistTest(int argc, char **argv, int accurate) {
unsigned char *zl, *p;
unsigned char *entry;
unsigned int elen;
long long value;
int iteration;
/* If an argument is given, use it as the random seed. */
if (argc == 2)
srand(atoi(argv[1]));
if (argc >= 4)
srand(atoi(argv[3]));
zl = createIntList();
ziplistRepr(zl);
......@@ -2339,7 +2341,8 @@ int ziplistTest(int argc, char **argv) {
unsigned int slen;
long long sval;
for (i = 0; i < 20000; i++) {
iteration = accurate ? 20000 : 20;
for (i = 0; i < iteration; i++) {
zl = ziplistNew();
ref = listCreate();
listSetFreeMethod(ref,(void (*)(void*))sdsfree);
......@@ -2405,15 +2408,17 @@ int ziplistTest(int argc, char **argv) {
printf("Stress with variable ziplist size:\n");
{
unsigned long long start = usec();
stress(ZIPLIST_HEAD,100000,16384,256);
stress(ZIPLIST_TAIL,100000,16384,256);
int maxsize = accurate ? 16384 : 16;
stress(ZIPLIST_HEAD,100000,maxsize,256);
stress(ZIPLIST_TAIL,100000,maxsize,256);
printf("Done. usec=%lld\n\n", usec()-start);
}
/* Benchmarks */
{
zl = ziplistNew();
for (int i=0; i<100000; i++) {
iteration = accurate ? 100000 : 100;
for (int i=0; i<iteration; i++) {
char buf[4096] = "asdf";
zl = ziplistPush(zl, (unsigned char*)buf, 4, ZIPLIST_TAIL);
zl = ziplistPush(zl, (unsigned char*)buf, 40, ZIPLIST_TAIL);
......@@ -2462,7 +2467,8 @@ int ziplistTest(int argc, char **argv) {
{
char data[ZIP_BIG_PREVLEN];
zl = ziplistNew();
for (int i = 0; i < 100000; i++) {
iteration = accurate ? 100000 : 100;
for (int i = 0; i < iteration; i++) {
zl = ziplistPush(zl, (unsigned char*)data, ZIP_BIG_PREVLEN-4, ZIPLIST_TAIL);
}
unsigned long long start = usec();
......
......@@ -67,7 +67,7 @@ void ziplistRandomPairs(unsigned char *zl, unsigned int count, ziplistEntry *key
unsigned int ziplistRandomPairsUnique(unsigned char *zl, unsigned int count, ziplistEntry *keys, ziplistEntry *vals);
#ifdef REDIS_TEST
int ziplistTest(int argc, char *argv[]);
int ziplistTest(int argc, char *argv[], int accurate);
#endif
#endif /* _ZIPLIST_H */
......@@ -374,7 +374,7 @@ size_t zipmapBlobLen(unsigned char *zm) {
return totlen;
}
/* Validate the integrity of the data stracture.
/* Validate the integrity of the data structure.
* when `deep` is 0, only the integrity of the header is validated.
* when `deep` is 1, we scan all the entries one by one. */
int zipmapValidateIntegrity(unsigned char *zm, size_t size, int deep) {
......@@ -473,11 +473,12 @@ static void zipmapRepr(unsigned char *p) {
}
#define UNUSED(x) (void)(x)
int zipmapTest(int argc, char *argv[]) {
int zipmapTest(int argc, char *argv[], int accurate) {
unsigned char *zm;
UNUSED(argc);
UNUSED(argv);
UNUSED(accurate);
zm = zipmapNew();
......@@ -532,6 +533,7 @@ int zipmapTest(int argc, char *argv[]) {
printf(" %d:%.*s => %d:%.*s\n", klen, klen, key, vlen, vlen, value);
}
}
zfree(zm);
return 0;
}
#endif
......@@ -48,7 +48,7 @@ void zipmapRepr(unsigned char *p);
int zipmapValidateIntegrity(unsigned char *zm, size_t size, int deep);
#ifdef REDIS_TEST
int zipmapTest(int argc, char *argv[]);
int zipmapTest(int argc, char *argv[], int accurate);
#endif
#endif
......@@ -414,9 +414,9 @@ size_t zmalloc_get_rss(void) {
if (sysctl(mib, 4, &info, &infolen, NULL, 0) == 0)
#if defined(__FreeBSD__)
return (size_t)info.ki_rssize;
return (size_t)info.ki_rssize * getpagesize();
#else
return (size_t)info.kp_vm_rssize;
return (size_t)info.kp_vm_rssize * getpagesize();
#endif
return 0L;
......@@ -436,7 +436,7 @@ size_t zmalloc_get_rss(void) {
mib[4] = sizeof(info);
mib[5] = 1;
if (sysctl(mib, 4, &info, &infolen, NULL, 0) == 0)
return (size_t)info.p_vm_rssize;
return (size_t)info.p_vm_rssize * getpagesize();
return 0L;
}
......@@ -613,6 +613,11 @@ size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) {
}
#endif
/* Return the total number bytes in pages marked as Private Dirty.
*
* Note: depending on the platform and memory footprint of the process, this
* call can be slow, exceeding 1000ms!
*/
size_t zmalloc_get_private_dirty(long pid) {
return zmalloc_get_smap_bytes_by_field("Private_Dirty:",pid);
}
......@@ -675,11 +680,12 @@ size_t zmalloc_get_memory_size(void) {
#ifdef REDIS_TEST
#define UNUSED(x) ((void)(x))
int zmalloc_test(int argc, char **argv) {
int zmalloc_test(int argc, char **argv, int accurate) {
void *ptr;
UNUSED(argc);
UNUSED(argv);
UNUSED(accurate);
printf("Malloc prefix size: %d\n", (int) PREFIX_SIZE);
printf("Initial used memory: %zu\n", zmalloc_used_memory());
ptr = zmalloc(123);
......
......@@ -71,12 +71,21 @@
*/
#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#if !defined(NO_MALLOC_USABLE_SIZE) && \
(defined(__GLIBC__) || defined(__FreeBSD__) || \
defined(USE_MALLOC_USABLE_SIZE))
/* Includes for malloc_usable_size() */
#ifdef __FreeBSD__
#include <malloc_np.h>
#else
#include <malloc.h>
#endif
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_usable_size(p)
#endif
#endif
......@@ -126,7 +135,7 @@ size_t zmalloc_usable_size(void *ptr);
#endif
#ifdef REDIS_TEST
int zmalloc_test(int argc, char **argv);
int zmalloc_test(int argc, char **argv, int accurate);
#endif
#endif /* __ZMALLOC_H */
user alice on nopass ~* +@all
user bob on nopass ~* &* +@all
\ No newline at end of file
user alice on allcommands allkeys >alice
user bob on -@all +@set +acl ~set* >bob
user default on nopass ~* +@all
......@@ -4,6 +4,10 @@
# This software is released under the BSD License. See the COPYING file for
# more information.
# Track cluster configuration as created by create_cluster below
set ::cluster_master_nodes 0
set ::cluster_replica_nodes 0
# Returns a parsed CLUSTER NODES output as a list of dictionaries.
proc get_cluster_nodes id {
set lines [split [R $id cluster nodes] "\r\n"]
......@@ -120,6 +124,9 @@ proc create_cluster {masters slaves} {
cluster_allocate_slaves $masters $slaves
}
assert_cluster_state ok
set ::cluster_master_nodes $masters
set ::cluster_replica_nodes $slaves
}
# Set the cluster node-timeout to all the reachalbe nodes.
......@@ -143,3 +150,28 @@ proc cluster_write_test {id} {
}
$cluster close
}
# Check if cluster configuration is consistent.
proc cluster_config_consistent {} {
for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} {
if {$j == 0} {
set base_cfg [R $j cluster slots]
} else {
set cfg [R $j cluster slots]
if {$cfg != $base_cfg} {
return 0
}
}
}
return 1
}
# Wait for cluster configuration to propagate and be consistent across nodes.
proc wait_for_cluster_propagation {} {
wait_for_condition 50 100 {
[cluster_config_consistent] eq 1
} else {
fail "cluster config did not reach a consistent state"
}
}
......@@ -54,7 +54,17 @@ proc process_is_running {pid} {
set numkeys 50000
set numops 200000
set cluster [redis_cluster 127.0.0.1:[get_instance_attrib redis 0 port]]
set start_node_port [get_instance_attrib redis 0 port]
set cluster [redis_cluster 127.0.0.1:$start_node_port]
if {$::tls} {
# setup a non-TLS cluster client to the TLS cluster
set plaintext_port [get_instance_attrib redis 0 plaintext-port]
set cluster_plaintext [redis_cluster 127.0.0.1:$plaintext_port 0]
puts "Testing TLS cluster on start node 127.0.0.1:$start_node_port, plaintext port $plaintext_port"
} else {
set cluster_plaintext $cluster
puts "Testing using non-TLS cluster"
}
catch {unset content}
array set content {}
set tribpid {}
......@@ -94,8 +104,11 @@ test "Cluster consistency during live resharding" {
# This way we are able to stress Lua -> Redis command invocation
# as well, that has tests to prevent Lua to write into wrong
# hash slots.
if {$listid % 2} {
# We also use both TLS and plaintext connections.
if {$listid % 3 == 0} {
$cluster rpush $key $ele
} elseif {$listid % 3 == 1} {
$cluster_plaintext rpush $key $ele
} else {
$cluster eval {redis.call("rpush",KEYS[1],ARGV[1])} 1 $key $ele
}
......
......@@ -29,6 +29,12 @@ test "Each master should have at least two replicas attached" {
}
}
test "Set allow-replica-migration yes" {
foreach_redis_id id {
R $id CONFIG SET cluster-allow-replica-migration yes
}
}
set master0_id [dict get [get_myself 0] id]
test "Resharding all the master #0 slots away from it" {
set output [exec \
......
# Replica migration test #2.
#
# Check that if 'cluster-allow-replica-migration' is set to 'no', slaves do not
# migrate when master becomes empty.
source "../tests/includes/init-tests.tcl"
# Create a cluster with 5 master and 15 slaves, to make sure there are no
# empty masters and make rebalancing simpler to handle during the test.
test "Create a 5 nodes cluster" {
create_cluster 5 15
}
test "Cluster is up" {
assert_cluster_state ok
}
test "Each master should have at least two replicas attached" {
foreach_redis_id id {
if {$id < 5} {
wait_for_condition 1000 50 {
[llength [lindex [R 0 role] 2]] >= 2
} else {
fail "Master #$id does not have 2 slaves as expected"
}
}
}
}
test "Set allow-replica-migration no" {
foreach_redis_id id {
R $id CONFIG SET cluster-allow-replica-migration no
}
}
set master0_id [dict get [get_myself 0] id]
test "Resharding all the master #0 slots away from it" {
set output [exec \
../../../src/redis-cli --cluster rebalance \
127.0.0.1:[get_instance_attrib redis 0 port] \
{*}[rediscli_tls_config "../../../tests"] \
--cluster-weight ${master0_id}=0 >@ stdout ]
}
test "Wait cluster to be stable" {
wait_for_condition 1000 50 {
[catch {exec ../../../src/redis-cli --cluster \
check 127.0.0.1:[get_instance_attrib redis 0 port] \
{*}[rediscli_tls_config "../../../tests"] \
}] == 0
} else {
fail "Cluster doesn't stabilize"
}
}
test "Master #0 stil should have its replicas" {
assert { [llength [lindex [R 0 role] 2]] >= 2 }
}
test "Each master should have at least two replicas attached" {
foreach_redis_id id {
if {$id < 5} {
wait_for_condition 1000 50 {
[llength [lindex [R 0 role] 2]] >= 2
} else {
fail "Master #$id does not have 2 slaves as expected"
}
}
}
}
......@@ -48,3 +48,16 @@ test "client can handle keys with hash tag" {
$cluster set foo{tag} bar
$cluster close
}
if {$::tls} {
test {CLUSTER SLOTS from non-TLS client in TLS cluster} {
set slots_tls [R 0 cluster slots]
set host [get_instance_attrib redis 0 host]
set plaintext_port [get_instance_attrib redis 0 plaintext-port]
set client_plain [redis $host $plaintext_port 0 0]
set slots_plain [$client_plain cluster slots]
$client_plain close
# Compare the ports in the first row
assert_no_match [lindex $slots_tls 0 3 1] [lindex $slots_plain 0 3 1]
}
}
......@@ -36,7 +36,7 @@ test "Right to restore backups when fail to diskless load " {
# Write a key that belongs to slot 0
set slot0_key "06S"
$master set $slot0_key 1
after 100
wait_for_ofs_sync $master $replica
assert_equal {1} [$replica get $slot0_key]
assert_equal $slot0_key [$replica CLUSTER GETKEYSINSLOT 0 1]
......@@ -73,6 +73,13 @@ test "Right to restore backups when fail to diskless load " {
# Kill master, abort full sync
kill_instance redis $master_id
# Start full sync, wait till the replica detects the disconnection
wait_for_condition 500 10 {
[s $replica_id loading] eq 0
} else {
fail "Fail to full sync"
}
# Replica keys and keys to slots map still both are right
assert_equal {1} [$replica get $slot0_key]
assert_equal $slot0_key [$replica CLUSTER GETKEYSINSLOT 0 1]
......
......@@ -37,26 +37,35 @@ set master2 [Rn 1]
test "Continuous slots distribution" {
assert_match "* 0-8191*" [$master1 CLUSTER NODES]
assert_match "* 8192-16383*" [$master2 CLUSTER NODES]
assert_match "*0 8191*" [$master1 CLUSTER SLOTS]
assert_match "*8192 16383*" [$master2 CLUSTER SLOTS]
$master1 CLUSTER DELSLOTS 4096
assert_match "* 0-4095 4097-8191*" [$master1 CLUSTER NODES]
assert_match "*0 4095*4097 8191*" [$master1 CLUSTER SLOTS]
$master2 CLUSTER DELSLOTS 12288
assert_match "* 8192-12287 12289-16383*" [$master2 CLUSTER NODES]
assert_match "*8192 12287*12289 16383*" [$master2 CLUSTER SLOTS]
}
test "Discontinuous slots distribution" {
# Remove middle slots
$master1 CLUSTER DELSLOTS 4092 4094
assert_match "* 0-4091 4093 4095 4097-8191*" [$master1 CLUSTER NODES]
assert_match "*0 4091*4093 4093*4095 4095*4097 8191*" [$master1 CLUSTER SLOTS]
$master2 CLUSTER DELSLOTS 12284 12286
assert_match "* 8192-12283 12285 12287 12289-16383*" [$master2 CLUSTER NODES]
assert_match "*8192 12283*12285 12285*12287 12287*12289 16383*" [$master2 CLUSTER SLOTS]
# Remove head slots
$master1 CLUSTER DELSLOTS 0 2
assert_match "* 1 3-4091 4093 4095 4097-8191*" [$master1 CLUSTER NODES]
assert_match "*1 1*3 4091*4093 4093*4095 4095*4097 8191*" [$master1 CLUSTER SLOTS]
# Remove tail slots
$master2 CLUSTER DELSLOTS 16380 16382 16383
assert_match "* 8192-12283 12285 12287 12289-16379 16381*" [$master2 CLUSTER NODES]
assert_match "*8192 12283*12285 12285*12287 12287*12289 16379*16381 16381*" [$master2 CLUSTER SLOTS]
}
# Tests for fixing migrating slot at all stages:
# 1. when migration is half inited on "migrating" node
# 2. when migration is half inited on "importing" node
# 3. migration inited, but not finished
# 4. migration is half finished on "migrating" node
# 5. migration is half finished on "importing" node
# TODO: Test is currently disabled until it is stabilized (fixing the test
# itself or real issues in Redis).
if {false} {
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}
proc reset_cluster {} {
uplevel 1 {
$cluster refresh_nodes_map
array set nodefrom [$cluster masternode_for_slot 609]
array set nodeto [$cluster masternode_notfor_slot 609]
}
}
reset_cluster
$cluster set aga xyz
test "Half init migration in 'migrating' is fixable" {
assert_equal {OK} [$nodefrom(link) cluster setslot 609 migrating $nodeto(id)]
fix_cluster $nodefrom(addr)
assert_equal "xyz" [$cluster get aga]
}
test "Half init migration in 'importing' is fixable" {
assert_equal {OK} [$nodeto(link) cluster setslot 609 importing $nodefrom(id)]
fix_cluster $nodefrom(addr)
assert_equal "xyz" [$cluster get aga]
}
test "Init migration and move key" {
assert_equal {OK} [$nodefrom(link) cluster setslot 609 migrating $nodeto(id)]
assert_equal {OK} [$nodeto(link) cluster setslot 609 importing $nodefrom(id)]
assert_equal {OK} [$nodefrom(link) migrate $nodeto(host) $nodeto(port) aga 0 10000]
wait_for_cluster_propagation
assert_equal "xyz" [$cluster get aga]
fix_cluster $nodefrom(addr)
assert_equal "xyz" [$cluster get aga]
}
reset_cluster
test "Move key again" {
wait_for_cluster_propagation
assert_equal {OK} [$nodefrom(link) cluster setslot 609 migrating $nodeto(id)]
assert_equal {OK} [$nodeto(link) cluster setslot 609 importing $nodefrom(id)]
assert_equal {OK} [$nodefrom(link) migrate $nodeto(host) $nodeto(port) aga 0 10000]
wait_for_cluster_propagation
assert_equal "xyz" [$cluster get aga]
}
test "Half-finish migration" {
# half finish migration on 'migrating' node
assert_equal {OK} [$nodefrom(link) cluster setslot 609 node $nodeto(id)]
fix_cluster $nodefrom(addr)
assert_equal "xyz" [$cluster get aga]
}
reset_cluster
test "Move key back" {
# 'aga' key is in 609 slot
assert_equal {OK} [$nodefrom(link) cluster setslot 609 migrating $nodeto(id)]
assert_equal {OK} [$nodeto(link) cluster setslot 609 importing $nodefrom(id)]
assert_equal {OK} [$nodefrom(link) migrate $nodeto(host) $nodeto(port) aga 0 10000]
assert_equal "xyz" [$cluster get aga]
}
test "Half-finish importing" {
# Now we half finish 'importing' node
assert_equal {OK} [$nodeto(link) cluster setslot 609 node $nodeto(id)]
fix_cluster $nodefrom(addr)
assert_equal "xyz" [$cluster get aga]
}
config_set_all_nodes cluster-allow-replica-migration yes
}
# Tests for many simlutaneous migrations.
# TODO: Test is currently disabled until it is stabilized (fixing the test
# itself or real issues in Redis).
if {false} {
source "../tests/includes/init-tests.tcl"
source "../tests/includes/utils.tcl"
# TODO: This test currently runs without replicas, as failovers (which may
# happen on lower-end CI platforms) are still not handled properly by the
# cluster during slot migration (related to #6339).
test "Create a 10 nodes cluster" {
create_cluster 10 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" {
for {set i 0} {$i < 40000} {incr i} {
$cluster set key:$i val:$i
}
}
test "Keys are accessible" {
for {set i 0} {$i < 40000} {incr i} {
assert { [$cluster get key:$i] eq "val:$i" }
}
}
test "Init migration of many slots" {
for {set slot 0} {$slot < 1000} {incr slot} {
array set nodefrom [$cluster masternode_for_slot $slot]
array set nodeto [$cluster masternode_notfor_slot $slot]
$nodefrom(link) cluster setslot $slot migrating $nodeto(id)
$nodeto(link) cluster setslot $slot importing $nodefrom(id)
}
}
test "Fix cluster" {
wait_for_cluster_propagation
fix_cluster $nodefrom(addr)
}
test "Keys are accessible" {
for {set i 0} {$i < 40000} {incr i} {
assert { [$cluster get key:$i] eq "val:$i" }
}
}
config_set_all_nodes cluster-allow-replica-migration yes
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment