Skip to content

Commit 8eb051a

Browse files
authored
Merge pull request rails#48967 from jdelStrother/distributed-redis-tests
Add test coverage for RedisCacheStore with Redis::Distributed / ConnectionPool
2 parents 7f8cdb1 + 1b3d884 commit 8eb051a

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

activesupport/lib/active_support/cache/redis_cache_store.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
end
1111

1212
require "connection_pool"
13+
require "active_support/core_ext/array/wrap"
1314
require "active_support/core_ext/hash/slice"
1415
require "active_support/core_ext/numeric/time"
1516
require "active_support/digest"
@@ -455,8 +456,8 @@ def change_counter(key, amount, options)
455456
def supports_expire_nx?
456457
return @supports_expire_nx if defined?(@supports_expire_nx)
457458

458-
redis_version = redis.then { |c| c.info("server").fetch("redis_version") }
459-
@supports_expire_nx = Gem::Version.new(redis_version) >= Gem::Version.new("7.0.0")
459+
redis_versions = redis.then { |c| Array.wrap(c.info("server")).pluck("redis_version") }
460+
@supports_expire_nx = redis_versions.all? { |v| Gem::Version.new(v) >= Gem::Version.new("7.0.0") }
460461
end
461462

462463
def failsafe(method, returning: nil)

activesupport/test/cache/stores/redis_cache_store_test.rb

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ def lookup_store(options = {})
151151

152152
teardown do
153153
@cache.clear
154-
@cache.redis.disconnect!
154+
@cache.redis.with do |r|
155+
r.respond_to?(:on_each_node, true) ? r.send(:on_each_node, :disconnect!) : r.disconnect!
156+
end
155157
end
156158
end
157159

@@ -169,15 +171,15 @@ class RedisCacheStoreCommonBehaviorTest < StoreTest
169171
include EncodedKeyCacheBehavior
170172

171173
def test_fetch_multi_uses_redis_mget
172-
assert_called(@cache.redis, :mget, returns: []) do
174+
assert_called(redis_backend, :mget, returns: []) do
173175
@cache.fetch_multi("a", "b", "c") do |key|
174176
key * 2
175177
end
176178
end
177179
end
178180

179181
def test_fetch_multi_with_namespace
180-
assert_called_with(@cache.redis, :mget, ["custom-namespace:a", "custom-namespace:b", "custom-namespace:c"], returns: []) do
182+
assert_called_with(redis_backend, :mget, ["custom-namespace:a", "custom-namespace:b", "custom-namespace:c"], returns: []) do
181183
@cache.fetch_multi("a", "b", "c", namespace: "custom-namespace") do |key|
182184
key * 2
183185
end
@@ -186,39 +188,53 @@ def test_fetch_multi_with_namespace
186188

187189
def test_write_expires_at
188190
@cache.write "key_with_expires_at", "bar", expires_at: 30.minutes.from_now
189-
assert @cache.redis.ttl("#{@namespace}:key_with_expires_at") > 0
191+
redis_backend do |r|
192+
assert r.ttl("#{@namespace}:key_with_expires_at") > 0
193+
end
190194
end
191195

192196
def test_increment_expires_in
193197
@cache.increment "foo", 1, expires_in: 60
194-
assert @cache.redis.exists?("#{@namespace}:foo")
195-
assert @cache.redis.ttl("#{@namespace}:foo") > 0
198+
redis_backend do |r|
199+
assert r.exists?("#{@namespace}:foo")
200+
assert r.ttl("#{@namespace}:foo") > 0
201+
end
196202

197203
# key and ttl exist
198-
@cache.redis.setex "#{@namespace}:bar", 120, 1
204+
redis_backend { |r| r.setex "#{@namespace}:bar", 120, 1 }
199205
@cache.increment "bar", 1, expires_in: 60
200-
assert @cache.redis.ttl("#{@namespace}:bar") > 60
206+
redis_backend do |r|
207+
assert r.ttl("#{@namespace}:bar") > 60
208+
end
201209

202210
# key exist but not have expire
203-
@cache.redis.set "#{@namespace}:dar", 10
211+
redis_backend { |r| r.set "#{@namespace}:dar", 10 }
204212
@cache.increment "dar", 1, expires_in: 60
205-
assert @cache.redis.ttl("#{@namespace}:dar") > 0
213+
redis_backend do |r|
214+
assert r.ttl("#{@namespace}:dar") > 0
215+
end
206216
end
207217

208218
def test_decrement_expires_in
209219
@cache.decrement "foo", 1, expires_in: 60
210-
assert @cache.redis.exists?("#{@namespace}:foo")
211-
assert @cache.redis.ttl("#{@namespace}:foo") > 0
220+
redis_backend do |r|
221+
assert r.exists?("#{@namespace}:foo")
222+
assert r.ttl("#{@namespace}:foo") > 0
223+
end
212224

213225
# key and ttl exist
214-
@cache.redis.setex "#{@namespace}:bar", 120, 1
226+
redis_backend { |r| r.setex "#{@namespace}:bar", 120, 1 }
215227
@cache.decrement "bar", 1, expires_in: 60
216-
assert @cache.redis.ttl("#{@namespace}:bar") > 60
228+
redis_backend do |r|
229+
assert r.ttl("#{@namespace}:bar") > 60
230+
end
217231

218232
# key exist but not have expire
219-
@cache.redis.set "#{@namespace}:dar", 10
233+
redis_backend { |r| r.set "#{@namespace}:dar", 10 }
220234
@cache.decrement "dar", 1, expires_in: 60
221-
assert @cache.redis.ttl("#{@namespace}:dar") > 0
235+
redis_backend do |r|
236+
assert r.ttl("#{@namespace}:dar") > 0
237+
end
222238
end
223239

224240
test "fetch caches nil" do
@@ -235,6 +251,19 @@ def test_decrement_expires_in
235251
assert_equal false, @cache.exist?("foo")
236252
end
237253
end
254+
255+
def redis_backend
256+
@cache.redis.with do |r|
257+
yield r if block_given?
258+
return r
259+
end
260+
end
261+
end
262+
263+
class RedisCacheStoreWithDistributedRedisTest < RedisCacheStoreCommonBehaviorTest
264+
def lookup_store(options = {})
265+
super(options.merge(pool: { size: 5 }, url: [ENV["REDIS_URL"] || "redis://localhost:6379/0"] * 2))
266+
end
238267
end
239268

240269
class ConnectionPoolBehaviorTest < StoreTest

0 commit comments

Comments
 (0)