Cluster test improvements (#10920)

* Restructured testing to allow running cluster tests easily as part of the normal testing
This commit is contained in:
Madelyn Olson 2022-07-12 10:41:29 -07:00 committed by GitHub
parent 8221d48165
commit 8a4e3bcd8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 235 additions and 210 deletions

View File

@ -63,24 +63,6 @@ test "It is possible to write and read from the cluster" {
cluster_write_test 0
}
test "Function no-cluster flag" {
R 1 function load {#!lua name=test
redis.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-cluster'}}
}
catch {R 1 fcall f1 0} e
assert_match {*Can not run script on cluster, 'no-cluster' flag is set*} $e
}
test "Script no-cluster flag" {
catch {
R 1 eval {#!lua flags=no-cluster
return 1
} 0
} 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
@ -92,4 +74,3 @@ test "CLUSTER RESET SOFT test" {
R 1 CLUSTER RESET SOFT
assert {[get_info_field [R 1 cluster info] cluster_current_epoch] eq $last_epoch_node1}
}

View File

@ -0,0 +1,96 @@
# Helper functions specifically for setting up and configuring redis
# clusters.
# Check if cluster configuration is consistent.
proc cluster_config_consistent {} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
if {$j == 0} {
set base_cfg [R $j cluster slots]
} else {
if {[R $j cluster slots] != $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"
}
}
# Check that cluster nodes agree about "state", or raise an error.
proc wait_for_cluster_state {state} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
wait_for_condition 100 50 {
[CI $j cluster_state] eq $state
} else {
fail "Cluster node $j cluster_state:[CI $j cluster_state]"
}
}
}
# Default slot allocation for clusters, each master has a continuous block
# and approximately equal number of slots.
proc continuous_slot_allocation {masters} {
set avg [expr double(16384) / $masters]
set slot_start 0
for {set j 0} {$j < $masters} {incr j} {
set slot_end [expr int(ceil(($j + 1) * $avg) - 1)]
R $j cluster addslotsrange $slot_start $slot_end
set slot_start [expr $slot_end + 1]
}
}
# Setup method to be executed to configure the cluster before the
# tests run.
proc cluster_setup {masters node_count slot_allocator code} {
# Have all nodes meet
for {set i 1} {$i < $node_count} {incr i} {
R 0 CLUSTER MEET [srv -$i host] [srv -$i port]
}
$slot_allocator $masters
wait_for_cluster_propagation
# Setup master/replica relationships
for {set i 0} {$i < $masters} {incr i} {
set nodeid [R $i CLUSTER MYID]
for {set j [expr $i + $masters]} {$j < $node_count} {incr j $masters} {
R $j CLUSTER REPLICATE $nodeid
}
}
wait_for_cluster_propagation
wait_for_cluster_state "ok"
uplevel 1 $code
}
# Start a cluster with the given number of masters and replicas. Replicas
# will be allocated to masters by round robin.
proc start_cluster {masters replicas options code {slot_allocator continuous_slot_allocation}} {
set node_count [expr $masters + $replicas]
# Set the final code to be the tests + cluster setup
set code [list cluster_setup $masters $node_count $slot_allocator $code]
# Configure the starting of multiple servers. Set cluster node timeout
# aggressively since many tests depend on ping/pong messages.
set cluster_options [list overrides [list cluster-enabled yes cluster-node-timeout 500]]
set options [concat $cluster_options $options]
# Cluster mode only supports a single database, so before executing the tests
# it needs to be configured correctly and needs to be reset after the tests.
set old_singledb $::singledb
set ::singledb 1
start_multiple_servers $node_count $options $code
set ::singledb $old_singledb
}

View File

@ -253,12 +253,15 @@ proc tags {tags code} {
# Write the configuration in the dictionary 'config' in the specified
# file name.
proc create_server_config_file {filename config} {
proc create_server_config_file {filename config config_lines} {
set fp [open $filename w+]
foreach directive [dict keys $config] {
puts -nonewline $fp "$directive "
puts $fp [dict get $config $directive]
}
foreach {config_line_directive config_line_args} $config_lines {
puts $fp "$config_line_directive $config_line_args"
}
close $fp
}
@ -406,6 +409,7 @@ proc start_server {options {code undefined}} {
set tags {}
set args {}
set keep_persistence false
set config_lines {}
# parse options
foreach {option value} $options {
@ -416,6 +420,9 @@ proc start_server {options {code undefined}} {
"overrides" {
set overrides $value
}
"config_lines" {
set config_lines $value
}
"args" {
set args $value
}
@ -503,7 +510,7 @@ proc start_server {options {code undefined}} {
# write new configuration to temporary file
set config_file [tmpfile redis.conf]
create_server_config_file $config_file $config
create_server_config_file $config_file $config $config_lines
set stdout [format "%s/%s" [dict get $config "dir"] "stdout"]
set stderr [format "%s/%s" [dict get $config "dir"] "stderr"]
@ -544,7 +551,7 @@ proc start_server {options {code undefined}} {
} else {
dict set config port $port
}
create_server_config_file $config_file $config
create_server_config_file $config_file $config $config_lines
# Truncate log so wait_server_started will not be looking at
# output of the failed server.

View File

@ -77,12 +77,6 @@ proc getInfoProperty {infostr property} {
}
}
proc cluster_info {r field} {
if {[regexp "^$field:(.*?)\r\n" [$r cluster info] _ value]} {
set _ $value
}
}
# Return value for INFO property
proc status {r property} {
set _ [getInfoProperty [{*}$r info] $property]

View File

@ -8,6 +8,7 @@ set tcl_precision 17
source tests/support/redis.tcl
source tests/support/aofmanifest.tcl
source tests/support/server.tcl
source tests/support/cluster_helper.tcl
source tests/support/tmpfile.tcl
source tests/support/test.tcl
source tests/support/util.tcl
@ -90,11 +91,13 @@ set ::all_tests {
unit/oom-score-adj
unit/shutdown
unit/networking
unit/cluster
unit/client-eviction
unit/violations
unit/replybufsize
unit/cluster-scripting
unit/cluster/cli
unit/cluster/scripting
unit/cluster/hostnames
unit/cluster/multi-slot-operations
}
# Index to the next test to run in the ::all_tests list.
set ::next_test 0
@ -197,6 +200,13 @@ proc r {args} {
[srv $level "client"] {*}$args
}
# Provide easy access to a client for an inner server. Requires a positive
# index, unlike r which uses an optional negative index.
proc R {n args} {
set level [expr -1*$n]
[srv $level "client"] {*}$args
}
proc reconnect {args} {
set level [lindex $args 0]
if {[string length $level] == 0 || ![string is integer $level]} {
@ -275,14 +285,9 @@ proc s {args} {
status [srv $level "client"] [lindex $args 0]
}
# Provide easy access to CLUSTER INFO properties. Same semantic as "proc s".
proc csi {args} {
set level 0
if {[string is integer [lindex $args 0]]} {
set level [lindex $args 0]
set args [lrange $args 1 end]
}
cluster_info [srv $level "client"] [lindex $args 0]
# Get the specified field from the givens instances cluster info output.
proc CI {index field} {
getInfoProperty [R $index cluster info] $field
}
# Test wrapped into run_solo are sent back from the client to the

View File

@ -2,20 +2,6 @@
source tests/support/cli.tcl
proc cluster_info {r field} {
set _ [getInfoProperty [$r cluster info] $field]
}
# Provide easy access to CLUSTER INFO properties. Same semantic as "proc s".
proc csi {args} {
set level 0
if {[string is integer [lindex $args 0]]} {
set level [lindex $args 0]
set args [lrange $args 1 end]
}
cluster_info [srv $level "client"] [lindex $args 0]
}
# make sure the test infra won't use SELECT
set old_singledb $::singledb
set ::singledb 1
@ -40,9 +26,9 @@ start_multiple_servers 3 [list overrides $base_conf] {
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -127,8 +113,8 @@ start_multiple_servers 3 [list overrides $base_conf] {
exec kill -SIGSTOP $node3_pid
wait_for_condition 1000 50 {
[csi 0 cluster_state] eq {fail} &&
[csi -1 cluster_state] eq {fail}
[CI 0 cluster_state] eq {fail} &&
[CI 1 cluster_state] eq {fail}
} else {
fail "Cluster doesn't fail"
}
@ -162,9 +148,9 @@ start_multiple_servers 5 [list overrides $base_conf] {
wait_for_condition 1000 50 {
[csi 0 cluster_state] eq {ok} &&
[csi -1 cluster_state] eq {ok} &&
[csi -2 cluster_state] eq {ok}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -181,10 +167,10 @@ start_multiple_servers 5 [list overrides $base_conf] {
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -222,9 +208,9 @@ test {Migrate the last slot away from a node using redis-cli} {
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -239,10 +225,10 @@ test {Migrate the last slot away from a node using redis-cli} {
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -273,10 +259,10 @@ test {Migrate the last slot away from a node using redis-cli} {
[catch {exec src/redis-cli --cluster check 127.0.0.1:[srv -1 port]}] == 0 &&
[catch {exec src/redis-cli --cluster check 127.0.0.1:[srv -2 port]}] == 0 &&
[catch {exec src/redis-cli --cluster check 127.0.0.1:[srv -3 port]}] == 0 &&
[csi 0 cluster_state] eq {ok} &&
[csi -1 cluster_state] eq {ok} &&
[csi -2 cluster_state] eq {ok} &&
[csi -3 cluster_state] eq {ok}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -291,10 +277,10 @@ test {Migrate the last slot away from a node using redis-cli} {
# The empty node will become a replica of the new owner before the
# `MOVED` check, so let's wait for the cluster to become stable.
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -336,17 +322,17 @@ start_server [list overrides [list cluster-enabled yes cluster-node-timeout 1 cl
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 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]
assert_equal 3 [CI 0 cluster_known_nodes]
assert_equal 3 [CI 1 cluster_known_nodes]
assert_equal 3 [CI 2 cluster_known_nodes]
}
test {redis-cli --cluster add-node with cluster-port} {
@ -356,10 +342,10 @@ start_server [list overrides [list cluster-enabled yes cluster-node-timeout 1 cl
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok}
} else {
fail "Cluster doesn't stabilize"
}
@ -370,21 +356,21 @@ start_server [list overrides [list cluster-enabled yes cluster-node-timeout 1 cl
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}
[CI 0 cluster_state] eq {ok} &&
[CI 1 cluster_state] eq {ok} &&
[CI 2 cluster_state] eq {ok} &&
[CI 3 cluster_state] eq {ok} &&
[CI 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]
assert_equal 5 [CI 0 cluster_known_nodes]
assert_equal 5 [CI 1 cluster_known_nodes]
assert_equal 5 [CI 2 cluster_known_nodes]
assert_equal 5 [CI 3 cluster_known_nodes]
assert_equal 5 [CI 4 cluster_known_nodes]
}
# stop 5 servers
}

View File

@ -1,10 +1,8 @@
source "../tests/includes/init-tests.tcl"
# Isolate a node from the cluster and give it a new nodeid
proc isolate_node {id} {
set node_id [R $id CLUSTER MYID]
R 6 CLUSTER RESET HARD
for {set j 0} {$j < 20} {incr j} {
R $id CLUSTER RESET HARD
for {set j 0} {$j < [llength $::servers]} {incr j} {
if { $j eq $id } {
continue
}
@ -12,21 +10,29 @@ proc isolate_node {id} {
}
}
# Check if cluster's view of hostnames is consistent
proc are_hostnames_propagated {match_string} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
set cfg [R $j cluster slots]
foreach node $cfg {
for {set i 2} {$i < [llength $node]} {incr i} {
if {! [string match $match_string [lindex [lindex [lindex $node $i] 3] 1]] } {
return 0
}
}
}
}
return 1
}
proc get_slot_field {slot_output shard_id node_id attrib_id} {
return [lindex [lindex [lindex $slot_output $shard_id] $node_id] $attrib_id]
}
test "Create a 6 nodes cluster" {
cluster_create_with_continuous_slots 3 3
}
test "Cluster should start ok" {
assert_cluster_state ok
wait_for_cluster_propagation
}
# Start a cluster with 3 masters and 4 replicas.
start_cluster 3 4 {tags {external:skip cluster}} {
test "Set cluster hostnames and verify they are propagated" {
for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
R $j config set cluster-announce-hostname "host-$j.com"
}
@ -41,7 +47,7 @@ test "Set cluster hostnames and verify they are propagated" {
}
test "Update hostnames and make sure they are all eventually propagated" {
for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
R $j config set cluster-announce-hostname "host-updated-$j.com"
}
@ -56,7 +62,7 @@ test "Update hostnames and make sure they are all eventually propagated" {
}
test "Remove hostnames and make sure they are all eventually propagated" {
for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} {
for {set j 0} {$j < [llength $::servers]} {incr j} {
R $j config set cluster-announce-hostname ""
}
@ -136,7 +142,7 @@ test "Verify the nodes configured with prefer hostname only show hostname for ne
# Have everyone forget node 6 and isolate it from the cluster.
isolate_node 6
# Set hostnames for the primaries, now that the node is isolated
# Set hostnames for the masters, now that the node is isolated
R 0 config set cluster-announce-hostname "shard-1.com"
R 1 config set cluster-announce-hostname "shard-2.com"
R 2 config set cluster-announce-hostname "shard-3.com"
@ -149,14 +155,14 @@ test "Verify the nodes configured with prefer hostname only show hostname for ne
R 6 DEBUG DROP-CLUSTER-PACKET-FILTER 0
# Have a replica meet the isolated node
R 3 cluster meet 127.0.0.1 [get_instance_attrib redis 6 port]
R 3 cluster meet 127.0.0.1 [srv -6 port]
# Wait for the isolated node to learn about the rest of the cluster,
# which correspond to a single entry in cluster nodes. Note this
# doesn't mean the isolated node has successfully contacted each
# node.
wait_for_condition 50 100 {
[llength [split [R 6 CLUSTER NODES] "\n"]] eq 21
[llength [split [R 6 CLUSTER NODES] "\n"]] eq [expr [llength $::servers] + 1]
} else {
fail "Isolated node didn't learn about the rest of the cluster *"
}
@ -173,10 +179,10 @@ test "Verify the nodes configured with prefer hostname only show hostname for ne
assert_equal [lindex [get_slot_field $slot_result 0 2 3] 1] "shard-2.com"
assert_equal [lindex [get_slot_field $slot_result 1 2 3] 1] "shard-3.com"
# Also make sure we know about the isolated primary, we
# Also make sure we know about the isolated master, we
# just can't reach it.
set primary_id [R 0 CLUSTER MYID]
assert_match "*$primary_id*" [R 6 CLUSTER NODES]
set master_id [R 0 CLUSTER MYID]
assert_match "*$master_id*" [R 6 CLUSTER NODES]
# Stop dropping cluster packets, and make sure everything
# stabilizes
@ -199,8 +205,7 @@ test "Test restart will keep hostname information" {
R 0 config set cluster-announce-hostname "restart-1.com"
# Store the hostname in the config
R 0 config rewrite
kill_instance redis 0
restart_instance redis 0
restart_server 0 true false
set slot_result [R 0 CLUSTER SLOTS]
assert_equal [lindex [get_slot_field $slot_result 0 2 3] 1] "restart-1.com"
@ -216,4 +221,5 @@ test "Test hostname validation" {
# Note this isn't a valid hostname, but it passes our internal validation
R 0 config set cluster-announce-hostname "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."
}
}
}

View File

@ -1,7 +1,4 @@
# Check the multiple slot add and remove commands
source "../tests/includes/init-tests.tcl"
# This test uses a custom slot allocation for testing
proc cluster_allocate_with_continuous_slots_local {n} {
R 0 cluster ADDSLOTSRANGE 0 3276
R 1 cluster ADDSLOTSRANGE 3277 6552
@ -10,28 +7,13 @@ proc cluster_allocate_with_continuous_slots_local {n} {
R 4 cluster ADDSLOTSRANGE 13105 16383
}
proc cluster_create_with_continuous_slots_local {masters slaves} {
cluster_allocate_with_continuous_slots_local $masters
if {$slaves} {
cluster_allocate_slaves $masters $slaves
}
assert_cluster_state ok
}
start_cluster 5 0 {tags {external:skip cluster}} {
test "Create a 5 nodes cluster" {
cluster_create_with_continuous_slots_local 5 5
}
test "Cluster should start ok" {
assert_cluster_state ok
}
set master1 [Rn 0]
set master2 [Rn 1]
set master3 [Rn 2]
set master4 [Rn 3]
set master5 [Rn 4]
set master1 [srv 0 "client"]
set master2 [srv -1 "client"]
set master3 [srv -2 "client"]
set master4 [srv -3 "client"]
set master5 [srv -4 "client"]
test "Continuous slots distribution" {
assert_match "* 0-3276*" [$master1 CLUSTER NODES]
@ -113,3 +95,4 @@ test "DELSLOTSRANGE command with several boundary conditions test suite" {
assert_match "* 9829-11000 12001-12100 12201-13104*" [$master4 CLUSTER NODES]
assert_match "*9829 11000*12001 12100*12201 13104*" [$master4 CLUSTER SLOTS]
}
} cluster_allocate_with_continuous_slots_local

View File

@ -1,14 +1,4 @@
# make sure the test infra won't use SELECT
set old_singledb $::singledb
set ::singledb 1
start_server {overrides {cluster-enabled yes} tags {external:skip cluster}} {
r 0 cluster addslotsrange 0 16383
wait_for_condition 50 100 {
[csi 0 cluster_state] eq "ok"
} else {
fail "Cluster never became 'ok'"
}
start_cluster 1 0 {tags {external:skip cluster}} {
test {Eval scripts with shebangs and functions default to no cross slots} {
# Test that scripts with shebang block cross slot operations
@ -59,6 +49,22 @@ start_server {overrides {cluster-enabled yes} tags {external:skip cluster}} {
return 'OK'
} 1 bar}
}
}
set ::singledb $old_singledb
test "Function no-cluster flag" {
R 0 function load {#!lua name=test
redis.register_function{function_name='f1', callback=function() return 'hello' end, flags={'no-cluster'}}
}
catch {R 0 fcall f1 0} e
assert_match {*Can not run script on cluster, 'no-cluster' flag is set*} $e
}
test "Script no-cluster flag" {
catch {
R 0 eval {#!lua flags=no-cluster
return 1
} 0
} e
assert_match {*Can not run script on cluster, 'no-cluster' flag is set*} $e
}
}

View File

@ -1,59 +1,27 @@
# Primitive tests on cluster-enabled redis with modules using redis-cli
# Primitive tests on cluster-enabled redis with modules
source tests/support/cli.tcl
set testmodule [file normalize tests/modules/blockonkeys.so]
set testmodule_nokey [file normalize tests/modules/blockonbackground.so]
set testmodule_blockedclient [file normalize tests/modules/blockedclient.so]
# make sure the test infra won't use SELECT
set old_singledb $::singledb
set ::singledb 1
# cluster creation is complicated with TLS, and the current tests don't really need that coverage
tags {tls:skip external:skip cluster modules} {
# start three servers
set base_conf [list cluster-enabled yes cluster-node-timeout 1 loadmodule $testmodule]
start_server [list overrides $base_conf] {
start_server [list overrides $base_conf] {
start_server [list overrides $base_conf] {
set testmodule_nokey [file normalize tests/modules/blockonbackground.so]
set testmodule_blockedclient [file normalize tests/modules/blockedclient.so]
set testmodule [file normalize tests/modules/blockonkeys.so]
set modules [list loadmodule $testmodule loadmodule $testmodule_nokey loadmodule $testmodule_blockedclient]
start_cluster 3 0 [list config_lines $modules] {
set node1 [srv 0 client]
set node2 [srv -1 client]
set node3 [srv -2 client]
set node3_pid [srv -2 pid]
# the "overrides" mechanism can only support one "loadmodule" directive
$node1 module load $testmodule_nokey
$node2 module load $testmodule_nokey
$node3 module load $testmodule_nokey
$node1 module load $testmodule_blockedclient
$node2 module load $testmodule_blockedclient
$node3 module load $testmodule_blockedclient
test {Create 3 node cluster} {
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"
}
}
test "Run blocking command (blocked on key) on cluster node3" {
# key9184688 is mapped to slot 10923 (first slot of node 3)
set node3_rd [redis_deferring_client -2]
$node3_rd fsl.bpop key9184688 0
$node3_rd flush
wait_for_condition 50 100 {
[s -2 blocked_clients] eq {1}
} else {
@ -164,8 +132,8 @@ start_server [list overrides $base_conf] {
exec kill -SIGSTOP $node3_pid
wait_for_condition 1000 50 {
[csi 0 cluster_state] eq {fail} &&
[csi -1 cluster_state] eq {fail}
[CI 0 cluster_state] eq {fail} &&
[CI 1 cluster_state] eq {fail}
} else {
fail "Cluster doesn't fail"
}
@ -190,12 +158,5 @@ start_server [list overrides $base_conf] {
exec kill -SIGCONT $node3_pid
$node1_rd close
$node2_rd close
# stop three servers
}
}
}
} ;# tags
set ::singledb $old_singledb