Skip to content

Commit 48bbfec

Browse files
authored
Add some test cases (#13)
1 parent 198230c commit 48bbfec

File tree

4 files changed

+73
-6
lines changed

4 files changed

+73
-6
lines changed

docs/SEQUENCE_DIAGRAMS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ sequenceDiagram
66
participant Server Shard 1
77
participant Server Shard 2
88
participant Server Shard 3
9-
Note over Client,Server Shard 3: Redis.new(cluster: %w[redis://node1:6379])
10-
Client->>+Server Shard 1: CLUSTER SLOTS
9+
Note over Client,Server Shard 3: RedisClient.cluster(nodes: %w[redis://node1:6379]).new_client
10+
Client->>+Server Shard 1: CLUSTER NODES
1111
Server Shard 1-->>-Client: nodes and slots data
1212
Client->>+Server Shard 1: GET key1
1313
Server Shard 1-->>-Client: value1
@@ -20,5 +20,5 @@ sequenceDiagram
2020
Note over Client,Server Shard 3: Client needs to redirect to correct node
2121
Client->>+Server Shard 2: MGET key2 key3
2222
Server Shard 2-->>-Client: CROSSSLOTS
23-
Note over Client,Server Shard 2: Cannot command across shards
23+
Note over Client,Server Shard 2: Client cannot command across shards
2424
```

lib/redis_client/cluster/command.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Cluster
88
class Command
99
class << self
1010
def load(nodes)
11-
errors = nodes.map do |node|
11+
errors = nodes&.map do |node|
1212
reply = node.call('COMMAND')
1313
details = parse_command_details(reply)
1414
return ::RedisClient::Cluster::Command.new(details)
@@ -36,7 +36,7 @@ def extract_first_key(command)
3636
i = determine_first_key_position(command)
3737
return '' if i == 0
3838

39-
key = command[i].to_s
39+
key = (command[i].is_a?(Array) ? command[i].flatten.first : command[i]).to_s
4040
hash_tag = extract_hash_tag(key)
4141
hash_tag.empty? ? key : hash_tag
4242
end

lib/redis_client/cluster/errors.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Cluster
99
class InitialSetupError < ::RedisClient::Error
1010
# @param errors [Array<Redis::BaseError>]
1111
def initialize(errors)
12-
super("Redis client could not fetch cluster information: #{errors.map(&:message).uniq.join(',')}")
12+
super("Redis client could not fetch cluster information: #{errors&.map(&:message)&.uniq&.join(',')}")
1313
end
1414
end
1515

test/redis_client/cluster/test_command.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,30 @@
44
require 'testing_helper'
55
require 'redis_client/cluster'
66
require 'redis_client/cluster/command'
7+
require 'redis_client/cluster/errors'
78

89
class RedisClient
910
class Cluster
1011
class TestCommand < Minitest::Test
1112
include ::RedisClient::TestingHelper
1213

14+
def test_load
15+
[
16+
{ nodes: @clients, error: nil },
17+
{ nodes: [], error: ::RedisClient::Cluster::InitialSetupError },
18+
{ nodes: [''], error: NoMethodError },
19+
{ nodes: nil, error: ::RedisClient::Cluster::InitialSetupError }
20+
].each_with_index do |c, idx|
21+
msg = "Case: #{idx}"
22+
got = -> { ::RedisClient::Cluster::Command.load(c[:nodes]) }
23+
if c[:error].nil?
24+
assert_instance_of(::RedisClient::Cluster::Command, got.call, msg)
25+
else
26+
assert_raises(c[:error], msg, &got)
27+
end
28+
end
29+
end
30+
1331
def test_parse_command_details
1432
keys = %i[arity flags first last step].freeze
1533
[
@@ -45,6 +63,55 @@ def test_parse_command_details
4563
end
4664
end
4765

66+
def test_extract_first_key
67+
cmd = ::RedisClient::Cluster::Command.load(@clients)
68+
[
69+
{ command: %w[SET foo 1], want: 'foo' },
70+
{ command: %w[GET foo], want: 'foo' },
71+
{ command: %w[GET foo{bar}baz], want: 'bar' },
72+
{ command: %w[MGET foo bar baz], want: 'foo' },
73+
{ command: %w[UNKNOWN foo bar], want: '' },
74+
{ command: [['GET'], 'foo'], want: 'foo' },
75+
{ command: ['GET', ['foo']], want: 'foo' },
76+
{ command: [], want: '' },
77+
{ command: nil, want: '' }
78+
].each_with_index do |c, idx|
79+
msg = "Case: #{idx}"
80+
got = cmd.extract_first_key(c[:command])
81+
assert_equal(c[:want], got, msg)
82+
end
83+
end
84+
85+
def test_should_send_to_primary?
86+
cmd = ::RedisClient::Cluster::Command.load(@clients)
87+
[
88+
{ command: %w[SET foo 1], want: true },
89+
{ command: %w[GET foo], want: false },
90+
{ command: %w[UNKNOWN foo bar], want: nil },
91+
{ command: [], want: nil },
92+
{ command: nil, want: nil }
93+
].each_with_index do |c, idx|
94+
msg = "Case: #{idx}"
95+
got = cmd.should_send_to_primary?(c[:command])
96+
c[:want].nil? ? assert_nil(got, msg) : assert_equal(c[:want], got, msg)
97+
end
98+
end
99+
100+
def test_should_send_to_replica?
101+
cmd = ::RedisClient::Cluster::Command.load(@clients)
102+
[
103+
{ command: %w[SET foo 1], want: false },
104+
{ command: %w[GET foo], want: true },
105+
{ command: %w[UNKNOWN foo bar], want: nil },
106+
{ command: [], want: nil },
107+
{ command: nil, want: nil }
108+
].each_with_index do |c, idx|
109+
msg = "Case: #{idx}"
110+
got = cmd.should_send_to_replica?(c[:command])
111+
c[:want].nil? ? assert_nil(got, msg) : assert_equal(c[:want], got, msg)
112+
end
113+
end
114+
48115
def test_pick_details
49116
keys = %i[first_key_position write readonly].freeze
50117
[

0 commit comments

Comments
 (0)