redis 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +17 -29
- data/.travis/Gemfile +5 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +5 -0
- data/README.md +1 -1
- data/bin/build +71 -0
- data/lib/redis.rb +198 -12
- data/lib/redis/client.rb +26 -12
- data/lib/redis/cluster.rb +285 -0
- data/lib/redis/cluster/command.rb +81 -0
- data/lib/redis/cluster/command_loader.rb +32 -0
- data/lib/redis/cluster/key_slot_converter.rb +72 -0
- data/lib/redis/cluster/node.rb +104 -0
- data/lib/redis/cluster/node_key.rb +35 -0
- data/lib/redis/cluster/node_loader.rb +35 -0
- data/lib/redis/cluster/option.rb +76 -0
- data/lib/redis/cluster/slot.rb +69 -0
- data/lib/redis/cluster/slot_loader.rb +47 -0
- data/lib/redis/connection/ruby.rb +5 -2
- data/lib/redis/distributed.rb +10 -2
- data/lib/redis/errors.rb +46 -0
- data/lib/redis/pipeline.rb +9 -1
- data/lib/redis/version.rb +1 -1
- data/makefile +54 -22
- data/redis.gemspec +2 -1
- data/test/client_test.rb +17 -0
- data/test/cluster_abnormal_state_test.rb +38 -0
- data/test/cluster_blocking_commands_test.rb +15 -0
- data/test/cluster_client_internals_test.rb +77 -0
- data/test/cluster_client_key_hash_tags_test.rb +88 -0
- data/test/cluster_client_options_test.rb +147 -0
- data/test/cluster_client_pipelining_test.rb +59 -0
- data/test/cluster_client_replicas_test.rb +36 -0
- data/test/cluster_client_slots_test.rb +94 -0
- data/test/cluster_client_transactions_test.rb +71 -0
- data/test/cluster_commands_on_cluster_test.rb +165 -0
- data/test/cluster_commands_on_connection_test.rb +40 -0
- data/test/cluster_commands_on_geo_test.rb +74 -0
- data/test/cluster_commands_on_hashes_test.rb +11 -0
- data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
- data/test/cluster_commands_on_keys_test.rb +134 -0
- data/test/cluster_commands_on_lists_test.rb +15 -0
- data/test/cluster_commands_on_pub_sub_test.rb +101 -0
- data/test/cluster_commands_on_scripting_test.rb +56 -0
- data/test/cluster_commands_on_server_test.rb +221 -0
- data/test/cluster_commands_on_sets_test.rb +39 -0
- data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
- data/test/cluster_commands_on_streams_test.rb +196 -0
- data/test/cluster_commands_on_strings_test.rb +15 -0
- data/test/cluster_commands_on_transactions_test.rb +41 -0
- data/test/cluster_commands_on_value_types_test.rb +14 -0
- data/test/commands_on_geo_test.rb +116 -0
- data/test/commands_on_hashes_test.rb +2 -14
- data/test/commands_on_hyper_log_log_test.rb +2 -14
- data/test/commands_on_lists_test.rb +2 -13
- data/test/commands_on_sets_test.rb +2 -70
- data/test/commands_on_sorted_sets_test.rb +2 -145
- data/test/commands_on_strings_test.rb +2 -94
- data/test/commands_on_value_types_test.rb +36 -0
- data/test/distributed_blocking_commands_test.rb +8 -0
- data/test/distributed_commands_on_hashes_test.rb +16 -3
- data/test/distributed_commands_on_hyper_log_log_test.rb +8 -13
- data/test/distributed_commands_on_lists_test.rb +4 -5
- data/test/distributed_commands_on_sets_test.rb +45 -46
- data/test/distributed_commands_on_sorted_sets_test.rb +51 -8
- data/test/distributed_commands_on_strings_test.rb +10 -0
- data/test/distributed_commands_on_value_types_test.rb +36 -0
- data/test/helper.rb +176 -32
- data/test/internals_test.rb +20 -1
- data/test/lint/blocking_commands.rb +40 -16
- data/test/lint/hashes.rb +41 -0
- data/test/lint/hyper_log_log.rb +15 -1
- data/test/lint/lists.rb +16 -0
- data/test/lint/sets.rb +142 -0
- data/test/lint/sorted_sets.rb +183 -2
- data/test/lint/strings.rb +102 -0
- data/test/pipelining_commands_test.rb +8 -0
- data/test/support/cluster/orchestrator.rb +199 -0
- data/test/support/redis_mock.rb +1 -1
- data/test/transactions_test.rb +10 -0
- metadata +81 -2
@@ -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
|