Skip to content

Commit 8903554

Browse files
authored
Add some test cases (#17)
1 parent f3c46b2 commit 8903554

File tree

3 files changed

+195
-9
lines changed

3 files changed

+195
-9
lines changed

lib/redis_client/cluster/node.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def initialize(scale_read: false, **kwargs)
1818
super(**kwargs)
1919
end
2020

21+
private
22+
2123
def build_connection_prelude
2224
prelude = super.dup
2325
prelude << ['READONLY'] if @scale_read
@@ -27,31 +29,38 @@ def build_connection_prelude
2729

2830
class << self
2931
def load_info(options, **kwargs)
30-
tmp_nodes = ::RedisClient::Cluster::Node.new(options, **kwargs)
32+
startup_nodes = ::RedisClient::Cluster::Node.new(options, **kwargs)
3133

32-
errors = tmp_nodes.map do |tmp_node|
33-
reply = tmp_node.call('CLUSTER', 'NODES')
34+
errors = startup_nodes.map do |n|
35+
reply = n.call('CLUSTER', 'NODES')
3436
return parse_node_info(reply)
3537
rescue ::RedisClient::ConnectionError, ::RedisClient::CommandError => e
3638
e
3739
end
3840

3941
raise ::RedisClient::Cluster::InitialSetupError, errors
4042
ensure
41-
tmp_nodes&.each(&:close)
43+
startup_nodes&.each(&:close)
4244
end
4345

4446
private
4547

4648
# @see https://redis.io/commands/cluster-nodes/
49+
# @see https://github.com/redis/redis/blob/78960ad57b8a5e6af743d789ed8fd767e37d42b8/src/cluster.c#L4660-L4683
4750
def parse_node_info(info) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
4851
rows = info.split("\n").map(&:split)
4952
rows.each { |arr| arr[2] = arr[2].split(',') }
5053
rows.select! { |arr| arr[7] == 'connected' && (arr[2] & %w[fail? fail handshake noaddr noflags]).empty? }
5154
rows.each do |arr|
5255
arr[1] = arr[1].split('@').first
5356
arr[2] = (arr[2] & %w[master slave]).first
54-
arr[8] = arr[8].nil? ? [] : arr[8].split(',').map { |r| r.split('-').map { |s| Integer(s) } }
57+
if arr[8].nil?
58+
arr[8] = []
59+
next
60+
end
61+
62+
arr[8] = arr[8].split(',').map { |r| r.split('-').map { |s| Integer(s) } }
63+
arr[8] = arr[8].map { |a| a.size == 1 ? a << a.first : a }.map(&:sort)
5564
end
5665

5766
rows.map do |arr|
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# frozen_string_literal: true
2+
3+
require 'uri'
4+
require 'testing_helper'
5+
require 'redis_client/cluster/node'
6+
7+
class RedisClient
8+
class Cluster
9+
class Node
10+
class TestConfig < Minitest::Test
11+
def test_connection_prelude
12+
[
13+
{ params: { scale_read: true }, want: [%w[HELLO 3], %w[READONLY]] },
14+
{ params: { scale_read: false }, want: [%w[HELLO 3]] },
15+
{ params: {}, want: [%w[HELLO 3]] }
16+
].each_with_index do |c, idx|
17+
got = ::RedisClient::Cluster::Node::Config.new(**c[:params]).connection_prelude
18+
assert_equal(c[:want], got, "Case: #{idx}")
19+
end
20+
end
21+
end
22+
end
23+
24+
class TestNode < Minitest::Test
25+
def test_load_info
26+
[
27+
{ params: { options: TEST_NODE_OPTIONS, kwargs: {} }, want: { size: TEST_NODE_OPTIONS.size } },
28+
{ params: { options: { '127.0.0.1:11211' => { host: '127.0.0.1', port: 11_211 } }, kwargs: {} }, want: { error: ::RedisClient::Cluster::InitialSetupError } },
29+
{ params: { options: {}, kwargs: {} }, want: { error: ::RedisClient::Cluster::InitialSetupError } }
30+
].each_with_index do |c, idx|
31+
msg = "Case: #{idx}"
32+
got = -> { ::RedisClient::Cluster::Node.load_info(c[:params][:options], **c[:params][:kwargs]) }
33+
if c[:want].key?(:error)
34+
assert_raises(c[:want][:error], msg, &got)
35+
else
36+
assert_equal(c[:want][:size], got.call.size, msg)
37+
end
38+
end
39+
end
40+
41+
def test_parse_node_info
42+
info = <<~INFO
43+
07c37dfeb235213a872192d90877d0cd55635b91 127.0.0.1:30004@31004 slave e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 0 1426238317239 4 connected
44+
67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 127.0.0.1:30002@31002 master - 0 1426238316232 2 connected 5461-10922
45+
292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 127.0.0.1:30003@31003 master - 0 1426238318243 3 connected 10923-16383
46+
6ec23923021cf3ffec47632106199cb7f496ce01 127.0.0.1:30005@31005 slave 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 0 1426238316232 5 connected
47+
824fe116063bc5fcf9f4ffd895bc17aee7731ac3 127.0.0.1:30006@31006 slave 292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 0 1426238317741 6 connected
48+
e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 127.0.0.1:30001@31001 myself,master - 0 0 1 connected 0-5460
49+
INFO
50+
51+
want = [
52+
{ id: '07c37dfeb235213a872192d90877d0cd55635b91', node_key: '127.0.0.1:30004', role: 'slave',
53+
primary_id: 'e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca', ping_sent: '0', pong_recv: '1426238317239',
54+
config_epoch: '4', link_state: 'connected', slots: [] },
55+
{ id: '67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1', node_key: '127.0.0.1:30002', role: 'master',
56+
primary_id: '-', ping_sent: '0', pong_recv: '1426238316232',
57+
config_epoch: '2', link_state: 'connected', slots: [[5461, 10_922]] },
58+
{ id: '292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f', node_key: '127.0.0.1:30003', role: 'master',
59+
primary_id: '-', ping_sent: '0', pong_recv: '1426238318243',
60+
config_epoch: '3', link_state: 'connected', slots: [[10_923, 16_383]] },
61+
{ id: '6ec23923021cf3ffec47632106199cb7f496ce01', node_key: '127.0.0.1:30005', role: 'slave',
62+
primary_id: '67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1', ping_sent: '0', pong_recv: '1426238316232',
63+
config_epoch: '5', link_state: 'connected', slots: [] },
64+
{ id: '824fe116063bc5fcf9f4ffd895bc17aee7731ac3', node_key: '127.0.0.1:30006', role: 'slave',
65+
primary_id: '292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f', ping_sent: '0', pong_recv: '1426238317741',
66+
config_epoch: '6', link_state: 'connected', slots: [] },
67+
{ id: 'e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca', node_key: '127.0.0.1:30001', role: 'master',
68+
primary_id: '-', ping_sent: '0', pong_recv: '0', config_epoch: '1', link_state: 'connected', slots: [[0, 5460]] }
69+
]
70+
71+
assert_equal(want, ::RedisClient::Cluster::Node.send(:parse_node_info, info), 'Case: success: continuous slots')
72+
73+
info = <<~INFO
74+
07c37dfeb235213a872192d90877d0cd55635b91 127.0.0.1:30004@31004 slave e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 0 1426238317239 4 connected
75+
67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 127.0.0.1:30002@31002 master - 0 1426238316232 2 connected 3001,5461-7000,7002-10922
76+
292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 127.0.0.1:30003@31003 master - 0 1426238318243 3 connected 7001,10923-15000,15002-16383
77+
6ec23923021cf3ffec47632106199cb7f496ce01 127.0.0.1:30005@31005 slave 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 0 1426238316232 5 connected
78+
824fe116063bc5fcf9f4ffd895bc17aee7731ac3 127.0.0.1:30006@31006 slave 292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 0 1426238317741 6 connected
79+
e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 127.0.0.1:30001@31001 myself,master - 0 0 1 connected 0-3000,3002-5460,15001
80+
INFO
81+
82+
want = [
83+
{ id: '07c37dfeb235213a872192d90877d0cd55635b91', node_key: '127.0.0.1:30004', role: 'slave',
84+
primary_id: 'e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca', ping_sent: '0', pong_recv: '1426238317239',
85+
config_epoch: '4', link_state: 'connected', slots: [] },
86+
{ id: '67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1', node_key: '127.0.0.1:30002', role: 'master',
87+
primary_id: '-', ping_sent: '0', pong_recv: '1426238316232',
88+
config_epoch: '2', link_state: 'connected', slots: [[3001, 3001], [5461, 7000], [7002, 10_922]] },
89+
{ id: '292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f', node_key: '127.0.0.1:30003', role: 'master',
90+
primary_id: '-', ping_sent: '0', pong_recv: '1426238318243',
91+
config_epoch: '3', link_state: 'connected', slots: [[7001, 7001], [10_923, 15_000], [15_002, 16_383]] },
92+
{ id: '6ec23923021cf3ffec47632106199cb7f496ce01', node_key: '127.0.0.1:30005', role: 'slave',
93+
primary_id: '67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1', ping_sent: '0', pong_recv: '1426238316232',
94+
config_epoch: '5', link_state: 'connected', slots: [] },
95+
{ id: '824fe116063bc5fcf9f4ffd895bc17aee7731ac3', node_key: '127.0.0.1:30006', role: 'slave',
96+
primary_id: '292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f', ping_sent: '0', pong_recv: '1426238317741',
97+
config_epoch: '6', link_state: 'connected', slots: [] },
98+
{ id: 'e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca', node_key: '127.0.0.1:30001', role: 'master',
99+
primary_id: '-', ping_sent: '0', pong_recv: '0', config_epoch: '1', link_state: 'connected', slots: [[0, 3000], [3002, 5460], [15_001, 15_001]] }
100+
]
101+
102+
assert_equal(want, ::RedisClient::Cluster::Node.send(:parse_node_info, info), 'Case: success: discrete slots')
103+
104+
info = <<~INFO
105+
07c37dfeb235213a872192d90877d0cd55635b91 127.0.0.1:30004@31004 slave e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 0 1426238317239 4 disconnected
106+
67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 127.0.0.1:30002@31002 master - 0 1426238316232 2 disconnected 5461-10922
107+
292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 127.0.0.1:30003@31003 master - 0 1426238318243 3 disconnected 10923-16383
108+
6ec23923021cf3ffec47632106199cb7f496ce01 127.0.0.1:30005@31005 slave 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 0 1426238316232 5 disconnected
109+
824fe116063bc5fcf9f4ffd895bc17aee7731ac3 127.0.0.1:30006@31006 slave 292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 0 1426238317741 6 disconnected
110+
e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 127.0.0.1:30001@31001 myself,master - 0 0 1 disconnected 0-5460
111+
INFO
112+
113+
assert_empty(::RedisClient::Cluster::Node.send(:parse_node_info, info), 'Case: failure: link state')
114+
115+
info = <<~INFO
116+
07c37dfeb235213a872192d90877d0cd55635b91 127.0.0.1:30004@31004 fail?,slave e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 0 1426238317239 4 connected
117+
67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 127.0.0.1:30002@31002 fail,master - 0 1426238316232 2 connected 5461-10922
118+
292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 127.0.0.1:30003@31003 master,handshake - 0 1426238318243 3 connected 10923-16383
119+
6ec23923021cf3ffec47632106199cb7f496ce01 127.0.0.1:30005@31005 noaddr,slave 67ed2db8d677e59ec4a4cefb06858cf2a1a89fa1 0 1426238316232 5 connected
120+
824fe116063bc5fcf9f4ffd895bc17aee7731ac3 127.0.0.1:30006@31006 noflags 292f8b365bb7edb5e285caf0b7e6ddc7265d2f4f 0 1426238317741 6 connected
121+
e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 127.0.0.1:30001@31001 myself,fail,master - 0 0 1 connected 0-5460
122+
INFO
123+
124+
assert_empty(::RedisClient::Cluster::Node.send(:parse_node_info, info), 'Case: failure: flags')
125+
end
126+
127+
def test_inspect
128+
skip('TODO')
129+
end
130+
131+
def test_enumerable
132+
skip('TODO')
133+
end
134+
135+
def test_find_by
136+
skip('TODO')
137+
end
138+
139+
def test_call_all
140+
skip('TODO')
141+
end
142+
143+
def test_call_primary
144+
skip('TODO')
145+
end
146+
147+
def test_call_replica
148+
skip('TODO')
149+
end
150+
151+
def test_scale_reading_clients
152+
skip('TODO')
153+
end
154+
155+
def test_slot_exists?
156+
skip('TODO')
157+
end
158+
159+
def test_find_node_key_of_primary
160+
skip('TODO')
161+
end
162+
163+
def test_find_node_key_of_replica
164+
skip('TODO')
165+
end
166+
167+
def test_update_slot
168+
skip('TODO')
169+
end
170+
end
171+
end
172+
end

test/testing_helper.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
require 'redis_client'
55

66
class RedisClient
7-
module TestingHelper
8-
REDIS_SCHEME = ENV.fetch('REDIS_SCHEME', 'redis')
9-
NODE_ADDRS = (6379..6384).map { |port| "#{REDIS_SCHEME}://127.0.0.1:#{port}" }.freeze
7+
TEST_REDIS_SCHEME = ENV.fetch('REDIS_SCHEME', 'redis')
8+
TEST_REDIS_SSL = TEST_REDIS_SCHEME == 'rediss'
9+
TEST_REDIS_HOST = '127.0.0.1'
10+
TEST_REDIS_PORTS = (6379..6384).freeze
11+
TEST_NODE_URIS = TEST_REDIS_PORTS.map { |port| "#{TEST_REDIS_SCHEME}://#{TEST_REDIS_HOST}:#{port}" }.freeze
12+
TEST_NODE_OPTIONS = TEST_REDIS_PORTS.to_h { |port| ["#{TEST_REDIS_HOST}:#{port}", { host: TEST_REDIS_HOST, port: port }] }
13+
.transform_values { |v| TEST_REDIS_SSL ? v.merge(ssl: true) : v }.freeze
1014

15+
module TestingHelper
1116
def setup
12-
@raw_clients = NODE_ADDRS.map { |addr| ::RedisClient.config(url: addr).new_client }
17+
@raw_clients = TEST_NODE_URIS.map { |addr| ::RedisClient.config(url: addr).new_client }
1318
end
1419

1520
def teardown

0 commit comments

Comments
 (0)