3
3
require 'uri'
4
4
require 'testing_helper'
5
5
require 'redis_client/cluster/node'
6
+ require 'redis_client/cluster/node_key'
6
7
7
8
class RedisClient
8
9
class Cluster
@@ -22,11 +23,34 @@ def test_connection_prelude
22
23
end
23
24
24
25
class TestNode < Minitest ::Test
26
+ def setup
27
+ config = ::RedisClient ::ClusterConfig . new ( nodes : TEST_NODE_URIS )
28
+ @node_info = ::RedisClient ::Cluster ::Node . load_info ( config . per_node_key , timeout : TEST_TIMEOUT_SEC )
29
+ node_addrs = @node_info . map { |info | ::RedisClient ::Cluster ::NodeKey . hashify ( info [ :node_key ] ) }
30
+ config . update_node ( node_addrs )
31
+ @test_node = ::RedisClient ::Cluster ::Node . new ( config . per_node_key , node_info : @node_info , timeout : TEST_TIMEOUT_SEC )
32
+ @test_node_with_scale_read = ::RedisClient ::Cluster ::Node . new ( config . per_node_key , node_info : @node_info , with_replica : true , timeout : TEST_TIMEOUT_SEC )
33
+ end
34
+
35
+ def teardown
36
+ @test_node &.each ( &:close )
37
+ @test_node_with_scale_read &.each ( &:close )
38
+ end
39
+
25
40
def test_load_info
26
41
[
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 } }
42
+ {
43
+ params : { options : TEST_NODE_OPTIONS , kwargs : { timeout : TEST_TIMEOUT_SEC } } ,
44
+ want : { size : TEST_NODE_OPTIONS . size }
45
+ } ,
46
+ {
47
+ params : { options : { '127.0.0.1:11211' => { host : '127.0.0.1' , port : 11_211 } } , kwargs : { timeout : TEST_TIMEOUT_SEC } } ,
48
+ want : { error : ::RedisClient ::Cluster ::InitialSetupError }
49
+ } ,
50
+ {
51
+ params : { options : { } , kwargs : { timeout : TEST_TIMEOUT_SEC } } ,
52
+ want : { error : ::RedisClient ::Cluster ::InitialSetupError }
53
+ }
30
54
] . each_with_index do |c , idx |
31
55
msg = "Case: #{ idx } "
32
56
got = -> { ::RedisClient ::Cluster ::Node . load_info ( c [ :params ] [ :options ] , **c [ :params ] [ :kwargs ] ) }
@@ -125,46 +149,140 @@ def test_parse_node_info
125
149
end
126
150
127
151
def test_inspect
128
- skip ( 'TODO' )
152
+ assert_match ( /^#<RedisClient::Cluster::Node [0-9., :]*>$/ , @test_node . inspect )
129
153
end
130
154
131
155
def test_enumerable
132
- skip ( 'TODO' )
156
+ refute ( @test_node . any? ( &:nil? ) )
157
+ end
158
+
159
+ def test_node_keys
160
+ want = @node_info . map { |info | info [ :node_key ] }
161
+ @test_node . node_keys . each do |got |
162
+ assert_includes ( want , got , "Case: #{ got } " )
163
+ end
133
164
end
134
165
135
166
def test_find_by
136
- skip ( 'TODO' )
167
+ @node_info . each do |info |
168
+ msg = "Case: primary only: #{ info [ :node_key ] } "
169
+ got = -> { @test_node . find_by ( info [ :node_key ] ) }
170
+ if info [ :role ] == 'master'
171
+ assert_instance_of ( ::RedisClient , got . call , msg )
172
+ else
173
+ assert_raises ( ::RedisClient ::Cluster ::Node ::ReloadNeeded , msg , &got )
174
+ end
175
+
176
+ msg = "Case: scale read: #{ info [ :node_key ] } "
177
+ got = @test_node_with_scale_read . find_by ( info [ :node_key ] )
178
+ assert_instance_of ( ::RedisClient , got , msg )
179
+ end
137
180
end
138
181
139
182
def test_call_all
140
- skip ( 'TODO' )
183
+ want = ( 1 ..( @node_info . count { |info | info [ :role ] == 'master' } ) ) . map { |_ | 'PONG' }
184
+ got = @test_node . call_all ( :call , 'PING' )
185
+ assert_equal ( want , got , 'Case: primary only' )
186
+
187
+ want = ( 1 ..( @node_info . count ) ) . map { |_ | 'PONG' }
188
+ got = @test_node_with_scale_read . call_all ( :call , 'PING' )
189
+ assert_equal ( want , got , 'Case: scale read' )
141
190
end
142
191
143
192
def test_call_primary
144
- skip ( 'TODO' )
193
+ want = ( 1 ..( @node_info . count { |info | info [ :role ] == 'master' } ) ) . map { |_ | 'PONG' }
194
+ got = @test_node . call_primary ( :call , 'PING' )
195
+ assert_equal ( want , got )
145
196
end
146
197
147
198
def test_call_replica
148
- skip ( 'TODO' )
199
+ want = ( 1 ..( @node_info . count { |info | info [ :role ] == 'master' } ) ) . map { |_ | 'PONG' }
200
+ got = @test_node . call_replica ( :call , 'PING' )
201
+ assert_equal ( want , got , 'Case: primary only' )
202
+
203
+ want = ( 1 ..( @node_info . count { |info | info [ :role ] == 'slave' } ) ) . map { |_ | 'PONG' }
204
+ got = @test_node_with_scale_read . call_replica ( :call , 'PING' )
205
+ assert_equal ( want , got , 'Case: scale read' )
149
206
end
150
207
151
208
def test_scale_reading_clients
152
- skip ( 'TODO' )
209
+ want = @node_info . select { |info | info [ :role ] == 'master' } . map { |info | info [ :node_key ] } . sort
210
+ got = @test_node . scale_reading_clients . map { |client | "#{ client . config . host } :#{ client . config . port } " } . sort
211
+ assert_equal ( want , got , 'Case: primary only' )
212
+
213
+ want = @node_info . select { |info | info [ :role ] == 'slave' } . map { |info | info [ :node_key ] } . sort
214
+ got = @test_node_with_scale_read . scale_reading_clients . map { |client | "#{ client . config . host } :#{ client . config . port } " } . sort
215
+ assert_equal ( want , got , 'Case: scale read' )
153
216
end
154
217
155
218
def test_slot_exists?
156
- skip ( 'TODO' )
219
+ refute ( @test_node . slot_exists? ( -1 ) )
220
+ assert ( @test_node . slot_exists? ( 0 ) )
221
+ assert ( @test_node . slot_exists? ( 16_383 ) )
222
+ refute ( @test_node . slot_exists? ( 16_384 ) )
223
+ assert_raises ( TypeError ) { @test_node . slot_exists? ( :foo ) }
157
224
end
158
225
159
226
def test_find_node_key_of_primary
160
- skip ( 'TODO' )
227
+ sample_node = @node_info . find { |info | info [ :role ] == 'master' }
228
+ sample_slot = sample_node [ :slots ] . first . first
229
+ got = @test_node . find_node_key_of_primary ( sample_slot )
230
+ assert_equal ( sample_node [ :node_key ] , got )
161
231
end
162
232
163
233
def test_find_node_key_of_replica
164
- skip ( 'TODO' )
234
+ sample_node = @node_info . find { |info | info [ :role ] == 'master' }
235
+ sample_slot = sample_node [ :slots ] . first . first
236
+ got = @test_node . find_node_key_of_replica ( sample_slot )
237
+ assert_equal ( sample_node [ :node_key ] , got , 'Case: primary only' )
238
+
239
+ sample_replica = @node_info . find { |info | info [ :role ] == 'slave' }
240
+ sample_primary = @node_info . find { |info | info [ :id ] == sample_replica [ :primary_id ] }
241
+ sample_slot = sample_primary [ :slots ] . first . first
242
+ got = @test_node_with_scale_read . find_node_key_of_replica ( sample_slot )
243
+ assert_equal ( sample_replica [ :node_key ] , got , 'Case: scale read' )
165
244
end
166
245
167
246
def test_update_slot
247
+ sample_slot = 0
248
+ base_node_key = @test_node . find_node_key_of_primary ( sample_slot )
249
+ another_node_key = @node_info . find { |info | info [ :node_key ] != base_node_key && info [ :role ] == 'master' }
250
+ @test_node . update_slot ( sample_slot , another_node_key )
251
+ assert_equal ( another_node_key , @test_node . find_node_key_of_primary ( sample_slot ) )
252
+ end
253
+
254
+ def test_replica_disabled?
255
+ assert ( @test_node . send ( :replica_disabled? ) )
256
+ refute ( @test_node_with_scale_read . send ( :replica_disabled? ) )
257
+ end
258
+
259
+ def test_primary?
260
+ sample_primary = @node_info . find { |info | info [ :role ] == 'master' }
261
+ sample_replica = @node_info . find { |info | info [ :role ] == 'slave' }
262
+ assert ( @test_node . send ( :primary? , sample_primary [ :node_key ] ) )
263
+ refute ( @test_node . send ( :primary? , sample_replica [ :node_key ] ) )
264
+ end
265
+
266
+ def test_replica?
267
+ sample_primary = @node_info . find { |info | info [ :role ] == 'master' }
268
+ sample_replica = @node_info . find { |info | info [ :role ] == 'slave' }
269
+ refute ( @test_node . send ( :replica? , sample_primary [ :node_key ] ) )
270
+ assert ( @test_node . send ( :replica? , sample_replica [ :node_key ] ) )
271
+ end
272
+
273
+ def test_build_slot_node_mappings
274
+ skip ( 'TODO' )
275
+ end
276
+
277
+ def test_build_replication_mappings
278
+ skip ( 'TODO' )
279
+ end
280
+
281
+ def test_build_clients
282
+ skip ( 'TODO' )
283
+ end
284
+
285
+ def test_try_map
168
286
skip ( 'TODO' )
169
287
end
170
288
end
0 commit comments