redis 4.0.0.rc1 → 4.5.1
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 +5 -5
- data/CHANGELOG.md +164 -3
- data/README.md +127 -18
- data/lib/redis/client.rb +164 -93
- data/lib/redis/cluster/command.rb +81 -0
- data/lib/redis/cluster/command_loader.rb +33 -0
- data/lib/redis/cluster/key_slot_converter.rb +72 -0
- data/lib/redis/cluster/node.rb +108 -0
- data/lib/redis/cluster/node_key.rb +31 -0
- data/lib/redis/cluster/node_loader.rb +37 -0
- data/lib/redis/cluster/option.rb +93 -0
- data/lib/redis/cluster/slot.rb +86 -0
- data/lib/redis/cluster/slot_loader.rb +49 -0
- data/lib/redis/cluster.rb +291 -0
- data/lib/redis/connection/command_helper.rb +5 -2
- data/lib/redis/connection/hiredis.rb +4 -3
- data/lib/redis/connection/registry.rb +2 -1
- data/lib/redis/connection/ruby.rb +125 -106
- data/lib/redis/connection/synchrony.rb +18 -5
- data/lib/redis/connection.rb +2 -0
- data/lib/redis/distributed.rb +995 -0
- data/lib/redis/errors.rb +48 -0
- data/lib/redis/hash_ring.rb +89 -0
- data/lib/redis/pipeline.rb +55 -9
- data/lib/redis/subscribe.rb +11 -12
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +1433 -381
- metadata +34 -141
- data/.gitignore +0 -16
- data/.travis/Gemfile +0 -11
- data/.travis.yml +0 -71
- data/.yardopts +0 -3
- data/Gemfile +0 -3
- 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/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel/sentinel.conf +0 -9
- data/examples/sentinel/start +0 -49
- data/examples/sentinel.rb +0 -41
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/makefile +0 -42
- data/redis.gemspec +0 -40
- data/test/bitpos_test.rb +0 -63
- data/test/blocking_commands_test.rb +0 -183
- data/test/client_test.rb +0 -59
- data/test/command_map_test.rb +0 -28
- data/test/commands_on_hashes_test.rb +0 -174
- data/test/commands_on_hyper_log_log_test.rb +0 -70
- data/test/commands_on_lists_test.rb +0 -154
- data/test/commands_on_sets_test.rb +0 -208
- data/test/commands_on_sorted_sets_test.rb +0 -444
- data/test/commands_on_strings_test.rb +0 -338
- data/test/commands_on_value_types_test.rb +0 -246
- data/test/connection_handling_test.rb +0 -275
- data/test/db/.gitkeep +0 -0
- data/test/encoding_test.rb +0 -14
- data/test/error_replies_test.rb +0 -57
- data/test/fork_safety_test.rb +0 -60
- data/test/helper.rb +0 -179
- data/test/helper_test.rb +0 -22
- data/test/internals_test.rb +0 -435
- data/test/persistence_control_commands_test.rb +0 -24
- data/test/pipelining_commands_test.rb +0 -238
- data/test/publish_subscribe_test.rb +0 -280
- data/test/remote_server_control_commands_test.rb +0 -175
- data/test/scanning_test.rb +0 -407
- data/test/scripting_test.rb +0 -76
- data/test/sentinel_command_test.rb +0 -78
- data/test/sentinel_test.rb +0 -253
- data/test/sorting_test.rb +0 -57
- data/test/ssl_test.rb +0 -69
- 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 -85
- data/test/test.conf.erb +0 -9
- data/test/thread_safety_test.rb +0 -60
- data/test/transactions_test.rb +0 -262
- data/test/unknown_commands_test.rb +0 -12
- data/test/url_param_test.rb +0 -136
@@ -1,275 +0,0 @@
|
|
1
|
-
require_relative "helper"
|
2
|
-
|
3
|
-
class TestConnectionHandling < Test::Unit::TestCase
|
4
|
-
|
5
|
-
include Helper::Client
|
6
|
-
|
7
|
-
def test_auth
|
8
|
-
commands = {
|
9
|
-
:auth => lambda { |password| $auth = password; "+OK" },
|
10
|
-
:get => lambda { |key| $auth == "secret" ? "$3\r\nbar" : "$-1" },
|
11
|
-
}
|
12
|
-
|
13
|
-
redis_mock(commands, :password => "secret") do |redis|
|
14
|
-
assert_equal "bar", redis.get("foo")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_id
|
19
|
-
commands = {
|
20
|
-
:client => lambda { |cmd, name| $name = [cmd, name]; "+OK" },
|
21
|
-
:ping => lambda { "+PONG" },
|
22
|
-
}
|
23
|
-
|
24
|
-
redis_mock(commands, :id => "client-name") do |redis|
|
25
|
-
assert_equal "PONG", redis.ping
|
26
|
-
end
|
27
|
-
|
28
|
-
assert_equal ["setname","client-name"], $name
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_ping
|
32
|
-
assert_equal "PONG", r.ping
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_select
|
36
|
-
r.set "foo", "bar"
|
37
|
-
|
38
|
-
r.select 14
|
39
|
-
assert_equal nil, r.get("foo")
|
40
|
-
|
41
|
-
r._client.disconnect
|
42
|
-
|
43
|
-
assert_equal nil, r.get("foo")
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_quit
|
47
|
-
r.quit
|
48
|
-
|
49
|
-
assert !r._client.connected?
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_close
|
53
|
-
quit = 0
|
54
|
-
|
55
|
-
commands = {
|
56
|
-
:quit => lambda do
|
57
|
-
quit += 1
|
58
|
-
"+OK"
|
59
|
-
end
|
60
|
-
}
|
61
|
-
|
62
|
-
redis_mock(commands) do |redis|
|
63
|
-
assert_equal 0, quit
|
64
|
-
|
65
|
-
redis.quit
|
66
|
-
|
67
|
-
assert_equal 1, quit
|
68
|
-
|
69
|
-
redis.ping
|
70
|
-
|
71
|
-
redis.close
|
72
|
-
|
73
|
-
assert_equal 1, quit
|
74
|
-
|
75
|
-
assert !redis.connected?
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_disconnect
|
80
|
-
quit = 0
|
81
|
-
|
82
|
-
commands = {
|
83
|
-
:quit => lambda do
|
84
|
-
quit += 1
|
85
|
-
"+OK"
|
86
|
-
end
|
87
|
-
}
|
88
|
-
|
89
|
-
redis_mock(commands) do |redis|
|
90
|
-
assert_equal 0, quit
|
91
|
-
|
92
|
-
redis.quit
|
93
|
-
|
94
|
-
assert_equal 1, quit
|
95
|
-
|
96
|
-
redis.ping
|
97
|
-
|
98
|
-
redis.disconnect!
|
99
|
-
|
100
|
-
assert_equal 1, quit
|
101
|
-
|
102
|
-
assert !redis.connected?
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_shutdown
|
107
|
-
commands = {
|
108
|
-
:shutdown => lambda { :exit }
|
109
|
-
}
|
110
|
-
|
111
|
-
redis_mock(commands) do |redis|
|
112
|
-
# SHUTDOWN does not reply: test that it does not raise here.
|
113
|
-
assert_equal nil, redis.shutdown
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_shutdown_with_error
|
118
|
-
connections = 0
|
119
|
-
commands = {
|
120
|
-
:select => lambda { |*_| connections += 1; "+OK\r\n" },
|
121
|
-
:connections => lambda { ":#{connections}\r\n" },
|
122
|
-
:shutdown => lambda { "-ERR could not shutdown\r\n" }
|
123
|
-
}
|
124
|
-
|
125
|
-
redis_mock(commands) do |redis|
|
126
|
-
connections = redis.connections
|
127
|
-
|
128
|
-
# SHUTDOWN replies with an error: test that it gets raised
|
129
|
-
assert_raise Redis::CommandError do
|
130
|
-
redis.shutdown
|
131
|
-
end
|
132
|
-
|
133
|
-
# The connection should remain in tact
|
134
|
-
assert_equal connections, redis.connections
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_shutdown_from_pipeline
|
139
|
-
commands = {
|
140
|
-
:shutdown => lambda { :exit }
|
141
|
-
}
|
142
|
-
|
143
|
-
redis_mock(commands) do |redis|
|
144
|
-
result = redis.pipelined do
|
145
|
-
redis.shutdown
|
146
|
-
end
|
147
|
-
|
148
|
-
assert_equal nil, result
|
149
|
-
assert !redis._client.connected?
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_shutdown_with_error_from_pipeline
|
154
|
-
connections = 0
|
155
|
-
commands = {
|
156
|
-
:select => lambda { |*_| connections += 1; "+OK\r\n" },
|
157
|
-
:connections => lambda { ":#{connections}\r\n" },
|
158
|
-
:shutdown => lambda { "-ERR could not shutdown\r\n" }
|
159
|
-
}
|
160
|
-
|
161
|
-
redis_mock(commands) do |redis|
|
162
|
-
connections = redis.connections
|
163
|
-
|
164
|
-
# SHUTDOWN replies with an error: test that it gets raised
|
165
|
-
assert_raise Redis::CommandError do
|
166
|
-
redis.pipelined do
|
167
|
-
redis.shutdown
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# The connection should remain in tact
|
172
|
-
assert_equal connections, redis.connections
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def test_shutdown_from_multi_exec
|
177
|
-
commands = {
|
178
|
-
:multi => lambda { "+OK\r\n" },
|
179
|
-
:shutdown => lambda { "+QUEUED\r\n" },
|
180
|
-
:exec => lambda { :exit }
|
181
|
-
}
|
182
|
-
|
183
|
-
redis_mock(commands) do |redis|
|
184
|
-
result = redis.multi do
|
185
|
-
redis.shutdown
|
186
|
-
end
|
187
|
-
|
188
|
-
assert_equal nil, result
|
189
|
-
assert !redis._client.connected?
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def test_shutdown_with_error_from_multi_exec
|
194
|
-
connections = 0
|
195
|
-
commands = {
|
196
|
-
:select => lambda { |*_| connections += 1; "+OK\r\n" },
|
197
|
-
:connections => lambda { ":#{connections}\r\n" },
|
198
|
-
:multi => lambda { "+OK\r\n" },
|
199
|
-
:shutdown => lambda { "+QUEUED\r\n" },
|
200
|
-
:exec => lambda { "*1\r\n-ERR could not shutdown\r\n" }
|
201
|
-
}
|
202
|
-
|
203
|
-
redis_mock(commands) do |redis|
|
204
|
-
connections = redis.connections
|
205
|
-
|
206
|
-
# SHUTDOWN replies with an error: test that it gets returned
|
207
|
-
# We should test for Redis::CommandError here, but hiredis doesn't yet do
|
208
|
-
# custom error classes.
|
209
|
-
err = nil
|
210
|
-
|
211
|
-
begin
|
212
|
-
redis.multi { redis.shutdown }
|
213
|
-
rescue => err
|
214
|
-
end
|
215
|
-
|
216
|
-
assert err.kind_of?(StandardError)
|
217
|
-
|
218
|
-
# The connection should remain intact
|
219
|
-
assert_equal connections, redis.connections
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_slaveof
|
224
|
-
redis_mock(:slaveof => lambda { |host, port| "+SLAVEOF #{host} #{port}" }) do |redis|
|
225
|
-
assert_equal "SLAVEOF somehost 6381", redis.slaveof("somehost", 6381)
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def test_bgrewriteaof
|
230
|
-
redis_mock(:bgrewriteaof => lambda { "+BGREWRITEAOF" }) do |redis|
|
231
|
-
assert_equal "BGREWRITEAOF", redis.bgrewriteaof
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_config_get
|
236
|
-
assert r.config(:get, "*")["timeout"] != nil
|
237
|
-
|
238
|
-
config = r.config(:get, "timeout")
|
239
|
-
assert_equal ["timeout"], config.keys
|
240
|
-
assert config.values.compact.size > 0
|
241
|
-
end
|
242
|
-
|
243
|
-
def test_config_set
|
244
|
-
begin
|
245
|
-
assert_equal "OK", r.config(:set, "timeout", 200)
|
246
|
-
assert_equal "200", r.config(:get, "*")["timeout"]
|
247
|
-
|
248
|
-
assert_equal "OK", r.config(:set, "timeout", 100)
|
249
|
-
assert_equal "100", r.config(:get, "*")["timeout"]
|
250
|
-
ensure
|
251
|
-
r.config :set, "timeout", 300
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
driver(:ruby, :hiredis) do
|
256
|
-
def test_consistency_on_multithreaded_env
|
257
|
-
t = nil
|
258
|
-
|
259
|
-
commands = {
|
260
|
-
:set => lambda { |key, value| t.kill; "+OK\r\n" },
|
261
|
-
:incr => lambda { |key| ":1\r\n" },
|
262
|
-
}
|
263
|
-
|
264
|
-
redis_mock(commands) do |redis|
|
265
|
-
t = Thread.new do
|
266
|
-
redis.set("foo", "bar")
|
267
|
-
end
|
268
|
-
|
269
|
-
t.join
|
270
|
-
|
271
|
-
assert_equal 1, redis.incr("baz")
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
data/test/db/.gitkeep
DELETED
File without changes
|
data/test/encoding_test.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require_relative "helper"
|
2
|
-
|
3
|
-
class TestEncoding < Test::Unit::TestCase
|
4
|
-
|
5
|
-
include Helper::Client
|
6
|
-
|
7
|
-
def test_returns_properly_encoded_strings
|
8
|
-
with_external_encoding("UTF-8") do
|
9
|
-
r.set "foo", "שלום"
|
10
|
-
|
11
|
-
assert_equal "Shalom שלום", "Shalom " + r.get("foo")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/test/error_replies_test.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require_relative "helper"
|
2
|
-
|
3
|
-
class TestErrorReplies < Test::Unit::TestCase
|
4
|
-
|
5
|
-
include Helper::Client
|
6
|
-
|
7
|
-
# Every test shouldn't disconnect from the server. Also, when error replies are
|
8
|
-
# in play, the protocol should never get into an invalid state where there are
|
9
|
-
# pending replies in the connection. Calling INFO after every test ensures that
|
10
|
-
# the protocol is still in a valid state.
|
11
|
-
def with_reconnection_check
|
12
|
-
before = r.info["total_connections_received"]
|
13
|
-
yield(r)
|
14
|
-
after = r.info["total_connections_received"]
|
15
|
-
ensure
|
16
|
-
assert_equal before, after
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_error_reply_for_single_command
|
20
|
-
with_reconnection_check do
|
21
|
-
begin
|
22
|
-
r.unknown_command
|
23
|
-
rescue => ex
|
24
|
-
ensure
|
25
|
-
assert ex.message =~ /unknown command/i
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_raise_first_error_reply_in_pipeline
|
31
|
-
with_reconnection_check do
|
32
|
-
begin
|
33
|
-
r.pipelined do
|
34
|
-
r.set("foo", "s1")
|
35
|
-
r.incr("foo") # not an integer
|
36
|
-
r.lpush("foo", "value") # wrong kind of value
|
37
|
-
end
|
38
|
-
rescue => ex
|
39
|
-
ensure
|
40
|
-
assert ex.message =~ /not an integer/i
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_recover_from_raise_in__call_loop
|
46
|
-
with_reconnection_check do
|
47
|
-
begin
|
48
|
-
r._client.call_loop([:invalid_monitor]) do
|
49
|
-
assert false # Should never be executed
|
50
|
-
end
|
51
|
-
rescue => ex
|
52
|
-
ensure
|
53
|
-
assert ex.message =~ /unknown command/i
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/test/fork_safety_test.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require_relative "helper"
|
2
|
-
|
3
|
-
class TestForkSafety < Test::Unit::TestCase
|
4
|
-
|
5
|
-
include Helper::Client
|
6
|
-
|
7
|
-
driver(:ruby, :hiredis) do
|
8
|
-
def test_fork_safety
|
9
|
-
redis = Redis.new(OPTIONS)
|
10
|
-
redis.set "foo", 1
|
11
|
-
|
12
|
-
child_pid = fork do
|
13
|
-
begin
|
14
|
-
# InheritedError triggers a reconnect,
|
15
|
-
# so we need to disable reconnects to force
|
16
|
-
# the exception bubble up
|
17
|
-
redis.without_reconnect do
|
18
|
-
redis.set "foo", 2
|
19
|
-
end
|
20
|
-
rescue Redis::InheritedError
|
21
|
-
exit 127
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
_, status = Process.wait2(child_pid)
|
26
|
-
|
27
|
-
assert_equal 127, status.exitstatus
|
28
|
-
assert_equal "1", redis.get("foo")
|
29
|
-
|
30
|
-
rescue NotImplementedError => error
|
31
|
-
raise unless error.message =~ /fork is not available/
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_fork_safety_with_enabled_inherited_socket
|
35
|
-
redis = Redis.new(OPTIONS.merge(:inherit_socket => true))
|
36
|
-
redis.set "foo", 1
|
37
|
-
|
38
|
-
child_pid = fork do
|
39
|
-
begin
|
40
|
-
# InheritedError triggers a reconnect,
|
41
|
-
# so we need to disable reconnects to force
|
42
|
-
# the exception bubble up
|
43
|
-
redis.without_reconnect do
|
44
|
-
redis.set "foo", 2
|
45
|
-
end
|
46
|
-
rescue Redis::InheritedError
|
47
|
-
exit 127
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
_, status = Process.wait2(child_pid)
|
52
|
-
|
53
|
-
assert_equal 0, status.exitstatus
|
54
|
-
assert_equal "2", redis.get("foo")
|
55
|
-
|
56
|
-
rescue NotImplementedError => error
|
57
|
-
raise unless error.message =~ /fork is not available/
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/test/helper.rb
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
require "test/unit"
|
2
|
-
require "logger"
|
3
|
-
require "stringio"
|
4
|
-
|
5
|
-
$VERBOSE = true
|
6
|
-
|
7
|
-
ENV["DRIVER"] ||= "ruby"
|
8
|
-
|
9
|
-
require_relative "../lib/redis"
|
10
|
-
require_relative "../lib/redis/connection/#{ENV["DRIVER"]}"
|
11
|
-
|
12
|
-
require_relative "support/redis_mock"
|
13
|
-
require_relative "support/connection/#{ENV["DRIVER"]}"
|
14
|
-
|
15
|
-
PORT = 6381
|
16
|
-
OPTIONS = {:port => PORT, :db => 15, :timeout => Float(ENV["TIMEOUT"] || 0.1)}
|
17
|
-
NODES = ["redis://127.0.0.1:#{PORT}/15"]
|
18
|
-
|
19
|
-
def init(redis)
|
20
|
-
begin
|
21
|
-
redis.select 14
|
22
|
-
redis.flushdb
|
23
|
-
redis.select 15
|
24
|
-
redis.flushdb
|
25
|
-
redis
|
26
|
-
rescue Redis::CannotConnectError
|
27
|
-
puts <<-EOS
|
28
|
-
|
29
|
-
Cannot connect to Redis.
|
30
|
-
|
31
|
-
Make sure Redis is running on localhost, port #{PORT}.
|
32
|
-
This testing suite connects to the database 15.
|
33
|
-
|
34
|
-
Try this once:
|
35
|
-
|
36
|
-
$ make clean
|
37
|
-
|
38
|
-
Then run the build again:
|
39
|
-
|
40
|
-
$ make
|
41
|
-
|
42
|
-
EOS
|
43
|
-
exit 1
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def driver(*drivers, &blk)
|
48
|
-
if drivers.map(&:to_s).include?(ENV["DRIVER"])
|
49
|
-
class_eval(&blk)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
module Helper
|
54
|
-
|
55
|
-
def run(runner)
|
56
|
-
if respond_to?(:around)
|
57
|
-
around { super(runner) }
|
58
|
-
else
|
59
|
-
super
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def silent
|
64
|
-
verbose, $VERBOSE = $VERBOSE, false
|
65
|
-
|
66
|
-
begin
|
67
|
-
yield
|
68
|
-
ensure
|
69
|
-
$VERBOSE = verbose
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def with_external_encoding(encoding)
|
74
|
-
original_encoding = Encoding.default_external
|
75
|
-
|
76
|
-
begin
|
77
|
-
silent { Encoding.default_external = Encoding.find(encoding) }
|
78
|
-
yield
|
79
|
-
ensure
|
80
|
-
silent { Encoding.default_external = original_encoding }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class Version
|
85
|
-
|
86
|
-
include Comparable
|
87
|
-
|
88
|
-
attr :parts
|
89
|
-
|
90
|
-
def initialize(v)
|
91
|
-
case v
|
92
|
-
when Version
|
93
|
-
@parts = v.parts
|
94
|
-
else
|
95
|
-
@parts = v.to_s.split(".")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def <=>(other)
|
100
|
-
other = Version.new(other)
|
101
|
-
length = [self.parts.length, other.parts.length].max
|
102
|
-
length.times do |i|
|
103
|
-
a, b = self.parts[i], other.parts[i]
|
104
|
-
|
105
|
-
return -1 if a.nil?
|
106
|
-
return +1 if b.nil?
|
107
|
-
return a.to_i <=> b.to_i if a != b
|
108
|
-
end
|
109
|
-
|
110
|
-
0
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
module Generic
|
115
|
-
|
116
|
-
include Helper
|
117
|
-
|
118
|
-
attr_reader :log
|
119
|
-
attr_reader :redis
|
120
|
-
|
121
|
-
alias :r :redis
|
122
|
-
|
123
|
-
def setup
|
124
|
-
@log = StringIO.new
|
125
|
-
@redis = init _new_client
|
126
|
-
|
127
|
-
# Run GC to make sure orphaned connections are closed.
|
128
|
-
GC.start
|
129
|
-
end
|
130
|
-
|
131
|
-
def teardown
|
132
|
-
@redis.quit if @redis
|
133
|
-
end
|
134
|
-
|
135
|
-
def redis_mock(commands, options = {}, &blk)
|
136
|
-
RedisMock.start(commands, options) do |port|
|
137
|
-
yield _new_client(options.merge(:port => port))
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def redis_mock_with_handler(handler, options = {}, &blk)
|
142
|
-
RedisMock.start_with_handler(handler, options) do |port|
|
143
|
-
yield _new_client(options.merge(:port => port))
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def assert_in_range(range, value)
|
148
|
-
assert range.include?(value), "expected #{value} to be in #{range.inspect}"
|
149
|
-
end
|
150
|
-
|
151
|
-
def target_version(target)
|
152
|
-
if version < target
|
153
|
-
skip("Requires Redis > #{target}") if respond_to?(:skip)
|
154
|
-
else
|
155
|
-
yield
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
module Client
|
161
|
-
|
162
|
-
include Generic
|
163
|
-
|
164
|
-
def version
|
165
|
-
Version.new(redis.info["redis_version"])
|
166
|
-
end
|
167
|
-
|
168
|
-
private
|
169
|
-
|
170
|
-
def _format_options(options)
|
171
|
-
OPTIONS.merge(:logger => ::Logger.new(@log)).merge(options)
|
172
|
-
end
|
173
|
-
|
174
|
-
def _new_client(options = {})
|
175
|
-
Redis.new(_format_options(options).merge(:driver => ENV["DRIVER"]))
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
end
|
data/test/helper_test.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative "helper"
|
2
|
-
|
3
|
-
class TestHelper < Test::Unit::TestCase
|
4
|
-
|
5
|
-
include Helper
|
6
|
-
|
7
|
-
def test_version_comparison
|
8
|
-
v = Version.new("2.0.1")
|
9
|
-
|
10
|
-
assert v > "1"
|
11
|
-
assert v > "2"
|
12
|
-
assert v < "3"
|
13
|
-
assert v < "10"
|
14
|
-
|
15
|
-
assert v < "2.1"
|
16
|
-
assert v < "2.0.2"
|
17
|
-
assert v < "2.0.1.1"
|
18
|
-
assert v < "2.0.10"
|
19
|
-
|
20
|
-
assert v == "2.0.1"
|
21
|
-
end
|
22
|
-
end
|