Skip to content

Commit 5124ac5

Browse files
authored
Add some test cases (#26)
1 parent 9b0fbaa commit 5124ac5

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ cli.call('CLUSTER', 'KEYSLOT', 'key3')
8888
#=> 935
8989
```
9090

91+
## ACL
92+
The cluster client internally calls `COMMAND` and `CLUSTER NODES` commands to operate correctly.
93+
So please permit it like the followings.
94+
95+
```ruby
96+
# The default user is administrator.
97+
cli1 = RedisClient.cluster.new_client
98+
99+
# To create a user with permissions
100+
cli1.call('ACL', 'SETUSER', 'foo', 'ON', '+COMMAND', '+CLUSTER|NODES', '+PING', '>mysecret')
101+
102+
# To initialize client with the user
103+
cli2 = RedisClient.cluster(username: 'foo', password: 'mysecret').new_client
104+
105+
# The user can only call the PING command.
106+
cli2.call('PING')
107+
#=> "PONG"
108+
109+
cli2.call('GET', 'key1')
110+
#=> NOPERM this user has no permissions to run the 'get' command (RedisClient::PermissionError)
111+
```
112+
113+
Otherwise:
114+
115+
```ruby
116+
RedisClient.cluster(username: 'foo', password: 'mysecret').new_client
117+
#=> Redis client could not fetch cluster information: NOPERM this user has no permissions to run the 'cluster|nodes' command (RedisClient::Cluster::InitialSetupError)
118+
```
119+
91120
## Connection pooling
92121
TODO
93122

test/redis_client/test_cluster.rb

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ def teardown
2222
end
2323

2424
def wait_for_replication
25-
@client.call('WAIT', '1', (TEST_TIMEOUT_SEC * 1000).to_i.to_s)
25+
@client.call('WAIT', TEST_REPLICA_SIZE, (TEST_TIMEOUT_SEC * 1000).to_i)
2626
end
2727

2828
def test_inspect
2929
assert_match(/^#<RedisClient::Cluster [0-9., :]*>$/, @client.inspect)
3030
end
3131

3232
def test_call
33+
assert_raises(ArgumentError) { @client.call }
3334
(0..9).each do |i|
3435
assert_equal('OK', @client.call('SET', "key#{i}", i), "Case: SET: key#{i}")
3536
wait_for_replication
@@ -38,6 +39,7 @@ def test_call
3839
end
3940

4041
def test_call_once
42+
assert_raises(ArgumentError) { @client.call_once }
4143
(0..9).each do |i|
4244
assert_equal('OK', @client.call_once('SET', "key#{i}", i), "Case: SET: key#{i}")
4345
wait_for_replication
@@ -46,6 +48,7 @@ def test_call_once
4648
end
4749

4850
def test_blocking_call
51+
assert_raises(ArgumentError) { @client.blocking_call(TEST_TIMEOUT_SEC) }
4952
@client.call(*%w[RPUSH foo hello])
5053
@client.call(*%w[RPUSH foo world])
5154
wait_for_replication
@@ -140,6 +143,50 @@ def test_pubsub
140143
def test_close
141144
assert_nil(@client.close)
142145
end
146+
147+
def test_dedicated_commands
148+
(0..9).each { |i| @client.call('SET', "key#{i}", i) }
149+
[
150+
{ command: %w[ACL HELP], is_a: Array },
151+
{ command: %w[WAIT 1 1], want: TEST_NUMBER_OF_REPLICAS },
152+
{ command: %w[KEYS *], want: (0..9).map { |i| "key#{i}" } },
153+
{ command: %w[DBSIZE], want: (0..9).size },
154+
{ command: %w[SCAN], is_a: Array },
155+
{ command: %w[LASTSAVE], is_a: Array },
156+
{ command: %w[ROLE], is_a: Array },
157+
{ command: %w[CONFIG RESETSTAT], want: 'OK' },
158+
{ command: %w[CONFIG GET maxmemory], is_a: Hash },
159+
{ command: %w[CLIENT LIST], is_a: Array },
160+
{ command: %w[CLIENT PAUSE 100], want: 'OK' },
161+
{ command: %w[CLIENT INFO], is_a: String },
162+
{ command: %w[CLUSTER SET-CONFIG-EPOCH 0], error: ::RedisClient::Cluster::OrchestrationCommandNotSupported },
163+
{ command: %w[CLUSTER SAVECONFIG], want: 'OK' },
164+
{ command: %w[CLUSTER NODES], is_a: String },
165+
{ command: %w[READONLY], error: ::RedisClient::Cluster::OrchestrationCommandNotSupported },
166+
{ command: %w[MEMORY STATS], is_a: Array },
167+
{ command: %w[MEMORY PURGE], want: 'OK' },
168+
{ command: %w[MEMORY USAGE key0], is_a: Integer },
169+
{ command: %w[SCRIPT DEBUG NO], want: 'OK' },
170+
{ command: %w[SCRIPT FLUSH], want: 'OK' },
171+
{ command: %w[SCRIPT EXISTS b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c], want: [0] },
172+
{ command: %w[PUBSUB CHANNELS test-channel*], want: [] },
173+
{ command: %w[PUBSUB NUMSUB test-channel], want: { 'test-channel' => 0 } },
174+
{ command: %w[PUBSUB NUMPAT], want: 0 },
175+
{ command: %w[PUBSUB HELP], is_a: Array },
176+
{ command: %w[MULTI], error: ::RedisClient::Cluster::AmbiguousNodeError },
177+
{ command: %w[FLUSHDB], want: 'OK' }
178+
].each do |c|
179+
msg = "Case: #{c[:command].join(' ')}"
180+
got = -> { @client.call(*c[:command]) }
181+
if c.key?(:error)
182+
assert_raises(c[:error], msg, &got)
183+
elsif c.key?(:is_a)
184+
assert_instance_of(c[:is_a], got.call, msg)
185+
else
186+
assert_equal(c[:want], got.call, msg)
187+
end
188+
end
189+
end
143190
end
144191

145192
class PrimaryOnly < Minitest::Test

test/testing_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ module TestingHelper
1111
TEST_REDIS_PORTS = (6379..6384).freeze
1212
TEST_TIMEOUT_SEC = 5.0
1313
TEST_RECONNECT_ATTEMPTS = 3
14+
TEST_REPLICA_SIZE = 1
15+
TEST_NUMBER_OF_REPLICAS = 3
1416
TEST_GENERIC_OPTIONS = { timeout: TEST_TIMEOUT_SEC, reconnect_attempts: TEST_RECONNECT_ATTEMPTS, ssl: TEST_REDIS_SSL }.freeze
1517
TEST_NODE_URIS = TEST_REDIS_PORTS.map { |v| "#{TEST_REDIS_SCHEME}://#{TEST_REDIS_HOST}:#{v}" }.freeze
1618
TEST_NODE_OPTIONS = TEST_REDIS_PORTS.to_h { |v| ["#{TEST_REDIS_HOST}:#{v}", { host: TEST_REDIS_HOST, port: v, ssl: TEST_REDIS_SSL }] }.freeze

0 commit comments

Comments
 (0)