redis 4.0.2 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +6 -0
  5. data/lib/redis.rb +97 -11
  6. data/lib/redis/client.rb +19 -11
  7. data/lib/redis/cluster.rb +285 -0
  8. data/lib/redis/cluster/command.rb +81 -0
  9. data/lib/redis/cluster/command_loader.rb +32 -0
  10. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  11. data/lib/redis/cluster/node.rb +104 -0
  12. data/lib/redis/cluster/node_key.rb +35 -0
  13. data/lib/redis/cluster/node_loader.rb +35 -0
  14. data/lib/redis/cluster/option.rb +76 -0
  15. data/lib/redis/cluster/slot.rb +69 -0
  16. data/lib/redis/cluster/slot_loader.rb +47 -0
  17. data/lib/redis/errors.rb +46 -0
  18. data/lib/redis/version.rb +1 -1
  19. data/makefile +54 -16
  20. data/redis.gemspec +2 -1
  21. data/test/client_test.rb +17 -0
  22. data/test/cluster_abnormal_state_test.rb +38 -0
  23. data/test/cluster_blocking_commands_test.rb +15 -0
  24. data/test/cluster_client_internals_test.rb +77 -0
  25. data/test/cluster_client_key_hash_tags_test.rb +88 -0
  26. data/test/cluster_client_options_test.rb +147 -0
  27. data/test/cluster_client_pipelining_test.rb +59 -0
  28. data/test/cluster_client_replicas_test.rb +36 -0
  29. data/test/cluster_client_slots_test.rb +94 -0
  30. data/test/cluster_client_transactions_test.rb +71 -0
  31. data/test/cluster_commands_on_cluster_test.rb +165 -0
  32. data/test/cluster_commands_on_connection_test.rb +40 -0
  33. data/test/cluster_commands_on_geo_test.rb +74 -0
  34. data/test/cluster_commands_on_hashes_test.rb +11 -0
  35. data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
  36. data/test/cluster_commands_on_keys_test.rb +134 -0
  37. data/test/cluster_commands_on_lists_test.rb +15 -0
  38. data/test/cluster_commands_on_pub_sub_test.rb +101 -0
  39. data/test/cluster_commands_on_scripting_test.rb +56 -0
  40. data/test/cluster_commands_on_server_test.rb +221 -0
  41. data/test/cluster_commands_on_sets_test.rb +39 -0
  42. data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
  43. data/test/cluster_commands_on_streams_test.rb +196 -0
  44. data/test/cluster_commands_on_strings_test.rb +15 -0
  45. data/test/cluster_commands_on_transactions_test.rb +41 -0
  46. data/test/cluster_commands_on_value_types_test.rb +14 -0
  47. data/test/commands_on_hashes_test.rb +2 -14
  48. data/test/commands_on_hyper_log_log_test.rb +2 -14
  49. data/test/commands_on_lists_test.rb +2 -13
  50. data/test/commands_on_sets_test.rb +2 -70
  51. data/test/commands_on_sorted_sets_test.rb +2 -145
  52. data/test/commands_on_strings_test.rb +2 -94
  53. data/test/distributed_blocking_commands_test.rb +8 -0
  54. data/test/distributed_commands_on_hashes_test.rb +16 -3
  55. data/test/distributed_commands_on_hyper_log_log_test.rb +8 -13
  56. data/test/distributed_commands_on_lists_test.rb +4 -5
  57. data/test/distributed_commands_on_sets_test.rb +45 -46
  58. data/test/distributed_commands_on_sorted_sets_test.rb +51 -8
  59. data/test/distributed_commands_on_strings_test.rb +10 -0
  60. data/test/helper.rb +176 -32
  61. data/test/internals_test.rb +13 -0
  62. data/test/lint/blocking_commands.rb +40 -16
  63. data/test/lint/hashes.rb +26 -0
  64. data/test/lint/hyper_log_log.rb +15 -1
  65. data/test/lint/lists.rb +16 -0
  66. data/test/lint/sets.rb +142 -0
  67. data/test/lint/sorted_sets.rb +183 -2
  68. data/test/lint/strings.rb +102 -0
  69. data/test/support/cluster/orchestrator.rb +199 -0
  70. metadata +79 -4
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_client_options_test.rb
6
+ class TestClusterClientOptions < Test::Unit::TestCase
7
+ include Helper::Cluster
8
+
9
+ def test_option_class
10
+ option = Redis::Cluster::Option.new(cluster: %w[rediss://127.0.0.1:7000], replica: true)
11
+ assert_equal({ '127.0.0.1:7000' => { url: 'rediss://127.0.0.1:7000' } }, option.per_node_key)
12
+ assert_equal true, option.secure?
13
+ assert_equal true, option.use_replica?
14
+
15
+ option = Redis::Cluster::Option.new(cluster: %w[redis://127.0.0.1:7000], replica: false)
16
+ assert_equal({ '127.0.0.1:7000' => { url: 'redis://127.0.0.1:7000' } }, option.per_node_key)
17
+ assert_equal false, option.secure?
18
+ assert_equal false, option.use_replica?
19
+
20
+ option = Redis::Cluster::Option.new(cluster: %w[redis://127.0.0.1:7000])
21
+ assert_equal({ '127.0.0.1:7000' => { url: 'redis://127.0.0.1:7000' } }, option.per_node_key)
22
+ assert_equal false, option.secure?
23
+ assert_equal false, option.use_replica?
24
+ end
25
+
26
+ def test_client_accepts_valid_node_configs
27
+ nodes = ['redis://127.0.0.1:7000',
28
+ 'redis://127.0.0.1:7001',
29
+ { host: '127.0.0.1', port: '7002' },
30
+ { 'host' => '127.0.0.1', port: 7003 },
31
+ 'redis://127.0.0.1:7004',
32
+ 'redis://127.0.0.1:7005']
33
+
34
+ assert_nothing_raised do
35
+ build_another_client(cluster: nodes)
36
+ end
37
+ end
38
+
39
+ def test_client_accepts_valid_options
40
+ assert_nothing_raised do
41
+ build_another_client(timeout: 1.0)
42
+ end
43
+ end
44
+
45
+ def test_client_ignores_invalid_options
46
+ assert_nothing_raised do
47
+ build_another_client(invalid_option: true)
48
+ end
49
+ end
50
+
51
+ def test_client_works_even_if_so_many_unavailable_nodes_specified
52
+ nodes = (6001..7005).map { |port| "redis://127.0.0.1:#{port}" }
53
+ redis = build_another_client(cluster: nodes)
54
+
55
+ assert_equal 'PONG', redis.ping
56
+ end
57
+
58
+ def test_client_does_not_accept_db_specified_url
59
+ assert_raise(Redis::CannotConnectError, 'Could not connect to any nodes') do
60
+ build_another_client(cluster: ['redis://127.0.0.1:7000/1/namespace'])
61
+ end
62
+
63
+ assert_raise(Redis::CannotConnectError, 'Could not connect to any nodes') do
64
+ build_another_client(cluster: [{ host: '127.0.0.1', port: '7000' }], db: 1)
65
+ end
66
+ end
67
+
68
+ def test_client_does_not_accept_unconnectable_node_url_only
69
+ nodes = ['redis://127.0.0.1:7006']
70
+
71
+ assert_raise(Redis::CannotConnectError, 'Could not connect to any nodes') do
72
+ build_another_client(cluster: nodes)
73
+ end
74
+ end
75
+
76
+ def test_client_accepts_unconnectable_node_url_included
77
+ nodes = ['redis://127.0.0.1:7000', 'redis://127.0.0.1:7006']
78
+
79
+ assert_nothing_raised(Redis::CannotConnectError, 'Could not connect to any nodes') do
80
+ build_another_client(cluster: nodes)
81
+ end
82
+ end
83
+
84
+ def test_client_does_not_accept_http_scheme_url
85
+ nodes = ['http://127.0.0.1:80']
86
+
87
+ assert_raise(Redis::InvalidClientOptionError, "invalid uri scheme 'http'") do
88
+ build_another_client(cluster: nodes)
89
+ end
90
+ end
91
+
92
+ def test_client_does_not_accept_blank_included_config
93
+ nodes = ['']
94
+
95
+ assert_raise(Redis::InvalidClientOptionError, "invalid uri scheme ''") do
96
+ build_another_client(cluster: nodes)
97
+ end
98
+ end
99
+
100
+ def test_client_does_not_accept_bool_included_config
101
+ nodes = [true]
102
+
103
+ assert_raise(Redis::InvalidClientOptionError, "invalid uri scheme ''") do
104
+ build_another_client(cluster: nodes)
105
+ end
106
+ end
107
+
108
+ def test_client_does_not_accept_nil_included_config
109
+ nodes = [nil]
110
+
111
+ assert_raise(Redis::InvalidClientOptionError, "invalid uri scheme ''") do
112
+ build_another_client(cluster: nodes)
113
+ end
114
+ end
115
+
116
+ def test_client_does_not_accept_array_included_config
117
+ nodes = [[]]
118
+
119
+ assert_raise(Redis::InvalidClientOptionError, "invalid uri scheme ''") do
120
+ build_another_client(cluster: nodes)
121
+ end
122
+ end
123
+
124
+ def test_client_does_not_accept_empty_hash_included_config
125
+ nodes = [{}]
126
+
127
+ assert_raise(Redis::InvalidClientOptionError, 'Redis option of `cluster` must includes `:host` and `:port` keys') do
128
+ build_another_client(cluster: nodes)
129
+ end
130
+ end
131
+
132
+ def test_client_does_not_accept_object_included_config
133
+ nodes = [Object.new]
134
+
135
+ assert_raise(Redis::InvalidClientOptionError, 'Redis Cluster node config must includes String or Hash') do
136
+ build_another_client(cluster: nodes)
137
+ end
138
+ end
139
+
140
+ def test_client_does_not_accept_not_array_config
141
+ nodes = :not_array
142
+
143
+ assert_raise(Redis::InvalidClientOptionError, 'Redis Cluster node config must be Array') do
144
+ build_another_client(cluster: nodes)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_client_pipelining_test.rb
6
+ class TestClusterClientPipelining < Test::Unit::TestCase
7
+ include Helper::Cluster
8
+
9
+ def test_pipelining_with_a_hash_tag
10
+ p1 = p2 = p3 = p4 = p5 = p6 = nil
11
+
12
+ redis.pipelined do |r|
13
+ r.set('{Presidents.of.USA}:1', 'George Washington')
14
+ r.set('{Presidents.of.USA}:2', 'John Adams')
15
+ r.set('{Presidents.of.USA}:3', 'Thomas Jefferson')
16
+ r.set('{Presidents.of.USA}:4', 'James Madison')
17
+ r.set('{Presidents.of.USA}:5', 'James Monroe')
18
+ r.set('{Presidents.of.USA}:6', 'John Quincy Adams')
19
+
20
+ p1 = r.get('{Presidents.of.USA}:1')
21
+ p2 = r.get('{Presidents.of.USA}:2')
22
+ p3 = r.get('{Presidents.of.USA}:3')
23
+ p4 = r.get('{Presidents.of.USA}:4')
24
+ p5 = r.get('{Presidents.of.USA}:5')
25
+ p6 = r.get('{Presidents.of.USA}:6')
26
+ end
27
+
28
+ [p1, p2, p3, p4, p5, p6].each do |actual|
29
+ assert_true actual.is_a?(Redis::Future)
30
+ end
31
+
32
+ assert_equal('George Washington', p1.value)
33
+ assert_equal('John Adams', p2.value)
34
+ assert_equal('Thomas Jefferson', p3.value)
35
+ assert_equal('James Madison', p4.value)
36
+ assert_equal('James Monroe', p5.value)
37
+ assert_equal('John Quincy Adams', p6.value)
38
+ end
39
+
40
+ def test_pipelining_without_hash_tags
41
+ assert_raise(Redis::Cluster::CrossSlotPipeliningError) do
42
+ redis.pipelined do
43
+ redis.set(:a, 1)
44
+ redis.set(:b, 2)
45
+ redis.set(:c, 3)
46
+ redis.set(:d, 4)
47
+ redis.set(:e, 5)
48
+ redis.set(:f, 6)
49
+
50
+ redis.get(:a)
51
+ redis.get(:b)
52
+ redis.get(:c)
53
+ redis.get(:d)
54
+ redis.get(:e)
55
+ redis.get(:f)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_client_replicas_test.rb
6
+ class TestClusterClientReplicas < Test::Unit::TestCase
7
+ include Helper::Cluster
8
+
9
+ def test_client_can_command_with_replica
10
+ r = build_another_client(replica: true)
11
+
12
+ 100.times do |i|
13
+ assert_equal 'OK', r.set("key#{i}", i)
14
+ end
15
+
16
+ 100.times do |i|
17
+ assert_equal i.to_s, r.get("key#{i}")
18
+ end
19
+ end
20
+
21
+ def test_client_can_flush_with_replica
22
+ r = build_another_client(replica: true)
23
+
24
+ assert_equal 'OK', r.flushall
25
+ assert_equal 'OK', r.flushdb
26
+ end
27
+
28
+ def test_some_reference_commands_are_sent_to_slaves_if_needed
29
+ r = build_another_client(replica: true)
30
+
31
+ 5.times { |i| r.set("key#{i}", i) }
32
+
33
+ assert_equal %w[key0 key1 key2 key3 key4], r.keys
34
+ assert_equal 5, r.dbsize
35
+ end
36
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_client_slots_test.rb
6
+ class TestClusterClientSlots < Test::Unit::TestCase
7
+ include Helper::Cluster
8
+
9
+ def test_slot_class
10
+ slot = Redis::Cluster::Slot.new('127.0.0.1:7000' => 1..10)
11
+
12
+ assert_equal false, slot.exists?(0)
13
+ assert_equal true, slot.exists?(1)
14
+ assert_equal true, slot.exists?(10)
15
+ assert_equal false, slot.exists?(11)
16
+
17
+ assert_equal nil, slot.find_node_key_of_master(0)
18
+ assert_equal nil, slot.find_node_key_of_slave(0)
19
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(1)
20
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_slave(1)
21
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(10)
22
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_slave(10)
23
+ assert_equal nil, slot.find_node_key_of_master(11)
24
+ assert_equal nil, slot.find_node_key_of_slave(11)
25
+
26
+ assert_equal nil, slot.put(1, '127.0.0.1:7001')
27
+ end
28
+
29
+ def test_slot_class_with_node_flags_and_replicas
30
+ slot = Redis::Cluster::Slot.new({ '127.0.0.1:7000' => 1..10, '127.0.0.1:7001' => 1..10 },
31
+ { '127.0.0.1:7000' => 'master', '127.0.0.1:7001' => 'slave' },
32
+ true)
33
+
34
+ assert_equal false, slot.exists?(0)
35
+ assert_equal true, slot.exists?(1)
36
+ assert_equal true, slot.exists?(10)
37
+ assert_equal false, slot.exists?(11)
38
+
39
+ assert_equal nil, slot.find_node_key_of_master(0)
40
+ assert_equal nil, slot.find_node_key_of_slave(0)
41
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(1)
42
+ assert_equal '127.0.0.1:7001', slot.find_node_key_of_slave(1)
43
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(10)
44
+ assert_equal '127.0.0.1:7001', slot.find_node_key_of_slave(10)
45
+ assert_equal nil, slot.find_node_key_of_master(11)
46
+ assert_equal nil, slot.find_node_key_of_slave(11)
47
+
48
+ assert_equal nil, slot.put(1, '127.0.0.1:7002')
49
+ end
50
+
51
+ def test_slot_class_with_node_flags_and_without_replicas
52
+ slot = Redis::Cluster::Slot.new({ '127.0.0.1:7000' => 1..10, '127.0.0.1:7001' => 1..10 },
53
+ { '127.0.0.1:7000' => 'master', '127.0.0.1:7001' => 'slave' },
54
+ false)
55
+
56
+ assert_equal false, slot.exists?(0)
57
+ assert_equal true, slot.exists?(1)
58
+ assert_equal true, slot.exists?(10)
59
+ assert_equal false, slot.exists?(11)
60
+
61
+ assert_equal nil, slot.find_node_key_of_master(0)
62
+ assert_equal nil, slot.find_node_key_of_slave(0)
63
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(1)
64
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_slave(1)
65
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_master(10)
66
+ assert_equal '127.0.0.1:7000', slot.find_node_key_of_slave(10)
67
+ assert_equal nil, slot.find_node_key_of_master(11)
68
+ assert_equal nil, slot.find_node_key_of_slave(11)
69
+
70
+ assert_equal nil, slot.put(1, '127.0.0.1:7002')
71
+ end
72
+
73
+ def test_slot_class_with_empty_slots
74
+ slot = Redis::Cluster::Slot.new({})
75
+
76
+ assert_equal false, slot.exists?(0)
77
+ assert_equal false, slot.exists?(1)
78
+
79
+ assert_equal nil, slot.find_node_key_of_master(0)
80
+ assert_equal nil, slot.find_node_key_of_slave(0)
81
+ assert_equal nil, slot.find_node_key_of_master(1)
82
+ assert_equal nil, slot.find_node_key_of_slave(1)
83
+
84
+ assert_equal nil, slot.put(1, '127.0.0.1:7001')
85
+ end
86
+
87
+ def test_redirection_when_slot_is_resharding
88
+ 100.times { |i| redis.set("{key}#{i}", i) }
89
+
90
+ redis_cluster_resharding(12539, src: '127.0.0.1:7002', dest: '127.0.0.1:7000') do
91
+ 100.times { |i| assert_equal i.to_s, redis.get("{key}#{i}") }
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_client_transactions_test.rb
6
+ class TestClusterClientTransactions < Test::Unit::TestCase
7
+ include Helper::Cluster
8
+
9
+ def test_transaction_with_hash_tag
10
+ rc1 = redis
11
+ rc2 = build_another_client
12
+
13
+ rc1.multi do |cli|
14
+ 100.times { |i| cli.set("{key}#{i}", i) }
15
+ end
16
+
17
+ 100.times { |i| assert_equal i.to_s, rc1.get("{key}#{i}") }
18
+ 100.times { |i| assert_equal i.to_s, rc2.get("{key}#{i}") }
19
+ end
20
+
21
+ def test_transaction_without_hash_tag
22
+ rc1 = redis
23
+ rc2 = build_another_client
24
+
25
+ assert_raise(Redis::Cluster::CrossSlotPipeliningError) do
26
+ rc1.multi do |cli|
27
+ 100.times { |i| cli.set("key#{i}", i) }
28
+ end
29
+ end
30
+
31
+ 100.times { |i| assert_equal nil, rc1.get("key#{i}") }
32
+ 100.times { |i| assert_equal nil, rc2.get("key#{i}") }
33
+ end
34
+
35
+ def test_transaction_with_replicas
36
+ rc1 = build_another_client(replica: true)
37
+ rc2 = build_another_client(replica: true)
38
+
39
+ rc1.multi do |cli|
40
+ 100.times { |i| cli.set("{key}#{i}", i) }
41
+ end
42
+
43
+ sleep 0.1
44
+
45
+ 100.times { |i| assert_equal i.to_s, rc1.get("{key}#{i}") }
46
+ 100.times { |i| assert_equal i.to_s, rc2.get("{key}#{i}") }
47
+ end
48
+
49
+ def test_transaction_with_watch
50
+ rc1 = redis
51
+ rc2 = build_another_client
52
+
53
+ rc1.set('{key}1', 100)
54
+ rc1.watch('{key}1')
55
+
56
+ rc2.set('{key}1', 200)
57
+ val = rc1.get('{key}1').to_i
58
+ val += 1
59
+
60
+ rc1.multi do |cli|
61
+ cli.set('{key}1', val)
62
+ cli.set('{key}2', 300)
63
+ end
64
+
65
+ assert_equal '200', rc1.get('{key}1')
66
+ assert_equal '200', rc2.get('{key}1')
67
+
68
+ assert_equal nil, rc1.get('{key}2')
69
+ assert_equal nil, rc2.get('{key}2')
70
+ end
71
+ end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_commands_on_cluster_test.rb
6
+ # @see https://redis.io/commands#cluster
7
+ class TestClusterCommandsOnCluster < Test::Unit::TestCase
8
+ include Helper::Cluster
9
+
10
+ def test_cluster_addslots
11
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER ADDSLOTS command should be...') do
12
+ redis.cluster(:addslots, 0, 1, 2)
13
+ end
14
+ end
15
+
16
+ def test_cluster_count_failure_reports
17
+ assert_raise(Redis::CommandError, 'ERR Unknown node unknown-node-id') do
18
+ redis.cluster('count-failure-reports', 'unknown-node-id')
19
+ end
20
+
21
+ node_id = redis.cluster(:nodes).first.fetch('node_id')
22
+ assert_true(redis.cluster('count-failure-reports', node_id) >= 0)
23
+ end
24
+
25
+ def test_cluster_countkeysinslot
26
+ assert_true(redis.cluster(:countkeysinslot, 0) >= 0)
27
+ assert_true(redis.cluster(:countkeysinslot, 16383) >= 0)
28
+
29
+ assert_raise(Redis::CommandError, 'ERR Invalid slot') do
30
+ redis.cluster(:countkeysinslot, -1)
31
+ end
32
+
33
+ assert_raise(Redis::CommandError, 'ERR Invalid slot') do
34
+ redis.cluster(:countkeysinslot, 16384)
35
+ end
36
+ end
37
+
38
+ def test_cluster_delslots
39
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER DELSLOTS command should be...') do
40
+ redis.cluster(:delslots, 0, 1, 2)
41
+ end
42
+ end
43
+
44
+ def test_cluster_failover
45
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER FAILOVER command should be...') do
46
+ redis.cluster(:failover, 'FORCE')
47
+ end
48
+ end
49
+
50
+ def test_cluster_forget
51
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER FORGET command should be...') do
52
+ redis.cluster(:forget, 'unknown-node-id')
53
+ end
54
+ end
55
+
56
+ def test_cluster_getkeysinslot
57
+ assert_instance_of Array, redis.cluster(:getkeysinslot, 0, 3)
58
+ end
59
+
60
+ def test_cluster_info
61
+ info = redis.cluster(:info)
62
+
63
+ assert_equal '3', info.fetch('cluster_size')
64
+ end
65
+
66
+ def test_cluster_keyslot
67
+ assert_equal Redis::Cluster::KeySlotConverter.convert('hogehoge'), redis.cluster(:keyslot, 'hogehoge')
68
+ assert_equal Redis::Cluster::KeySlotConverter.convert('12345'), redis.cluster(:keyslot, '12345')
69
+ assert_equal Redis::Cluster::KeySlotConverter.convert('foo'), redis.cluster(:keyslot, 'boo{foo}woo')
70
+ assert_equal Redis::Cluster::KeySlotConverter.convert('antirez.is.cool'), redis.cluster(:keyslot, 'antirez.is.cool')
71
+ assert_equal Redis::Cluster::KeySlotConverter.convert(''), redis.cluster(:keyslot, '')
72
+ end
73
+
74
+ def test_cluster_meet
75
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER MEET command should be...') do
76
+ redis.cluster(:meet, '127.0.0.1', 11211)
77
+ end
78
+ end
79
+
80
+ def test_cluster_nodes
81
+ cluster_nodes = redis.cluster(:nodes)
82
+ sample_node = cluster_nodes.first
83
+
84
+ assert_equal 6, cluster_nodes.length
85
+ assert_equal true, sample_node.key?('node_id')
86
+ assert_equal true, sample_node.key?('ip_port')
87
+ assert_equal true, sample_node.key?('flags')
88
+ assert_equal true, sample_node.key?('master_node_id')
89
+ assert_equal true, sample_node.key?('ping_sent')
90
+ assert_equal true, sample_node.key?('pong_recv')
91
+ assert_equal true, sample_node.key?('config_epoch')
92
+ assert_equal true, sample_node.key?('link_state')
93
+ assert_equal true, sample_node.key?('slots')
94
+ end
95
+
96
+ def test_cluster_replicate
97
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER REPLICATE command should be...') do
98
+ redis.cluster(:replicate)
99
+ end
100
+ end
101
+
102
+ def test_cluster_reset
103
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER RESET command should be...') do
104
+ redis.cluster(:reset)
105
+ end
106
+ end
107
+
108
+ def test_cluster_saveconfig
109
+ assert_equal 'OK', redis.cluster(:saveconfig)
110
+ end
111
+
112
+ def test_cluster_set_config_epoch
113
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER SET-CONFIG-EPOCH command should be...') do
114
+ redis.cluster('set-config-epoch')
115
+ end
116
+ end
117
+
118
+ def test_cluster_setslot
119
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'CLUSTER SETSLOT command should be...') do
120
+ redis.cluster(:setslot)
121
+ end
122
+ end
123
+
124
+ def test_cluster_slaves
125
+ cluster_nodes = redis.cluster(:nodes)
126
+
127
+ sample_master_node_id = cluster_nodes.find { |n| n.fetch('master_node_id') == '-' }.fetch('node_id')
128
+ sample_slave_node_id = cluster_nodes.find { |n| n.fetch('master_node_id') != '-' }.fetch('node_id')
129
+
130
+ assert_equal 'slave', redis.cluster(:slaves, sample_master_node_id).first.fetch('flags').first
131
+ assert_raise(Redis::CommandError, 'ERR The specified node is not a master') do
132
+ redis.cluster(:slaves, sample_slave_node_id)
133
+ end
134
+ end
135
+
136
+ def test_cluster_slots
137
+ slots = redis.cluster(:slots)
138
+ sample_slot = slots.first
139
+
140
+ assert_equal 3, slots.length
141
+ assert_equal true, sample_slot.key?('start_slot')
142
+ assert_equal true, sample_slot.key?('end_slot')
143
+ assert_equal true, sample_slot.key?('master')
144
+ assert_equal true, sample_slot.fetch('master').key?('ip')
145
+ assert_equal true, sample_slot.fetch('master').key?('port')
146
+ assert_equal true, sample_slot.fetch('master').key?('node_id')
147
+ assert_equal true, sample_slot.key?('replicas')
148
+ assert_equal true, sample_slot.fetch('replicas').is_a?(Array)
149
+ assert_equal true, sample_slot.fetch('replicas').first.key?('ip')
150
+ assert_equal true, sample_slot.fetch('replicas').first.key?('port')
151
+ assert_equal true, sample_slot.fetch('replicas').first.key?('node_id')
152
+ end
153
+
154
+ def test_readonly
155
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'READONLY command should be...') do
156
+ redis.readonly
157
+ end
158
+ end
159
+
160
+ def test_readwrite
161
+ assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'READWRITE command should be...') do
162
+ redis.readwrite
163
+ end
164
+ end
165
+ end