redis 3.3.5 → 4.1.0

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.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -2
  3. data/README.md +77 -76
  4. data/lib/redis.rb +779 -63
  5. data/lib/redis/client.rb +41 -20
  6. data/lib/redis/cluster.rb +286 -0
  7. data/lib/redis/cluster/command.rb +81 -0
  8. data/lib/redis/cluster/command_loader.rb +34 -0
  9. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  10. data/lib/redis/cluster/node.rb +104 -0
  11. data/lib/redis/cluster/node_key.rb +35 -0
  12. data/lib/redis/cluster/node_loader.rb +37 -0
  13. data/lib/redis/cluster/option.rb +77 -0
  14. data/lib/redis/cluster/slot.rb +69 -0
  15. data/lib/redis/cluster/slot_loader.rb +49 -0
  16. data/lib/redis/connection.rb +2 -2
  17. data/lib/redis/connection/command_helper.rb +2 -8
  18. data/lib/redis/connection/hiredis.rb +2 -2
  19. data/lib/redis/connection/ruby.rb +13 -30
  20. data/lib/redis/connection/synchrony.rb +12 -4
  21. data/lib/redis/distributed.rb +32 -12
  22. data/lib/redis/errors.rb +46 -0
  23. data/lib/redis/hash_ring.rb +20 -64
  24. data/lib/redis/pipeline.rb +9 -7
  25. data/lib/redis/version.rb +1 -1
  26. metadata +53 -196
  27. data/.gitignore +0 -16
  28. data/.travis.yml +0 -89
  29. data/.travis/Gemfile +0 -11
  30. data/.yardopts +0 -3
  31. data/Gemfile +0 -4
  32. data/Rakefile +0 -87
  33. data/benchmarking/logging.rb +0 -71
  34. data/benchmarking/pipeline.rb +0 -51
  35. data/benchmarking/speed.rb +0 -21
  36. data/benchmarking/suite.rb +0 -24
  37. data/benchmarking/worker.rb +0 -71
  38. data/examples/basic.rb +0 -15
  39. data/examples/consistency.rb +0 -114
  40. data/examples/dist_redis.rb +0 -43
  41. data/examples/incr-decr.rb +0 -17
  42. data/examples/list.rb +0 -26
  43. data/examples/pubsub.rb +0 -37
  44. data/examples/sentinel.rb +0 -41
  45. data/examples/sentinel/start +0 -49
  46. data/examples/sets.rb +0 -36
  47. data/examples/unicorn/config.ru +0 -3
  48. data/examples/unicorn/unicorn.rb +0 -20
  49. data/redis.gemspec +0 -44
  50. data/test/bitpos_test.rb +0 -69
  51. data/test/blocking_commands_test.rb +0 -42
  52. data/test/client_test.rb +0 -59
  53. data/test/command_map_test.rb +0 -30
  54. data/test/commands_on_hashes_test.rb +0 -21
  55. data/test/commands_on_hyper_log_log_test.rb +0 -21
  56. data/test/commands_on_lists_test.rb +0 -20
  57. data/test/commands_on_sets_test.rb +0 -77
  58. data/test/commands_on_sorted_sets_test.rb +0 -137
  59. data/test/commands_on_strings_test.rb +0 -101
  60. data/test/commands_on_value_types_test.rb +0 -133
  61. data/test/connection_handling_test.rb +0 -277
  62. data/test/connection_test.rb +0 -57
  63. data/test/distributed_blocking_commands_test.rb +0 -46
  64. data/test/distributed_commands_on_hashes_test.rb +0 -10
  65. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  66. data/test/distributed_commands_on_lists_test.rb +0 -22
  67. data/test/distributed_commands_on_sets_test.rb +0 -83
  68. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  69. data/test/distributed_commands_on_strings_test.rb +0 -59
  70. data/test/distributed_commands_on_value_types_test.rb +0 -95
  71. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  72. data/test/distributed_connection_handling_test.rb +0 -23
  73. data/test/distributed_internals_test.rb +0 -79
  74. data/test/distributed_key_tags_test.rb +0 -52
  75. data/test/distributed_persistence_control_commands_test.rb +0 -26
  76. data/test/distributed_publish_subscribe_test.rb +0 -92
  77. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  78. data/test/distributed_scripting_test.rb +0 -102
  79. data/test/distributed_sorting_test.rb +0 -20
  80. data/test/distributed_test.rb +0 -58
  81. data/test/distributed_transactions_test.rb +0 -32
  82. data/test/encoding_test.rb +0 -18
  83. data/test/error_replies_test.rb +0 -59
  84. data/test/fork_safety_test.rb +0 -65
  85. data/test/helper.rb +0 -232
  86. data/test/helper_test.rb +0 -24
  87. data/test/internals_test.rb +0 -417
  88. data/test/lint/blocking_commands.rb +0 -150
  89. data/test/lint/hashes.rb +0 -162
  90. data/test/lint/hyper_log_log.rb +0 -60
  91. data/test/lint/lists.rb +0 -143
  92. data/test/lint/sets.rb +0 -140
  93. data/test/lint/sorted_sets.rb +0 -316
  94. data/test/lint/strings.rb +0 -260
  95. data/test/lint/value_types.rb +0 -122
  96. data/test/persistence_control_commands_test.rb +0 -26
  97. data/test/pipelining_commands_test.rb +0 -242
  98. data/test/publish_subscribe_test.rb +0 -282
  99. data/test/remote_server_control_commands_test.rb +0 -118
  100. data/test/scanning_test.rb +0 -413
  101. data/test/scripting_test.rb +0 -78
  102. data/test/sentinel_command_test.rb +0 -80
  103. data/test/sentinel_test.rb +0 -255
  104. data/test/sorting_test.rb +0 -59
  105. data/test/ssl_test.rb +0 -73
  106. data/test/support/connection/hiredis.rb +0 -1
  107. data/test/support/connection/ruby.rb +0 -1
  108. data/test/support/connection/synchrony.rb +0 -17
  109. data/test/support/redis_mock.rb +0 -130
  110. data/test/support/ssl/gen_certs.sh +0 -31
  111. data/test/support/ssl/trusted-ca.crt +0 -25
  112. data/test/support/ssl/trusted-ca.key +0 -27
  113. data/test/support/ssl/trusted-cert.crt +0 -81
  114. data/test/support/ssl/trusted-cert.key +0 -28
  115. data/test/support/ssl/untrusted-ca.crt +0 -26
  116. data/test/support/ssl/untrusted-ca.key +0 -27
  117. data/test/support/ssl/untrusted-cert.crt +0 -82
  118. data/test/support/ssl/untrusted-cert.key +0 -28
  119. data/test/support/wire/synchrony.rb +0 -24
  120. data/test/support/wire/thread.rb +0 -5
  121. data/test/synchrony_driver.rb +0 -88
  122. data/test/test.conf.erb +0 -9
  123. data/test/thread_safety_test.rb +0 -62
  124. data/test/transactions_test.rb +0 -264
  125. data/test/unknown_commands_test.rb +0 -14
  126. data/test/url_param_test.rb +0 -138
@@ -1,282 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- class TestPublishSubscribe < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- class TestError < StandardError
10
- end
11
-
12
- def test_subscribe_and_unsubscribe
13
- @subscribed = false
14
- @unsubscribed = false
15
-
16
- wire = Wire.new do
17
- r.subscribe("foo") do |on|
18
- on.subscribe do |channel, total|
19
- @subscribed = true
20
- @t1 = total
21
- end
22
-
23
- on.message do |channel, message|
24
- if message == "s1"
25
- r.unsubscribe
26
- @message = message
27
- end
28
- end
29
-
30
- on.unsubscribe do |channel, total|
31
- @unsubscribed = true
32
- @t2 = total
33
- end
34
- end
35
- end
36
-
37
- # Wait until the subscription is active before publishing
38
- Wire.pass while !@subscribed
39
-
40
- Redis.new(OPTIONS).publish("foo", "s1")
41
-
42
- wire.join
43
-
44
- assert @subscribed
45
- assert_equal 1, @t1
46
- assert @unsubscribed
47
- assert_equal 0, @t2
48
- assert_equal "s1", @message
49
- end
50
-
51
- def test_psubscribe_and_punsubscribe
52
- @subscribed = false
53
- @unsubscribed = false
54
-
55
- wire = Wire.new do
56
- r.psubscribe("f*") do |on|
57
- on.psubscribe do |pattern, total|
58
- @subscribed = true
59
- @t1 = total
60
- end
61
-
62
- on.pmessage do |pattern, channel, message|
63
- if message == "s1"
64
- r.punsubscribe
65
- @message = message
66
- end
67
- end
68
-
69
- on.punsubscribe do |pattern, total|
70
- @unsubscribed = true
71
- @t2 = total
72
- end
73
- end
74
- end
75
-
76
- # Wait until the subscription is active before publishing
77
- Wire.pass while !@subscribed
78
-
79
- Redis.new(OPTIONS).publish("foo", "s1")
80
-
81
- wire.join
82
-
83
- assert @subscribed
84
- assert_equal 1, @t1
85
- assert @unsubscribed
86
- assert_equal 0, @t2
87
- assert_equal "s1", @message
88
- end
89
-
90
- def test_pubsub_with_numpat_subcommand
91
- target_version("2.8.0") do
92
- @subscribed = false
93
- wire = Wire.new do
94
- r.psubscribe("f*") do |on|
95
- on.psubscribe { |channel, total| @subscribed = true }
96
- on.pmessage { |pattern, channel, message| r.punsubscribe }
97
- end
98
- end
99
- Wire.pass while !@subscribed
100
- redis = Redis.new(OPTIONS)
101
- numpat_result = redis.pubsub(:numpat)
102
-
103
- redis.publish("foo", "s1")
104
- wire.join
105
-
106
- assert_equal redis.pubsub(:numpat), 0
107
- assert_equal numpat_result, 1
108
- end
109
- end
110
-
111
-
112
- def test_pubsub_with_channels_and_numsub_subcommnads
113
- target_version("2.8.0") do
114
- @subscribed = false
115
- wire = Wire.new do
116
- r.subscribe("foo") do |on|
117
- on.subscribe { |channel, total| @subscribed = true }
118
- on.message { |channel, message| r.unsubscribe }
119
- end
120
- end
121
- Wire.pass while !@subscribed
122
- redis = Redis.new(OPTIONS)
123
- channels_result = redis.pubsub(:channels)
124
- numsub_result = redis.pubsub(:numsub, 'foo', 'boo')
125
-
126
- redis.publish("foo", "s1")
127
- wire.join
128
-
129
- assert_equal channels_result, ['foo']
130
- assert_equal numsub_result, ['foo', 1, 'boo', 0]
131
- end
132
- end
133
-
134
- def test_subscribe_connection_usable_after_raise
135
- @subscribed = false
136
-
137
- wire = Wire.new do
138
- begin
139
- r.subscribe("foo") do |on|
140
- on.subscribe do |channel, total|
141
- @subscribed = true
142
- end
143
-
144
- on.message do |channel, message|
145
- raise TestError
146
- end
147
- end
148
- rescue TestError
149
- end
150
- end
151
-
152
- # Wait until the subscription is active before publishing
153
- Wire.pass while !@subscribed
154
-
155
- Redis.new(OPTIONS).publish("foo", "s1")
156
-
157
- wire.join
158
-
159
- assert_equal "PONG", r.ping
160
- end
161
-
162
- def test_psubscribe_connection_usable_after_raise
163
- @subscribed = false
164
-
165
- wire = Wire.new do
166
- begin
167
- r.psubscribe("f*") do |on|
168
- on.psubscribe do |pattern, total|
169
- @subscribed = true
170
- end
171
-
172
- on.pmessage do |pattern, channel, message|
173
- raise TestError
174
- end
175
- end
176
- rescue TestError
177
- end
178
- end
179
-
180
- # Wait until the subscription is active before publishing
181
- Wire.pass while !@subscribed
182
-
183
- Redis.new(OPTIONS).publish("foo", "s1")
184
-
185
- wire.join
186
-
187
- assert_equal "PONG", r.ping
188
- end
189
-
190
- def test_subscribe_within_subscribe
191
- @channels = []
192
-
193
- wire = Wire.new do
194
- r.subscribe("foo") do |on|
195
- on.subscribe do |channel, total|
196
- @channels << channel
197
-
198
- r.subscribe("bar") if channel == "foo"
199
- r.unsubscribe if channel == "bar"
200
- end
201
- end
202
- end
203
-
204
- wire.join
205
-
206
- assert_equal ["foo", "bar"], @channels
207
- end
208
-
209
- def test_other_commands_within_a_subscribe
210
- assert_raise Redis::CommandError do
211
- r.subscribe("foo") do |on|
212
- on.subscribe do |channel, total|
213
- r.set("bar", "s2")
214
- end
215
- end
216
- end
217
- end
218
-
219
- def test_subscribe_without_a_block
220
- assert_raise LocalJumpError do
221
- r.subscribe("foo")
222
- end
223
- end
224
-
225
- def test_unsubscribe_without_a_subscribe
226
- assert_raise RuntimeError do
227
- r.unsubscribe
228
- end
229
-
230
- assert_raise RuntimeError do
231
- r.punsubscribe
232
- end
233
- end
234
-
235
- def test_subscribe_past_a_timeout
236
- # For some reason, a thread here doesn't reproduce the issue.
237
- sleep = %{sleep #{OPTIONS[:timeout] * 2}}
238
- publish = %{ruby -rsocket -e 't=TCPSocket.new("127.0.0.1",#{OPTIONS[:port]});t.write("publish foo bar\\r\\n");t.read(4);t.close'}
239
- cmd = [sleep, publish].join("; ")
240
-
241
- IO.popen(cmd, "r+") do |pipe|
242
- received = false
243
-
244
- r.subscribe "foo" do |on|
245
- on.message do |channel, message|
246
- received = true
247
- r.unsubscribe
248
- end
249
- end
250
-
251
- assert received
252
- end
253
- end
254
-
255
- def test_subscribe_with_timeout
256
- received = false
257
-
258
- assert_raise Redis::TimeoutError do
259
- r.subscribe_with_timeout(1, "foo") do |on|
260
- on.message do |channel, message|
261
- received = true
262
- end
263
- end
264
- end
265
-
266
- assert !received
267
- end
268
-
269
- def test_psubscribe_with_timeout
270
- received = false
271
-
272
- assert_raise Redis::TimeoutError do
273
- r.psubscribe_with_timeout(1, "f*") do |on|
274
- on.message do |channel, message|
275
- received = true
276
- end
277
- end
278
- end
279
-
280
- assert !received
281
- end
282
- end
@@ -1,118 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- class TestRemoteServerControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_info
10
- keys = [
11
- "redis_version",
12
- "uptime_in_seconds",
13
- "uptime_in_days",
14
- "connected_clients",
15
- "used_memory",
16
- "total_connections_received",
17
- "total_commands_processed",
18
- ]
19
-
20
- info = r.info
21
-
22
- keys.each do |k|
23
- msg = "expected #info to include #{k}"
24
- assert info.keys.include?(k), msg
25
- end
26
- end
27
-
28
- def test_info_commandstats
29
- target_version "2.5.7" do
30
- r.config(:resetstat)
31
- r.ping
32
-
33
- result = r.info(:commandstats)
34
- assert_equal "1", result["ping"]["calls"]
35
- end
36
- end
37
-
38
- def test_monitor_redis_lt_2_5_0
39
- return unless version < "2.5.0"
40
-
41
- log = []
42
-
43
- wire = Wire.new do
44
- Redis.new(OPTIONS).monitor do |line|
45
- log << line
46
- break if log.size == 3
47
- end
48
- end
49
-
50
- Wire.pass while log.empty? # Faster than sleep
51
-
52
- r.set "foo", "s1"
53
-
54
- wire.join
55
-
56
- assert log[-1][%q{(db 15) "set" "foo" "s1"}]
57
- end
58
-
59
- def test_monitor_redis_gte_2_5_0
60
- return unless version >= "2.5.0"
61
-
62
- log = []
63
-
64
- wire = Wire.new do
65
- Redis.new(OPTIONS).monitor do |line|
66
- log << line
67
- break if line =~ /set/
68
- end
69
- end
70
-
71
- Wire.pass while log.empty? # Faster than sleep
72
-
73
- r.set "foo", "s1"
74
-
75
- wire.join
76
-
77
- assert log[-1] =~ /\b15\b.* "set" "foo" "s1"/
78
- end
79
-
80
- def test_monitor_returns_value_for_break
81
- result = r.monitor do |line|
82
- break line
83
- end
84
-
85
- assert_equal "OK", result
86
- end
87
-
88
- def test_echo
89
- assert_equal "foo bar baz\n", r.echo("foo bar baz\n")
90
- end
91
-
92
- def test_debug
93
- r.set "foo", "s1"
94
-
95
- assert r.debug(:object, "foo").kind_of?(String)
96
- end
97
-
98
- def test_object
99
- r.lpush "list", "value"
100
-
101
- assert_equal 1, r.object(:refcount, "list")
102
- encoding = r.object(:encoding, "list")
103
- assert "ziplist" == encoding || "quicklist" == encoding, "Wrong encoding for list"
104
- assert r.object(:idletime, "list").kind_of?(Integer)
105
- end
106
-
107
- def test_sync
108
- redis_mock(:sync => lambda { "+OK" }) do |redis|
109
- assert_equal "OK", redis.sync
110
- end
111
- end
112
-
113
- def test_slowlog
114
- r.slowlog(:reset)
115
- result = r.slowlog(:len)
116
- assert_equal 0, result
117
- end
118
- end
@@ -1,413 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- unless defined?(Enumerator)
6
- Enumerator = Enumerable::Enumerator
7
- end
8
-
9
- class TestScanning < Test::Unit::TestCase
10
-
11
- include Helper::Client
12
-
13
- def test_scan_basic
14
- target_version "2.7.105" do
15
- r.debug :populate, 1000
16
-
17
- cursor = 0
18
- all_keys = []
19
- loop {
20
- cursor, keys = r.scan cursor
21
- all_keys += keys
22
- break if cursor == "0"
23
- }
24
-
25
- assert_equal 1000, all_keys.uniq.size
26
- end
27
- end
28
-
29
- def test_scan_count
30
- target_version "2.7.105" do
31
- r.debug :populate, 1000
32
-
33
- cursor = 0
34
- all_keys = []
35
- loop {
36
- cursor, keys = r.scan cursor, :count => 5
37
- all_keys += keys
38
- break if cursor == "0"
39
- }
40
-
41
- assert_equal 1000, all_keys.uniq.size
42
- end
43
- end
44
-
45
- def test_scan_match
46
- target_version "2.7.105" do
47
- r.debug :populate, 1000
48
-
49
- cursor = 0
50
- all_keys = []
51
- loop {
52
- cursor, keys = r.scan cursor, :match => "key:1??"
53
- all_keys += keys
54
- break if cursor == "0"
55
- }
56
-
57
- assert_equal 100, all_keys.uniq.size
58
- end
59
- end
60
-
61
- def test_scan_each_enumerator
62
- target_version "2.7.105" do
63
-
64
- r.debug :populate, 1000
65
-
66
- scan_enumerator = r.scan_each
67
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
68
-
69
- keys_from_scan = scan_enumerator.to_a.uniq
70
- all_keys = r.keys "*"
71
-
72
- assert all_keys.sort == keys_from_scan.sort
73
- end
74
- end
75
-
76
- def test_scan_each_enumerator_match
77
- target_version "2.7.105" do
78
-
79
- r.debug :populate, 1000
80
-
81
- keys_from_scan = r.scan_each(:match => "key:1??").to_a.uniq
82
- all_keys = r.keys "key:1??"
83
-
84
- assert all_keys.sort == keys_from_scan.sort
85
- end
86
- end
87
-
88
- def test_scan_each_block
89
- target_version "2.7.105" do
90
-
91
- r.debug :populate, 100
92
-
93
- keys_from_scan = []
94
- r.scan_each {|key|
95
- keys_from_scan << key
96
- }
97
-
98
- all_keys = r.keys "*"
99
-
100
- assert all_keys.sort == keys_from_scan.uniq.sort
101
- end
102
- end
103
-
104
- def test_scan_each_block_match
105
- target_version "2.7.105" do
106
-
107
- r.debug :populate, 100
108
-
109
- keys_from_scan = []
110
- r.scan_each(:match => "key:1?") {|key|
111
- keys_from_scan << key
112
- }
113
-
114
- all_keys = r.keys "key:1?"
115
-
116
- assert all_keys.sort == keys_from_scan.uniq.sort
117
- end
118
- end
119
-
120
- def test_sscan_with_encoding
121
- target_version "2.7.105" do
122
- [:intset, :hashtable].each do |enc|
123
- r.del "set"
124
-
125
- prefix = ""
126
- prefix = "ele:" if enc == :hashtable
127
-
128
- elements = []
129
- 100.times { |j| elements << "#{prefix}#{j}" }
130
-
131
- r.sadd "set", elements
132
-
133
- assert_equal enc.to_s, r.object("encoding", "set")
134
-
135
- cursor = 0
136
- all_keys = []
137
- loop {
138
- cursor, keys = r.sscan "set", cursor
139
- all_keys += keys
140
- break if cursor == "0"
141
- }
142
-
143
- assert_equal 100, all_keys.uniq.size
144
- end
145
- end
146
- end
147
-
148
- def test_sscan_each_enumerator
149
- target_version "2.7.105" do
150
- elements = []
151
- 100.times { |j| elements << "ele:#{j}" }
152
- r.sadd "set", elements
153
-
154
- scan_enumerator = r.sscan_each("set")
155
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
156
-
157
- keys_from_scan = scan_enumerator.to_a.uniq
158
- all_keys = r.smembers("set")
159
-
160
- assert all_keys.sort == keys_from_scan.sort
161
- end
162
- end
163
-
164
- def test_sscan_each_enumerator_match
165
- target_version "2.7.105" do
166
- elements = []
167
- 100.times { |j| elements << "ele:#{j}" }
168
- r.sadd "set", elements
169
-
170
- keys_from_scan = r.sscan_each("set", :match => "ele:1?").to_a.uniq
171
-
172
- all_keys = r.smembers("set").grep(/^ele:1.$/)
173
-
174
- assert all_keys.sort == keys_from_scan.sort
175
- end
176
- end
177
-
178
- def test_sscan_each_enumerator_block
179
- target_version "2.7.105" do
180
- elements = []
181
- 100.times { |j| elements << "ele:#{j}" }
182
- r.sadd "set", elements
183
-
184
- keys_from_scan = []
185
- r.sscan_each("set") do |key|
186
- keys_from_scan << key
187
- end
188
-
189
- all_keys = r.smembers("set")
190
-
191
- assert all_keys.sort == keys_from_scan.uniq.sort
192
- end
193
- end
194
-
195
- def test_sscan_each_enumerator_block_match
196
- target_version "2.7.105" do
197
- elements = []
198
- 100.times { |j| elements << "ele:#{j}" }
199
- r.sadd "set", elements
200
-
201
- keys_from_scan = []
202
- r.sscan_each("set", :match => "ele:1?") do |key|
203
- keys_from_scan << key
204
- end
205
-
206
- all_keys = r.smembers("set").grep(/^ele:1.$/)
207
-
208
- assert all_keys.sort == keys_from_scan.uniq.sort
209
- end
210
- end
211
-
212
- def test_hscan_with_encoding
213
- target_version "2.7.105" do
214
- [:ziplist, :hashtable].each do |enc|
215
- r.del "set"
216
-
217
- count = 1000
218
- count = 30 if enc == :ziplist
219
-
220
- elements = []
221
- count.times { |j| elements << "key:#{j}" << j.to_s }
222
-
223
- r.hmset "hash", *elements
224
-
225
- assert_equal enc.to_s, r.object("encoding", "hash")
226
-
227
- cursor = 0
228
- all_key_values = []
229
- loop {
230
- cursor, key_values = r.hscan "hash", cursor
231
- all_key_values.concat key_values
232
- break if cursor == "0"
233
- }
234
-
235
- keys2 = []
236
- all_key_values.each do |k, v|
237
- assert_equal "key:#{v}", k
238
- keys2 << k
239
- end
240
-
241
- assert_equal count, keys2.uniq.size
242
- end
243
- end
244
- end
245
-
246
- def test_hscan_each_enumerator
247
- target_version "2.7.105" do
248
- count = 1000
249
- elements = []
250
- count.times { |j| elements << "key:#{j}" << j.to_s }
251
- r.hmset "hash", *elements
252
-
253
- scan_enumerator = r.hscan_each("hash")
254
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
255
-
256
- keys_from_scan = scan_enumerator.to_a.uniq
257
- all_keys = r.hgetall("hash").to_a
258
-
259
- assert all_keys.sort == keys_from_scan.sort
260
- end
261
- end
262
-
263
- def test_hscan_each_enumerator_match
264
- target_version "2.7.105" do
265
- count = 100
266
- elements = []
267
- count.times { |j| elements << "key:#{j}" << j.to_s }
268
- r.hmset "hash", *elements
269
-
270
- keys_from_scan = r.hscan_each("hash", :match => "key:1?").to_a.uniq
271
- all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/}
272
-
273
- assert all_keys.sort == keys_from_scan.sort
274
- end
275
- end
276
-
277
- def test_hscan_each_block
278
- target_version "2.7.105" do
279
- count = 1000
280
- elements = []
281
- count.times { |j| elements << "key:#{j}" << j.to_s }
282
- r.hmset "hash", *elements
283
-
284
- keys_from_scan = []
285
- r.hscan_each("hash") do |field, value|
286
- keys_from_scan << [field, value]
287
- end
288
- all_keys = r.hgetall("hash").to_a
289
-
290
- assert all_keys.sort == keys_from_scan.uniq.sort
291
- end
292
- end
293
-
294
- def test_hscan_each_block_match
295
- target_version "2.7.105" do
296
- count = 1000
297
- elements = []
298
- count.times { |j| elements << "key:#{j}" << j.to_s }
299
- r.hmset "hash", *elements
300
-
301
- keys_from_scan = []
302
- r.hscan_each("hash", :match => "key:1?") do |field, value|
303
- keys_from_scan << [field, value]
304
- end
305
- all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/}
306
-
307
- assert all_keys.sort == keys_from_scan.uniq.sort
308
- end
309
- end
310
-
311
- def test_zscan_with_encoding
312
- target_version "2.7.105" do
313
- [:ziplist, :skiplist].each do |enc|
314
- r.del "zset"
315
-
316
- count = 1000
317
- count = 30 if enc == :ziplist
318
-
319
- elements = []
320
- count.times { |j| elements << j << "key:#{j}" }
321
-
322
- r.zadd "zset", elements
323
-
324
- assert_equal enc.to_s, r.object("encoding", "zset")
325
-
326
- cursor = 0
327
- all_key_scores = []
328
- loop {
329
- cursor, key_scores = r.zscan "zset", cursor
330
- all_key_scores.concat key_scores
331
- break if cursor == "0"
332
- }
333
-
334
- keys2 = []
335
- all_key_scores.each do |k, v|
336
- assert_equal true, v.is_a?(Float)
337
- assert_equal "key:#{Integer(v)}", k
338
- keys2 << k
339
- end
340
-
341
- assert_equal count, keys2.uniq.size
342
- end
343
- end
344
- end
345
-
346
- def test_zscan_each_enumerator
347
- target_version "2.7.105" do
348
- count = 1000
349
- elements = []
350
- count.times { |j| elements << j << "key:#{j}" }
351
- r.zadd "zset", elements
352
-
353
- scan_enumerator = r.zscan_each "zset"
354
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
355
-
356
- scores_from_scan = scan_enumerator.to_a.uniq
357
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
358
-
359
- assert member_scores.sort == scores_from_scan.sort
360
- end
361
- end
362
-
363
- def test_zscan_each_enumerator_match
364
- target_version "2.7.105" do
365
- count = 1000
366
- elements = []
367
- count.times { |j| elements << j << "key:#{j}" }
368
- r.zadd "zset", elements
369
-
370
- scores_from_scan = r.zscan_each("zset", :match => "key:1??").to_a.uniq
371
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
372
- filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/}
373
-
374
- assert filtered_members.sort == scores_from_scan.sort
375
- end
376
- end
377
-
378
- def test_zscan_each_block
379
- target_version "2.7.105" do
380
- count = 1000
381
- elements = []
382
- count.times { |j| elements << j << "key:#{j}" }
383
- r.zadd "zset", elements
384
-
385
- scores_from_scan = []
386
- r.zscan_each("zset") do |member, score|
387
- scores_from_scan << [member, score]
388
- end
389
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
390
-
391
- assert member_scores.sort == scores_from_scan.sort
392
- end
393
- end
394
-
395
- def test_zscan_each_block_match
396
- target_version "2.7.105" do
397
- count = 1000
398
- elements = []
399
- count.times { |j| elements << j << "key:#{j}" }
400
- r.zadd "zset", elements
401
-
402
- scores_from_scan = []
403
- r.zscan_each("zset", :match => "key:1??") do |member, score|
404
- scores_from_scan << [member, score]
405
- end
406
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
407
- filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/}
408
-
409
- assert filtered_members.sort == scores_from_scan.sort
410
- end
411
- end
412
-
413
- end