redis 3.2.0 → 4.6.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 (133) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +278 -15
  3. data/README.md +260 -76
  4. data/lib/redis/client.rb +239 -115
  5. data/lib/redis/cluster/command.rb +79 -0
  6. data/lib/redis/cluster/command_loader.rb +33 -0
  7. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  8. data/lib/redis/cluster/node.rb +120 -0
  9. data/lib/redis/cluster/node_key.rb +31 -0
  10. data/lib/redis/cluster/node_loader.rb +37 -0
  11. data/lib/redis/cluster/option.rb +93 -0
  12. data/lib/redis/cluster/slot.rb +86 -0
  13. data/lib/redis/cluster/slot_loader.rb +49 -0
  14. data/lib/redis/cluster.rb +315 -0
  15. data/lib/redis/commands/bitmaps.rb +63 -0
  16. data/lib/redis/commands/cluster.rb +45 -0
  17. data/lib/redis/commands/connection.rb +58 -0
  18. data/lib/redis/commands/geo.rb +84 -0
  19. data/lib/redis/commands/hashes.rb +251 -0
  20. data/lib/redis/commands/hyper_log_log.rb +37 -0
  21. data/lib/redis/commands/keys.rb +411 -0
  22. data/lib/redis/commands/lists.rb +289 -0
  23. data/lib/redis/commands/pubsub.rb +72 -0
  24. data/lib/redis/commands/scripting.rb +114 -0
  25. data/lib/redis/commands/server.rb +188 -0
  26. data/lib/redis/commands/sets.rb +207 -0
  27. data/lib/redis/commands/sorted_sets.rb +804 -0
  28. data/lib/redis/commands/streams.rb +382 -0
  29. data/lib/redis/commands/strings.rb +313 -0
  30. data/lib/redis/commands/transactions.rb +92 -0
  31. data/lib/redis/commands.rb +242 -0
  32. data/lib/redis/connection/command_helper.rb +7 -10
  33. data/lib/redis/connection/hiredis.rb +11 -6
  34. data/lib/redis/connection/registry.rb +2 -1
  35. data/lib/redis/connection/ruby.rb +173 -64
  36. data/lib/redis/connection/synchrony.rb +32 -8
  37. data/lib/redis/connection.rb +3 -1
  38. data/lib/redis/distributed.rb +233 -74
  39. data/lib/redis/errors.rb +48 -0
  40. data/lib/redis/hash_ring.rb +30 -72
  41. data/lib/redis/pipeline.rb +145 -12
  42. data/lib/redis/subscribe.rb +20 -13
  43. data/lib/redis/version.rb +3 -1
  44. data/lib/redis.rb +171 -2476
  45. metadata +71 -165
  46. data/.gitignore +0 -15
  47. data/.travis/Gemfile +0 -11
  48. data/.travis.yml +0 -54
  49. data/.yardopts +0 -3
  50. data/Gemfile +0 -4
  51. data/Rakefile +0 -68
  52. data/benchmarking/logging.rb +0 -71
  53. data/benchmarking/pipeline.rb +0 -51
  54. data/benchmarking/speed.rb +0 -21
  55. data/benchmarking/suite.rb +0 -24
  56. data/benchmarking/worker.rb +0 -71
  57. data/examples/basic.rb +0 -15
  58. data/examples/consistency.rb +0 -114
  59. data/examples/dist_redis.rb +0 -43
  60. data/examples/incr-decr.rb +0 -17
  61. data/examples/list.rb +0 -26
  62. data/examples/pubsub.rb +0 -37
  63. data/examples/sentinel/sentinel.conf +0 -9
  64. data/examples/sentinel/start +0 -49
  65. data/examples/sentinel.rb +0 -41
  66. data/examples/sets.rb +0 -36
  67. data/examples/unicorn/config.ru +0 -3
  68. data/examples/unicorn/unicorn.rb +0 -20
  69. data/redis.gemspec +0 -43
  70. data/test/bitpos_test.rb +0 -69
  71. data/test/blocking_commands_test.rb +0 -42
  72. data/test/command_map_test.rb +0 -30
  73. data/test/commands_on_hashes_test.rb +0 -21
  74. data/test/commands_on_hyper_log_log_test.rb +0 -21
  75. data/test/commands_on_lists_test.rb +0 -20
  76. data/test/commands_on_sets_test.rb +0 -77
  77. data/test/commands_on_sorted_sets_test.rb +0 -123
  78. data/test/commands_on_strings_test.rb +0 -101
  79. data/test/commands_on_value_types_test.rb +0 -131
  80. data/test/connection_handling_test.rb +0 -189
  81. data/test/db/.gitkeep +0 -0
  82. data/test/distributed_blocking_commands_test.rb +0 -46
  83. data/test/distributed_commands_on_hashes_test.rb +0 -10
  84. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  85. data/test/distributed_commands_on_lists_test.rb +0 -22
  86. data/test/distributed_commands_on_sets_test.rb +0 -83
  87. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  88. data/test/distributed_commands_on_strings_test.rb +0 -59
  89. data/test/distributed_commands_on_value_types_test.rb +0 -95
  90. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  91. data/test/distributed_connection_handling_test.rb +0 -23
  92. data/test/distributed_internals_test.rb +0 -70
  93. data/test/distributed_key_tags_test.rb +0 -52
  94. data/test/distributed_persistence_control_commands_test.rb +0 -26
  95. data/test/distributed_publish_subscribe_test.rb +0 -92
  96. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  97. data/test/distributed_scripting_test.rb +0 -102
  98. data/test/distributed_sorting_test.rb +0 -20
  99. data/test/distributed_test.rb +0 -58
  100. data/test/distributed_transactions_test.rb +0 -32
  101. data/test/encoding_test.rb +0 -18
  102. data/test/error_replies_test.rb +0 -59
  103. data/test/fork_safety_test.rb +0 -65
  104. data/test/helper.rb +0 -232
  105. data/test/helper_test.rb +0 -24
  106. data/test/internals_test.rb +0 -434
  107. data/test/lint/blocking_commands.rb +0 -150
  108. data/test/lint/hashes.rb +0 -162
  109. data/test/lint/hyper_log_log.rb +0 -60
  110. data/test/lint/lists.rb +0 -143
  111. data/test/lint/sets.rb +0 -125
  112. data/test/lint/sorted_sets.rb +0 -238
  113. data/test/lint/strings.rb +0 -260
  114. data/test/lint/value_types.rb +0 -122
  115. data/test/persistence_control_commands_test.rb +0 -26
  116. data/test/pipelining_commands_test.rb +0 -242
  117. data/test/publish_subscribe_test.rb +0 -210
  118. data/test/remote_server_control_commands_test.rb +0 -117
  119. data/test/scanning_test.rb +0 -413
  120. data/test/scripting_test.rb +0 -78
  121. data/test/sorting_test.rb +0 -59
  122. data/test/support/connection/hiredis.rb +0 -1
  123. data/test/support/connection/ruby.rb +0 -1
  124. data/test/support/connection/synchrony.rb +0 -17
  125. data/test/support/redis_mock.rb +0 -115
  126. data/test/support/wire/synchrony.rb +0 -24
  127. data/test/support/wire/thread.rb +0 -5
  128. data/test/synchrony_driver.rb +0 -88
  129. data/test/test.conf +0 -9
  130. data/test/thread_safety_test.rb +0 -32
  131. data/test/transactions_test.rb +0 -264
  132. data/test/unknown_commands_test.rb +0 -14
  133. data/test/url_param_test.rb +0 -132
data/test/helper.rb DELETED
@@ -1,232 +0,0 @@
1
- $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
2
- $:.unshift File.expand_path(File.dirname(__FILE__))
3
-
4
- require "test/unit"
5
- require "logger"
6
- require "stringio"
7
-
8
- (class Random; def self.rand(*args) super end; end) unless defined?(Random)
9
-
10
- begin
11
- require "ruby-debug"
12
- rescue LoadError
13
- end
14
-
15
- $VERBOSE = true
16
-
17
- ENV["conn"] ||= "ruby"
18
-
19
- require "redis"
20
- require "redis/distributed"
21
- require "redis/connection/#{ENV["conn"]}"
22
-
23
- require "support/redis_mock"
24
- require "support/connection/#{ENV["conn"]}"
25
-
26
- PORT = 6381
27
- OPTIONS = {:port => PORT, :db => 15, :timeout => Float(ENV["TIMEOUT"] || 0.1)}
28
- NODES = ["redis://127.0.0.1:#{PORT}/15"]
29
-
30
- def init(redis)
31
- begin
32
- redis.select 14
33
- redis.flushdb
34
- redis.select 15
35
- redis.flushdb
36
- redis
37
- rescue Redis::CannotConnectError
38
- puts <<-EOS
39
-
40
- Cannot connect to Redis.
41
-
42
- Make sure Redis is running on localhost, port #{PORT}.
43
- This testing suite connects to the database 15.
44
-
45
- Try this once:
46
-
47
- $ rake clean
48
-
49
- Then run the build again:
50
-
51
- $ rake
52
-
53
- EOS
54
- exit 1
55
- end
56
- end
57
-
58
- def driver(*drivers, &blk)
59
- if drivers.map(&:to_s).include?(ENV["conn"])
60
- class_eval(&blk)
61
- end
62
- end
63
-
64
- module Helper
65
-
66
- def run(runner)
67
- if respond_to?(:around)
68
- around { super(runner) }
69
- else
70
- super
71
- end
72
- end
73
-
74
- def silent
75
- verbose, $VERBOSE = $VERBOSE, false
76
-
77
- begin
78
- yield
79
- ensure
80
- $VERBOSE = verbose
81
- end
82
- end
83
-
84
- def with_external_encoding(encoding)
85
- original_encoding = Encoding.default_external
86
-
87
- begin
88
- silent { Encoding.default_external = Encoding.find(encoding) }
89
- yield
90
- ensure
91
- silent { Encoding.default_external = original_encoding }
92
- end
93
- end
94
-
95
- def try_encoding(encoding, &block)
96
- if defined?(Encoding)
97
- with_external_encoding(encoding, &block)
98
- else
99
- yield
100
- end
101
- end
102
-
103
- class Version
104
-
105
- include Comparable
106
-
107
- attr :parts
108
-
109
- def initialize(v)
110
- case v
111
- when Version
112
- @parts = v.parts
113
- else
114
- @parts = v.to_s.split(".")
115
- end
116
- end
117
-
118
- def <=>(other)
119
- other = Version.new(other)
120
- length = [self.parts.length, other.parts.length].max
121
- length.times do |i|
122
- a, b = self.parts[i], other.parts[i]
123
-
124
- return -1 if a.nil?
125
- return +1 if b.nil?
126
- return a.to_i <=> b.to_i if a != b
127
- end
128
-
129
- 0
130
- end
131
- end
132
-
133
- module Generic
134
-
135
- include Helper
136
-
137
- attr_reader :log
138
- attr_reader :redis
139
-
140
- alias :r :redis
141
-
142
- def setup
143
- @log = StringIO.new
144
- @redis = init _new_client
145
-
146
- # Run GC to make sure orphaned connections are closed.
147
- GC.start
148
- end
149
-
150
- def teardown
151
- @redis.quit if @redis
152
- end
153
-
154
- def redis_mock(commands, options = {}, &blk)
155
- RedisMock.start(commands, options) do |port|
156
- yield _new_client(options.merge(:port => port))
157
- end
158
- end
159
-
160
- def redis_mock_with_handler(handler, options = {}, &blk)
161
- RedisMock.start_with_handler(handler, options) do |port|
162
- yield _new_client(options.merge(:port => port))
163
- end
164
- end
165
-
166
- def assert_in_range(range, value)
167
- assert range.include?(value), "expected #{value} to be in #{range.inspect}"
168
- end
169
-
170
- def target_version(target)
171
- if version < target
172
- skip("Requires Redis > #{target}") if respond_to?(:skip)
173
- else
174
- yield
175
- end
176
- end
177
- end
178
-
179
- module Client
180
-
181
- include Generic
182
-
183
- def version
184
- Version.new(redis.info["redis_version"])
185
- end
186
-
187
- private
188
-
189
- def _format_options(options)
190
- OPTIONS.merge(:logger => ::Logger.new(@log)).merge(options)
191
- end
192
-
193
- def _new_client(options = {})
194
- Redis.new(_format_options(options).merge(:driver => ENV["conn"]))
195
- end
196
- end
197
-
198
- module Distributed
199
-
200
- include Generic
201
-
202
- def version
203
- Version.new(redis.info.first["redis_version"])
204
- end
205
-
206
- private
207
-
208
- def _format_options(options)
209
- {
210
- :timeout => OPTIONS[:timeout],
211
- :logger => ::Logger.new(@log),
212
- }.merge(options)
213
- end
214
-
215
- def _new_client(options = {})
216
- Redis::Distributed.new(NODES, _format_options(options).merge(:driver => ENV["conn"]))
217
- end
218
- end
219
-
220
- # Basic support for `skip` in 1.8.x
221
- # Note: YOU MUST use `return skip(message)` in order to appropriately bail
222
- # from a running test.
223
- module Skipable
224
- Skipped = Class.new(RuntimeError)
225
-
226
- def skip(message = nil, bt = caller)
227
- return super if defined?(super)
228
-
229
- $stderr.puts("SKIPPED: #{self} #{message || 'no reason given'}")
230
- end
231
- end
232
- end
data/test/helper_test.rb DELETED
@@ -1,24 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- class TestHelper < Test::Unit::TestCase
6
-
7
- include Helper
8
-
9
- def test_version_comparison
10
- v = Version.new("2.0.1")
11
-
12
- assert v > "1"
13
- assert v > "2"
14
- assert v < "3"
15
- assert v < "10"
16
-
17
- assert v < "2.1"
18
- assert v < "2.0.2"
19
- assert v < "2.0.1.1"
20
- assert v < "2.0.10"
21
-
22
- assert v == "2.0.1"
23
- end
24
- end
@@ -1,434 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- class TestInternals < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_logger
10
- r.ping
11
-
12
- assert log.string["[Redis] command=PING"]
13
- assert log.string =~ /\[Redis\] call_time=\d+\.\d+ ms/
14
- end
15
-
16
- def test_logger_with_pipelining
17
- r.pipelined do
18
- r.set "foo", "bar"
19
- r.get "foo"
20
- end
21
-
22
- assert log.string[" command=SET args=\"foo\" \"bar\""]
23
- assert log.string[" command=GET args=\"foo\""]
24
- end
25
-
26
- def test_recovers_from_failed_commands
27
- # See https://github.com/redis/redis-rb/issues#issue/28
28
-
29
- assert_raise(Redis::CommandError) do
30
- r.command_that_doesnt_exist
31
- end
32
-
33
- assert_nothing_raised do
34
- r.info
35
- end
36
- end
37
-
38
- def test_raises_on_protocol_errors
39
- redis_mock(:ping => lambda { |*_| "foo" }) do |redis|
40
- assert_raise(Redis::ProtocolError) do
41
- redis.ping
42
- end
43
- end
44
- end
45
-
46
- def test_provides_a_meaningful_inspect
47
- assert_equal "#<Redis client v#{Redis::VERSION} for redis://127.0.0.1:#{PORT}/15>", r.inspect
48
- end
49
-
50
- def test_redis_current
51
- assert_equal "127.0.0.1", Redis.current.client.host
52
- assert_equal 6379, Redis.current.client.port
53
- assert_equal 0, Redis.current.client.db
54
-
55
- Redis.current = Redis.new(OPTIONS.merge(:port => 6380, :db => 1))
56
-
57
- t = Thread.new do
58
- assert_equal "127.0.0.1", Redis.current.client.host
59
- assert_equal 6380, Redis.current.client.port
60
- assert_equal 1, Redis.current.client.db
61
- end
62
-
63
- t.join
64
-
65
- assert_equal "127.0.0.1", Redis.current.client.host
66
- assert_equal 6380, Redis.current.client.port
67
- assert_equal 1, Redis.current.client.db
68
- end
69
-
70
- def test_redis_connected?
71
- fresh_client = _new_client
72
- assert !fresh_client.connected?
73
-
74
- fresh_client.ping
75
- assert fresh_client.connected?
76
-
77
- fresh_client.quit
78
- assert !fresh_client.connected?
79
- end
80
-
81
- def test_default_id_with_host_and_port
82
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0))
83
- assert_equal "redis://host:1234/0", redis.client.id
84
- end
85
-
86
- def test_default_id_with_host_and_port_and_explicit_scheme
87
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0, :scheme => "foo"))
88
- assert_equal "redis://host:1234/0", redis.client.id
89
- end
90
-
91
- def test_default_id_with_path
92
- redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0))
93
- assert_equal "redis:///tmp/redis.sock/0", redis.client.id
94
- end
95
-
96
- def test_default_id_with_path_and_explicit_scheme
97
- redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0, :scheme => "foo"))
98
- assert_equal "redis:///tmp/redis.sock/0", redis.client.id
99
- end
100
-
101
- def test_override_id
102
- redis = Redis.new(OPTIONS.merge(:id => "test"))
103
- assert_equal redis.client.id, "test"
104
- end
105
-
106
- def test_timeout
107
- assert_nothing_raised do
108
- Redis.new(OPTIONS.merge(:timeout => 0))
109
- end
110
- end
111
-
112
- def test_id_inside_multi
113
- redis = Redis.new(OPTIONS)
114
- id = nil
115
-
116
- redis.multi do
117
- id = redis.id
118
- end
119
-
120
- assert_equal id, "redis://127.0.0.1:6381/15"
121
- end
122
-
123
- driver(:ruby) do
124
- def test_tcp_keepalive
125
- keepalive = {:time => 20, :intvl => 10, :probes => 5}
126
-
127
- redis = Redis.new(OPTIONS.merge(:tcp_keepalive => keepalive))
128
- redis.ping
129
-
130
- connection = redis.client.connection
131
- actual_keepalive = connection.get_tcp_keepalive
132
-
133
- [:time, :intvl, :probes].each do |key|
134
- if actual_keepalive.has_key?(key)
135
- assert_equal actual_keepalive[key], keepalive[key]
136
- end
137
- end
138
- end
139
- end
140
-
141
- def test_time
142
- target_version "2.5.4" do
143
- # Test that the difference between the time that Ruby reports and the time
144
- # that Redis reports is minimal (prevents the test from being racy).
145
- rv = r.time
146
-
147
- redis_usec = rv[0] * 1_000_000 + rv[1]
148
- ruby_usec = Integer(Time.now.to_f * 1_000_000)
149
-
150
- assert 500_000 > (ruby_usec - redis_usec).abs
151
- end
152
- end
153
-
154
- def test_connection_timeout
155
- assert_raise Redis::CannotConnectError do
156
- Redis.new(OPTIONS.merge(:host => "10.255.255.254", :timeout => 0.1)).ping
157
- end
158
- end
159
-
160
- def close_on_ping(seq, options = {})
161
- $request = 0
162
-
163
- command = lambda do
164
- idx = $request
165
- $request += 1
166
-
167
- rv = "+%d" % idx
168
- rv = nil if seq.include?(idx)
169
- rv
170
- end
171
-
172
- redis_mock({:ping => command}, {:timeout => 0.1}.merge(options)) do |redis|
173
- yield(redis)
174
- end
175
- end
176
-
177
- def test_retry_by_default
178
- close_on_ping([0]) do |redis|
179
- assert_equal "1", redis.ping
180
- end
181
- end
182
-
183
- def test_retry_when_wrapped_in_with_reconnect_true
184
- close_on_ping([0]) do |redis|
185
- redis.with_reconnect(true) do
186
- assert_equal "1", redis.ping
187
- end
188
- end
189
- end
190
-
191
- def test_dont_retry_when_wrapped_in_with_reconnect_false
192
- close_on_ping([0]) do |redis|
193
- assert_raise Redis::ConnectionError do
194
- redis.with_reconnect(false) do
195
- redis.ping
196
- end
197
- end
198
- end
199
- end
200
-
201
- def test_dont_retry_when_wrapped_in_without_reconnect
202
- close_on_ping([0]) do |redis|
203
- assert_raise Redis::ConnectionError do
204
- redis.without_reconnect do
205
- redis.ping
206
- end
207
- end
208
- end
209
- end
210
-
211
- def test_retry_only_once_when_read_raises_econnreset
212
- close_on_ping([0, 1]) do |redis|
213
- assert_raise Redis::ConnectionError do
214
- redis.ping
215
- end
216
-
217
- assert !redis.client.connected?
218
- end
219
- end
220
-
221
- def test_retry_with_custom_reconnect_attempts
222
- close_on_ping([0, 1], :reconnect_attempts => 2) do |redis|
223
- assert_equal "2", redis.ping
224
- end
225
- end
226
-
227
- def test_retry_with_custom_reconnect_attempts_can_still_fail
228
- close_on_ping([0, 1, 2], :reconnect_attempts => 2) do |redis|
229
- assert_raise Redis::ConnectionError do
230
- redis.ping
231
- end
232
-
233
- assert !redis.client.connected?
234
- end
235
- end
236
-
237
- def test_don_t_retry_when_second_read_in_pipeline_raises_econnreset
238
- close_on_ping([1]) do |redis|
239
- assert_raise Redis::ConnectionError do
240
- redis.pipelined do
241
- redis.ping
242
- redis.ping # Second #read times out
243
- end
244
- end
245
-
246
- assert !redis.client.connected?
247
- end
248
- end
249
-
250
- def close_on_connection(seq)
251
- $n = 0
252
-
253
- read_command = lambda do |session|
254
- Array.new(session.gets[1..-3].to_i) do
255
- bytes = session.gets[1..-3].to_i
256
- arg = session.read(bytes)
257
- session.read(2) # Discard \r\n
258
- arg
259
- end
260
- end
261
-
262
- handler = lambda do |session|
263
- n = $n
264
- $n += 1
265
-
266
- select = read_command.call(session)
267
- if select[0].downcase == "select"
268
- session.write("+OK\r\n")
269
- else
270
- raise "Expected SELECT"
271
- end
272
-
273
- if !seq.include?(n)
274
- while read_command.call(session)
275
- session.write("+#{n}\r\n")
276
- end
277
- end
278
- end
279
-
280
- redis_mock_with_handler(handler) do |redis|
281
- yield(redis)
282
- end
283
- end
284
-
285
- def test_retry_on_write_error_by_default
286
- close_on_connection([0]) do |redis|
287
- assert_equal "1", redis.client.call(["x" * 128 * 1024])
288
- end
289
- end
290
-
291
- def test_retry_on_write_error_when_wrapped_in_with_reconnect_true
292
- close_on_connection([0]) do |redis|
293
- redis.with_reconnect(true) do
294
- assert_equal "1", redis.client.call(["x" * 128 * 1024])
295
- end
296
- end
297
- end
298
-
299
- def test_dont_retry_on_write_error_when_wrapped_in_with_reconnect_false
300
- close_on_connection([0]) do |redis|
301
- assert_raise Redis::ConnectionError do
302
- redis.with_reconnect(false) do
303
- redis.client.call(["x" * 128 * 1024])
304
- end
305
- end
306
- end
307
- end
308
-
309
- def test_dont_retry_on_write_error_when_wrapped_in_without_reconnect
310
- close_on_connection([0]) do |redis|
311
- assert_raise Redis::ConnectionError do
312
- redis.without_reconnect do
313
- redis.client.call(["x" * 128 * 1024])
314
- end
315
- end
316
- end
317
- end
318
-
319
- def test_connecting_to_unix_domain_socket
320
- assert_nothing_raised do
321
- Redis.new(OPTIONS.merge(:path => "./test/db/redis.sock")).ping
322
- end
323
- end
324
-
325
- driver(:ruby, :hiredis) do
326
- def test_bubble_timeout_without_retrying
327
- serv = TCPServer.new(6380)
328
-
329
- redis = Redis.new(:port => 6380, :timeout => 0.1)
330
-
331
- assert_raise(Redis::TimeoutError) do
332
- redis.ping
333
- end
334
-
335
- ensure
336
- serv.close if serv
337
- end
338
- end
339
-
340
- def test_client_options
341
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => 1234, :db => 1, :scheme => "foo"))
342
-
343
- assert_equal "host", redis.client.options[:host]
344
- assert_equal 1234, redis.client.options[:port]
345
- assert_equal 1, redis.client.options[:db]
346
- assert_equal "foo", redis.client.options[:scheme]
347
- end
348
-
349
- def test_does_not_change_self_client_options
350
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => 1234, :db => 1, :scheme => "foo"))
351
- options = redis.client.options
352
-
353
- options[:host] << "new_host"
354
- options[:scheme] << "bar"
355
- options.merge!(:db => 0)
356
-
357
- assert_equal "host", redis.client.options[:host]
358
- assert_equal 1, redis.client.options[:db]
359
- assert_equal "foo", redis.client.options[:scheme]
360
- end
361
-
362
- def test_resolves_localhost
363
- assert_nothing_raised do
364
- Redis.new(OPTIONS.merge(:host => 'localhost')).ping
365
- end
366
- end
367
-
368
- class << self
369
- def af_family_supported(af)
370
- hosts = {
371
- Socket::AF_INET => "127.0.0.1",
372
- Socket::AF_INET6 => "::1",
373
- }
374
-
375
- begin
376
- s = Socket.new(af, Socket::SOCK_STREAM, 0)
377
- begin
378
- tries = 5
379
- begin
380
- sa = Socket.pack_sockaddr_in(1024 + Random.rand(63076), hosts[af])
381
- s.bind(sa)
382
- rescue Errno::EADDRINUSE
383
- tries -= 1
384
- retry if tries > 0
385
-
386
- raise
387
- end
388
- yield
389
- rescue Errno::EADDRNOTAVAIL
390
- ensure
391
- s.close
392
- end
393
- rescue Errno::ESOCKTNOSUPPORT
394
- end
395
- end
396
- end
397
-
398
- def af_test(host)
399
- commands = {
400
- :ping => lambda { |*_| "+pong" },
401
- }
402
-
403
- redis_mock(commands, :host => host) do |redis|
404
- assert_nothing_raised do
405
- redis.ping
406
- end
407
- end
408
- end
409
-
410
- driver(:ruby) do
411
- af_family_supported(Socket::AF_INET) do
412
- def test_connect_ipv4
413
- af_test("127.0.0.1")
414
- end
415
- end
416
- end
417
-
418
- driver(:ruby) do
419
- af_family_supported(Socket::AF_INET6) do
420
- def test_connect_ipv6
421
- af_test("::1")
422
- end
423
- end
424
- end
425
-
426
- def test_can_be_duped_to_create_a_new_connection
427
- clients = r.info["connected_clients"].to_i
428
-
429
- r2 = r.dup
430
- r2.ping
431
-
432
- assert_equal clients + 1, r.info["connected_clients"].to_i
433
- end
434
- end