Skip to content

Commit 1967399

Browse files
authored
test: count errors of cluster down (#378)
1 parent 4ee1116 commit 1967399

File tree

5 files changed

+45
-19
lines changed

5 files changed

+45
-19
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ Also, it should handle errors.
442442
* https://redis.io/docs/reference/cluster-spec/
443443
* https://github.com/redis/redis-rb/issues/1070
444444
* https://github.com/redis/redis/issues/8948
445+
* https://github.com/valkey-io/valkey/issues/384
445446
* https://github.com/antirez/redis-rb-cluster
446447
* https://twitter.com/antirez
447448
* http://antirez.com/latest/0

test/test_against_cluster_broken.rb

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
require 'testing_helper'
44

55
class TestAgainstClusterBroken < TestingWrapper
6-
WAIT_SEC = 3
6+
WAIT_SEC = 1
7+
MAX_ATTEMPTS = 60
8+
NUMBER_OF_KEYS = 10
79

810
def setup
911
@captured_commands = ::Middlewares::CommandCapture::CommandBuffer.new
@@ -24,23 +26,26 @@ def setup
2426
)
2527
@captured_commands.clear
2628
@redirect_count.clear
29+
@cluster_down_error_count = 0
2730
end
2831

2932
def teardown
3033
@client&.close
3134
@controller&.close
32-
print "#{@redirect_count.get}, ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')} = "
35+
print "#{@redirect_count.get}, "\
36+
"ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')}, "\
37+
"ClusterDownError: #{@cluster_down_error_count} = "
3338
end
3439

3540
def test_a_replica_is_down
3641
sacrifice = @controller.select_sacrifice_of_replica
37-
do_test_a_node_is_down(sacrifice, number_of_keys: 10)
42+
do_test_a_node_is_down(sacrifice, number_of_keys: NUMBER_OF_KEYS)
3843
refute(@captured_commands.count('cluster', 'nodes').zero?, @captured_commands.to_a.map(&:command))
3944
end
4045

4146
def test_a_primary_is_down
4247
sacrifice = @controller.select_sacrifice_of_primary
43-
do_test_a_node_is_down(sacrifice, number_of_keys: 10)
48+
do_test_a_node_is_down(sacrifice, number_of_keys: NUMBER_OF_KEYS)
4449
refute(@captured_commands.count('cluster', 'nodes').zero?, @captured_commands.to_a.map(&:command))
4550
end
4651

@@ -57,8 +62,8 @@ def wait_for_replication
5762
def do_test_a_node_is_down(sacrifice, number_of_keys:)
5863
prepare_test_data(number_of_keys: number_of_keys)
5964

60-
kill_a_node(sacrifice, kill_attempts: 10)
61-
wait_for_cluster_to_be_ready(wait_attempts: 10)
65+
kill_a_node(sacrifice, kill_attempts: MAX_ATTEMPTS)
66+
wait_for_cluster_to_be_ready(wait_attempts: MAX_ATTEMPTS)
6267

6368
assert_equal('PONG', @client.call('PING'), 'Case: PING')
6469
do_assertions_without_pipelining(number_of_keys: number_of_keys)
@@ -75,15 +80,15 @@ def kill_a_node(sacrifice, kill_attempts:)
7580
refute_nil(sacrifice, "#{sacrifice.config.host}:#{sacrifice.config.port}")
7681

7782
loop do
78-
break if kill_attempts <= 0
83+
raise MaxRetryExceeded if kill_attempts <= 0
7984

85+
kill_attempts -= 1
8086
sacrifice.call('SHUTDOWN', 'NOSAVE')
8187
rescue ::RedisClient::CommandError => e
8288
raise unless e.message.include?('Errors trying to SHUTDOWN')
8389
rescue ::RedisClient::ConnectionError
8490
break
8591
ensure
86-
kill_attempts -= 1
8792
sleep WAIT_SEC
8893
end
8994

@@ -92,11 +97,13 @@ def kill_a_node(sacrifice, kill_attempts:)
9297

9398
def wait_for_cluster_to_be_ready(wait_attempts:)
9499
loop do
95-
break if wait_attempts <= 0 || @client.call('PING') == 'PONG'
100+
raise MaxRetryExceeded if wait_attempts <= 0
101+
102+
wait_attempts -= 1
103+
break if @client.call('PING') == 'PONG'
96104
rescue ::RedisClient::Cluster::NodeMightBeDown
97-
# ignore
105+
@cluster_down_error_count += 1
98106
ensure
99-
wait_attempts -= 1
100107
sleep WAIT_SEC
101108
end
102109
end

test/test_against_cluster_scale.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
require 'testing_helper'
44

55
class TestAgainstClusterScale < TestingWrapper
6+
WAIT_SEC = 1
7+
MAX_ATTEMPTS = 20
68
NUMBER_OF_KEYS = 20_000
79

810
def self.test_order
@@ -23,12 +25,15 @@ def setup
2325
@client.call('echo', 'init')
2426
@captured_commands.clear
2527
@redirect_count.clear
28+
@cluster_down_error_count = 0
2629
end
2730

2831
def teardown
2932
@client&.close
3033
@controller&.close
31-
print "#{@redirect_count.get}, ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')} = "
34+
print "#{@redirect_count.get}, "\
35+
"ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')}, "\
36+
"ClusterDownError: #{@cluster_down_error_count} = "
3237
end
3338

3439
def test_01_scale_out
@@ -57,12 +62,8 @@ def test_02_scale_in
5762
@controller.scale_in
5863

5964
NUMBER_OF_KEYS.times do |i|
60-
assert_equal(i.to_s, @client.call('GET', "key#{i}"), "Case: key#{i}")
61-
rescue ::RedisClient::CommandError => e
62-
raise unless e.message.start_with?('CLUSTERDOWN Hash slot not served')
63-
64-
# FIXME: Why does the error occur?
65-
p "key#{i}"
65+
got = retry_call(attempts: MAX_ATTEMPTS) { @client.call('GET', "key#{i}") }
66+
assert_equal(i.to_s, got, "Case: key#{i}")
6667
end
6768

6869
want = TEST_NODE_URIS.size
@@ -98,4 +99,18 @@ def build_additional_node_urls
9899
max = TEST_REDIS_PORTS.max
99100
(max + 1..max + 2).map { |port| "#{TEST_REDIS_SCHEME}://#{TEST_REDIS_HOST}:#{port}" }
100101
end
102+
103+
def retry_call(attempts:)
104+
loop do
105+
raise MaxRetryExceeded if attempts <= 0
106+
107+
attempts -= 1
108+
break yield
109+
rescue ::RedisClient::CommandError => e
110+
raise unless e.message.start_with?('CLUSTERDOWN Hash slot not served')
111+
112+
@cluster_down_error_count += 1
113+
sleep WAIT_SEC
114+
end
115+
end
101116
end

test/test_against_cluster_state.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ def setup
2525
def teardown
2626
@controller&.close
2727
@client&.close
28-
print "#{@redirect_count.get}, ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')} = "
28+
print "#{@redirect_count.get}, "\
29+
"ClusterNodesCall: #{@captured_commands.count('cluster', 'nodes')} = "
2930
end
3031

3132
def test_the_state_of_cluster_down

test/testing_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
when 'hiredis' then require 'hiredis-client'
1515
end
1616

17+
MaxRetryExceeded = Class.new(StandardError)
18+
1719
class TestingWrapper < Minitest::Test
1820
private
1921

0 commit comments

Comments
 (0)