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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -2
- data/README.md +77 -76
- data/lib/redis.rb +779 -63
- data/lib/redis/client.rb +41 -20
- data/lib/redis/cluster.rb +286 -0
- data/lib/redis/cluster/command.rb +81 -0
- data/lib/redis/cluster/command_loader.rb +34 -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 +37 -0
- data/lib/redis/cluster/option.rb +77 -0
- data/lib/redis/cluster/slot.rb +69 -0
- data/lib/redis/cluster/slot_loader.rb +49 -0
- data/lib/redis/connection.rb +2 -2
- data/lib/redis/connection/command_helper.rb +2 -8
- data/lib/redis/connection/hiredis.rb +2 -2
- data/lib/redis/connection/ruby.rb +13 -30
- data/lib/redis/connection/synchrony.rb +12 -4
- data/lib/redis/distributed.rb +32 -12
- data/lib/redis/errors.rb +46 -0
- data/lib/redis/hash_ring.rb +20 -64
- data/lib/redis/pipeline.rb +9 -7
- data/lib/redis/version.rb +1 -1
- metadata +53 -196
- data/.gitignore +0 -16
- data/.travis.yml +0 -89
- data/.travis/Gemfile +0 -11
- data/.yardopts +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -87
- data/benchmarking/logging.rb +0 -71
- data/benchmarking/pipeline.rb +0 -51
- data/benchmarking/speed.rb +0 -21
- data/benchmarking/suite.rb +0 -24
- data/benchmarking/worker.rb +0 -71
- data/examples/basic.rb +0 -15
- data/examples/consistency.rb +0 -114
- data/examples/dist_redis.rb +0 -43
- data/examples/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel.rb +0 -41
- data/examples/sentinel/start +0 -49
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/redis.gemspec +0 -44
- data/test/bitpos_test.rb +0 -69
- data/test/blocking_commands_test.rb +0 -42
- data/test/client_test.rb +0 -59
- data/test/command_map_test.rb +0 -30
- data/test/commands_on_hashes_test.rb +0 -21
- data/test/commands_on_hyper_log_log_test.rb +0 -21
- data/test/commands_on_lists_test.rb +0 -20
- data/test/commands_on_sets_test.rb +0 -77
- data/test/commands_on_sorted_sets_test.rb +0 -137
- data/test/commands_on_strings_test.rb +0 -101
- data/test/commands_on_value_types_test.rb +0 -133
- data/test/connection_handling_test.rb +0 -277
- data/test/connection_test.rb +0 -57
- data/test/distributed_blocking_commands_test.rb +0 -46
- data/test/distributed_commands_on_hashes_test.rb +0 -10
- data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
- data/test/distributed_commands_on_lists_test.rb +0 -22
- data/test/distributed_commands_on_sets_test.rb +0 -83
- data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
- data/test/distributed_commands_on_strings_test.rb +0 -59
- data/test/distributed_commands_on_value_types_test.rb +0 -95
- data/test/distributed_commands_requiring_clustering_test.rb +0 -164
- data/test/distributed_connection_handling_test.rb +0 -23
- data/test/distributed_internals_test.rb +0 -79
- data/test/distributed_key_tags_test.rb +0 -52
- data/test/distributed_persistence_control_commands_test.rb +0 -26
- data/test/distributed_publish_subscribe_test.rb +0 -92
- data/test/distributed_remote_server_control_commands_test.rb +0 -66
- data/test/distributed_scripting_test.rb +0 -102
- data/test/distributed_sorting_test.rb +0 -20
- data/test/distributed_test.rb +0 -58
- data/test/distributed_transactions_test.rb +0 -32
- data/test/encoding_test.rb +0 -18
- data/test/error_replies_test.rb +0 -59
- data/test/fork_safety_test.rb +0 -65
- data/test/helper.rb +0 -232
- data/test/helper_test.rb +0 -24
- data/test/internals_test.rb +0 -417
- data/test/lint/blocking_commands.rb +0 -150
- data/test/lint/hashes.rb +0 -162
- data/test/lint/hyper_log_log.rb +0 -60
- data/test/lint/lists.rb +0 -143
- data/test/lint/sets.rb +0 -140
- data/test/lint/sorted_sets.rb +0 -316
- data/test/lint/strings.rb +0 -260
- data/test/lint/value_types.rb +0 -122
- data/test/persistence_control_commands_test.rb +0 -26
- data/test/pipelining_commands_test.rb +0 -242
- data/test/publish_subscribe_test.rb +0 -282
- data/test/remote_server_control_commands_test.rb +0 -118
- data/test/scanning_test.rb +0 -413
- data/test/scripting_test.rb +0 -78
- data/test/sentinel_command_test.rb +0 -80
- data/test/sentinel_test.rb +0 -255
- data/test/sorting_test.rb +0 -59
- data/test/ssl_test.rb +0 -73
- data/test/support/connection/hiredis.rb +0 -1
- data/test/support/connection/ruby.rb +0 -1
- data/test/support/connection/synchrony.rb +0 -17
- data/test/support/redis_mock.rb +0 -130
- data/test/support/ssl/gen_certs.sh +0 -31
- data/test/support/ssl/trusted-ca.crt +0 -25
- data/test/support/ssl/trusted-ca.key +0 -27
- data/test/support/ssl/trusted-cert.crt +0 -81
- data/test/support/ssl/trusted-cert.key +0 -28
- data/test/support/ssl/untrusted-ca.crt +0 -26
- data/test/support/ssl/untrusted-ca.key +0 -27
- data/test/support/ssl/untrusted-cert.crt +0 -82
- data/test/support/ssl/untrusted-cert.key +0 -28
- data/test/support/wire/synchrony.rb +0 -24
- data/test/support/wire/thread.rb +0 -5
- data/test/synchrony_driver.rb +0 -88
- data/test/test.conf.erb +0 -9
- data/test/thread_safety_test.rb +0 -62
- data/test/transactions_test.rb +0 -264
- data/test/unknown_commands_test.rb +0 -14
- 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
|
data/test/scanning_test.rb
DELETED
@@ -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
|