redis-store-pika 1.9.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
1
+ require 'redis'
2
+ require 'redis/store/factory'
3
+ require 'redis/distributed_store'
4
+ require 'redis/store/namespace'
5
+ require 'redis/store/serialization'
6
+ require 'redis/store/version'
7
+ require 'redis/store/redis_version'
8
+ require 'redis/store/ttl'
9
+ require 'redis/store/interface'
10
+ require 'redis/store/redis_version'
11
+
12
+ class Redis
13
+ class Store < self
14
+ include Ttl, Interface, RedisVersion
15
+
16
+ def initialize(options = {})
17
+ orig_options = options.dup
18
+
19
+ _remove_unsupported_options(options)
20
+ # The options here is updated
21
+ super(options)
22
+
23
+ unless orig_options[:marshalling].nil?
24
+ puts %(
25
+ DEPRECATED: You are passing the :marshalling option, which has been
26
+ replaced with `serializer: Marshal` to support pluggable serialization
27
+ backends. To disable serialization (much like disabling marshalling),
28
+ pass `serializer: nil` in your configuration.
29
+
30
+ The :marshalling option will be removed for redis-store 2.0.
31
+ )
32
+ end
33
+
34
+ @serializer = orig_options.key?(:serializer) ? orig_options.delete(:serializer) : Marshal
35
+
36
+ unless orig_options[:marshalling].nil?
37
+ # `marshalling` only used here, might not be supported in `super`
38
+ @serializer = orig_options.delete(:marshalling) ? Marshal : nil
39
+ end
40
+
41
+ _extend_marshalling
42
+ _extend_namespace orig_options
43
+ end
44
+
45
+ def reconnect
46
+ @client.reconnect
47
+ end
48
+
49
+ def to_s
50
+ "Redis Client connected to #{location} against DB #{@client.db}"
51
+ end
52
+
53
+ def location
54
+ if @client.path
55
+ @client.path
56
+ else
57
+ h = @client.host
58
+ h = "[#{h}]" if h.include?(":")
59
+ "#{h}:#{@client.port}"
60
+ end
61
+ end
62
+
63
+ private
64
+ def _remove_unsupported_options(options)
65
+ return unless self.class.redis_client_defined?
66
+
67
+ # Unsupported keywords should be removed to avoid errors
68
+ # https://github.com/redis-rb/redis-client/blob/v0.13.0/lib/redis_client/config.rb#L21
69
+ options.delete(:raw)
70
+ options.delete(:serializer)
71
+ options.delete(:marshalling)
72
+ options.delete(:namespace)
73
+ options.delete(:scheme)
74
+ end
75
+
76
+ def _extend_marshalling
77
+ extend Serialization unless @serializer.nil?
78
+ end
79
+
80
+ def _extend_namespace(options)
81
+ @namespace = options[:namespace]
82
+ extend Namespace
83
+ end
84
+ end
85
+ end
@@ -0,0 +1 @@
1
+ require 'redis-store'
@@ -0,0 +1 @@
1
+ require 'redis/store'
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path('../lib', __FILE__)
4
+ require 'redis/store/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'redis-store-pika'
8
+ s.version = Redis::Store::VERSION
9
+ s.authors = ['Luca Guidi']
10
+ s.email = ['me@lucaguidi.com']
11
+ s.homepage = 'https://github.com/PikachuEXE/redis-store'
12
+ s.summary = 'Redis stores for Ruby frameworks'
13
+ s.description = 'Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks.'
14
+ s.post_install_message = "
15
+ This is a fork of official redis-store gem published to let people use fixes unavailable on official one yet.
16
+ Be sure to check updates from official redis-store gem sometimes in case the fixes here are merged there.
17
+ "
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.require_paths = ["lib"]
21
+ s.license = 'MIT'
22
+
23
+ s.add_dependency 'redis', '>= 4', '< 6'
24
+
25
+ s.add_development_dependency 'rake', '>= 12.3.3'
26
+ s.add_development_dependency 'bundler'
27
+ s.add_development_dependency 'mocha', '~> 2.1.0'
28
+ s.add_development_dependency 'minitest', '~> 5'
29
+ s.add_development_dependency 'git', '~> 1.2'
30
+ s.add_development_dependency 'pry-nav', '~> 0.2.4'
31
+ s.add_development_dependency 'pry', '~> 0.10.4'
32
+ s.add_development_dependency 'redis-store-testing'
33
+ s.add_development_dependency 'appraisal', '~> 2.0'
34
+ s.add_development_dependency 'rubocop', '~> 0.54'
35
+ end
@@ -0,0 +1,111 @@
1
+ require 'test_helper'
2
+
3
+ describe "Redis::DistributedStore" do
4
+ def setup
5
+ @dmr = Redis::DistributedStore.new [
6
+ { :host => "localhost", :port => "6380", :db => 0 },
7
+ { :host => "localhost", :port => "6381", :db => 0 }
8
+ ]
9
+ @rabbit = OpenStruct.new :name => "bunny"
10
+ @white_rabbit = OpenStruct.new :color => "white"
11
+ @dmr.set "rabbit", @rabbit
12
+ end
13
+
14
+ def teardown
15
+ @dmr.ring.nodes.each { |server| server.flushdb }
16
+ end
17
+
18
+ it "accepts connection params" do
19
+ dmr = Redis::DistributedStore.new [ :host => "localhost", :port => "6380", :db => "1" ]
20
+ _(dmr.ring.nodes.size).must_equal(1)
21
+ mr = dmr.ring.nodes.first
22
+ _(mr.to_s).must_equal("Redis Client connected to localhost:6380 against DB 1")
23
+ end
24
+
25
+ it "forces reconnection" do
26
+ @dmr.nodes.each do |node|
27
+ node.expects(:reconnect)
28
+ end
29
+
30
+ @dmr.reconnect
31
+ end
32
+
33
+ it "sets an object" do
34
+ @dmr.set "rabbit", @white_rabbit
35
+ _(@dmr.get("rabbit")).must_equal(@white_rabbit)
36
+ end
37
+
38
+ it "gets an object" do
39
+ _(@dmr.get("rabbit")).must_equal(@rabbit)
40
+ end
41
+
42
+ it "mget" do
43
+ @dmr.set "rabbit2", @white_rabbit
44
+ begin
45
+ @dmr.mget "rabbit", "rabbit2" do |rabbits|
46
+ rabbit, rabbit2 = rabbits
47
+ _(rabbits.length).must_equal(2)
48
+ _(rabbit).must_equal(@rabbit)
49
+ _(rabbit2).must_equal(@white_rabbit)
50
+ end
51
+ rescue Redis::Distributed::CannotDistribute
52
+ # Not supported on redis-rb < 4, and hence Ruby < 2.2.
53
+ end
54
+ end
55
+
56
+ it "mapped_mget" do
57
+ @dmr.set "rabbit2", @white_rabbit
58
+ begin
59
+ result = @dmr.mapped_mget("rabbit", "rabbit2")
60
+ _(result.keys).must_equal %w[ rabbit rabbit2 ]
61
+ _(result["rabbit"]).must_equal @rabbit
62
+ _(result["rabbit2"]).must_equal @white_rabbit
63
+ rescue Redis::Distributed::CannotDistribute
64
+ # Not supported on redis-rb < 4, and hence Ruby < 2.2.
65
+ end
66
+ end
67
+
68
+ it "passes through ring replica options" do
69
+ dmr = Redis::DistributedStore.new [
70
+ { :host => "localhost", :port => "6380", :db => 0 },
71
+ { :host => "localhost", :port => "6381", :db => 0 }
72
+ ], replicas: 1024
73
+ _(dmr.ring.replicas).must_equal 1024
74
+ end
75
+
76
+ it "uses a custom ring object" do
77
+ my_ring = Redis::HashRing.new
78
+ dmr = Redis::DistributedStore.new [
79
+ { :host => "localhost", :port => "6380", :db => 0 },
80
+ { :host => "localhost", :port => "6381", :db => 0 }
81
+ ], ring: my_ring
82
+ _(dmr.ring).must_equal my_ring
83
+ _(dmr.ring.nodes.length).must_equal 2
84
+ end
85
+
86
+ describe '#redis_version' do
87
+ it 'returns redis version' do
88
+ @dmr.nodes.first.expects(:redis_version)
89
+ @dmr.redis_version
90
+ end
91
+ end
92
+
93
+ describe '#supports_redis_version?' do
94
+ it 'returns redis version' do
95
+ @dmr.nodes.first.expects(:supports_redis_version?).with('2.8.0')
96
+ @dmr.supports_redis_version?('2.8.0')
97
+ end
98
+ end
99
+
100
+ describe "namespace" do
101
+ it "uses namespaced key" do
102
+ @dmr = Redis::DistributedStore.new [
103
+ { :host => "localhost", :port => "6380", :db => 0 },
104
+ { :host => "localhost", :port => "6381", :db => 0 }
105
+ ], :namespace => "theplaylist"
106
+
107
+ @dmr.expects(:node_for).with("theplaylist:rabbit").returns(@dmr.nodes.first)
108
+ @dmr.get "rabbit"
109
+ end
110
+ end
111
+ end unless ENV['CI']
@@ -0,0 +1,273 @@
1
+ require 'test_helper'
2
+ require 'json'
3
+
4
+ describe "Redis::Store::Factory" do
5
+ describe ".create" do
6
+ describe "when not given any arguments" do
7
+ it "instantiates Redis::Store" do
8
+ store = Redis::Store::Factory.create
9
+ _(store).must_be_kind_of(Redis::Store)
10
+ # `redis.rb` use different default host values in v4 & v5
11
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0$})
12
+ end
13
+ end
14
+
15
+ describe "when given a Hash" do
16
+ it "uses specified host" do
17
+ store = Redis::Store::Factory.create :host => "localhost"
18
+ _(store.to_s).must_equal("Redis Client connected to localhost:6379 against DB 0")
19
+ end
20
+
21
+ it "uses specified port" do
22
+ store = Redis::Store::Factory.create :host => "localhost", :port => 6380
23
+ _(store.to_s).must_equal("Redis Client connected to localhost:6380 against DB 0")
24
+ end
25
+
26
+ it "uses specified scheme" do
27
+ store = Redis::Store::Factory.create :scheme => "rediss"
28
+ client = store.instance_variable_get(:@client)
29
+ # `redis-client` does NOT have `scheme`
30
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('rediss')
31
+ end
32
+
33
+ it "uses specified path" do
34
+ store = Redis::Store::Factory.create :path => "/var/run/redis.sock"
35
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
36
+ end
37
+
38
+ it "uses specified db" do
39
+ store = Redis::Store::Factory.create :host => "localhost", :port => 6380, :db => 13
40
+ _(store.to_s).must_equal("Redis Client connected to localhost:6380 against DB 13")
41
+ end
42
+
43
+ it "uses specified namespace" do
44
+ store = Redis::Store::Factory.create :namespace => "theplaylist"
45
+ # `redis.rb` use different default host values in v4 & v5
46
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0 with namespace theplaylist$})
47
+ end
48
+
49
+ it "uses specified key_prefix as namespace" do
50
+ store = Redis::Store::Factory.create :key_prefix => "theplaylist"
51
+ # `redis.rb` use different default host values in v4 & v5
52
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0 with namespace theplaylist$})
53
+ end
54
+
55
+ it "uses specified password" do
56
+ store = Redis::Store::Factory.create :password => "secret"
57
+ _(store.instance_variable_get(:@client).password).must_equal("secret")
58
+ end
59
+
60
+ it 'uses empty password' do
61
+ store = Redis::Store::Factory.create :password => ''
62
+ _(store.instance_variable_get(:@client).password).must_equal('')
63
+ end
64
+
65
+ it 'uses nil password' do
66
+ store = Redis::Store::Factory.create :password => nil
67
+ assert_nil(store.instance_variable_get(:@client).password)
68
+ end
69
+
70
+ it "disables serialization" do
71
+ store = Redis::Store::Factory.create :serializer => nil
72
+ _(store.instance_variable_get(:@serializer)).must_be_nil
73
+ # `raw` would be removed when `redis-client` is used
74
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(true)
75
+ end
76
+
77
+ it "configures pluggable serialization backend" do
78
+ store = Redis::Store::Factory.create :serializer => JSON
79
+ _(store.instance_variable_get(:@serializer)).must_equal(JSON)
80
+ # `raw` would be removed when `redis-client` is used
81
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(false)
82
+ end
83
+
84
+ describe "defaults" do
85
+ it "defaults to localhost if no host specified" do
86
+ store = Redis::Store::Factory.create
87
+ # `redis.rb` use different default host values in v4 & v5
88
+ _(store.instance_variable_get(:@client).host).must_match(%r{^127.0.0.1|localhost$})
89
+ end
90
+
91
+ it "defaults to 6379 if no port specified" do
92
+ store = Redis::Store::Factory.create
93
+ _(store.instance_variable_get(:@client).port).must_equal(6379)
94
+ end
95
+
96
+ it "defaults to redis:// if no scheme specified" do
97
+ store = Redis::Store::Factory.create
98
+ client = store.instance_variable_get(:@client)
99
+ # `redis-client` does NOT have `scheme`
100
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('redis')
101
+ end
102
+ end
103
+
104
+ describe 'with stdout disabled' do
105
+ before do
106
+ @original_stderr = $stderr
107
+ @original_stdout = $stdout
108
+
109
+ $stderr = Tempfile.new('stderr')
110
+ $stdout = Tempfile.new('stdout')
111
+ end
112
+
113
+ it "disables marshalling and provides deprecation warning" do
114
+ store = Redis::Store::Factory.create :marshalling => false
115
+ _(store.instance_variable_get(:@serializer)).must_be_nil
116
+ # `raw` would be removed when `redis-client` is used
117
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(true)
118
+ end
119
+
120
+ it "enables marshalling but provides warning to use :serializer instead" do
121
+ store = Redis::Store::Factory.create :marshalling => true
122
+ _(store.instance_variable_get(:@serializer)).must_equal(Marshal)
123
+ # `raw` would be removed when `redis-client` is used
124
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(false)
125
+ end
126
+
127
+ after do
128
+ $stderr = @original_stderr
129
+ $stdout = @original_stdout
130
+ end
131
+ end
132
+
133
+ it "should instantiate a Redis::DistributedStore store" do
134
+ store = Redis::Store::Factory.create(
135
+ { :host => "localhost", :port => 6379 },
136
+ { :host => "localhost", :port => 6380 }
137
+ )
138
+ _(store).must_be_kind_of(Redis::DistributedStore)
139
+ _(store.nodes.map { |node| node.to_s }).must_equal([
140
+ "Redis Client connected to localhost:6379 against DB 0",
141
+ "Redis Client connected to localhost:6380 against DB 0",
142
+ ])
143
+ end
144
+ end
145
+
146
+ describe "when given a String" do
147
+ it "uses specified host" do
148
+ store = Redis::Store::Factory.create "redis://127.0.0.1"
149
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0")
150
+ end
151
+
152
+ it "uses specified port" do
153
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6380"
154
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6380 against DB 0")
155
+ end
156
+
157
+ it "uses specified scheme" do
158
+ store = Redis::Store::Factory.create "rediss://127.0.0.1:6380"
159
+ client = store.instance_variable_get(:@client)
160
+ # `redis-client` does NOT have `scheme`
161
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('rediss')
162
+ end
163
+
164
+ it "correctly defaults to redis:// when relative scheme specified" do
165
+ store = Redis::Store::Factory.create "//127.0.0.1:6379"
166
+ client = store.instance_variable_get(:@client)
167
+ # `redis-client` does NOT have `scheme`
168
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('redis')
169
+ end
170
+
171
+ it "uses specified path" do
172
+ store = Redis::Store::Factory.create "unix:///var/run/redis.sock"
173
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
174
+ end
175
+
176
+ it "uses specified db" do
177
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6380/13"
178
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6380 against DB 13")
179
+ end
180
+
181
+ it "uses specified namespace" do
182
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
183
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
184
+ end
185
+
186
+ it "uses specified via query namespace" do
187
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0?namespace=theplaylist"
188
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
189
+ end
190
+
191
+ it "uses specified namespace with path" do
192
+ store = Redis::Store::Factory.create "unix:///var/run/redis.sock?db=2&namespace=theplaylist"
193
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 2 with namespace theplaylist")
194
+ end
195
+
196
+ it "uses specified password" do
197
+ store = Redis::Store::Factory.create "redis://:secret@127.0.0.1:6379/0/theplaylist"
198
+ _(store.instance_variable_get(:@client).password).must_equal("secret")
199
+ end
200
+
201
+ it 'uses specified password with special characters' do
202
+ store = Redis::Store::Factory.create 'redis://:pwd%40123@127.0.0.1:6379/0/theplaylist'
203
+ _(store.instance_variable_get(:@client).password).must_equal('pwd@123')
204
+ end
205
+
206
+ it 'uses empty password' do
207
+ store = Redis::Store::Factory.create 'redis://:@127.0.0.1:6379/0/theplaylist'
208
+ _(store.instance_variable_get(:@client).password).must_equal('')
209
+ end
210
+
211
+ it 'uses nil password' do
212
+ store = Redis::Store::Factory.create 'redis://127.0.0.1:6379/0/theplaylist'
213
+ assert_nil(store.instance_variable_get(:@client).password)
214
+ end
215
+
216
+ it "correctly uses specified ipv6 host" do
217
+ store = Redis::Store::Factory.create "redis://[::1]:6380"
218
+ _(store.to_s).must_equal("Redis Client connected to [::1]:6380 against DB 0")
219
+ _(store.instance_variable_get('@options')[:host]).must_equal("::1")
220
+ end
221
+
222
+ it "instantiates Redis::DistributedStore" do
223
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380"
224
+ _(store).must_be_kind_of(Redis::DistributedStore)
225
+ _(store.nodes.map { |node| node.to_s }).must_equal([
226
+ "Redis Client connected to 127.0.0.1:6379 against DB 0",
227
+ "Redis Client connected to 127.0.0.1:6380 against DB 0",
228
+ ])
229
+ end
230
+ end
231
+
232
+ describe 'when given host Hash and options Hash' do
233
+ it 'instantiates Redis::Store and merges options' do
234
+ Redis::Store::Factory.create(
235
+ { :host => '127.0.0.1', :port => '6379' },
236
+ { :namespace => 'theplaylist' }
237
+ )
238
+ end
239
+
240
+ it 'instantiates Redis::DistributedStore and merges options' do
241
+ store = Redis::Store::Factory.create(
242
+ { :host => '127.0.0.1', :port => '6379' },
243
+ { :host => '127.0.0.1', :port => '6380' },
244
+ { :namespace => 'theplaylist' }
245
+ )
246
+ _(store.nodes.map { |node| node.to_s }).must_equal([
247
+ "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
248
+ "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist"
249
+ ])
250
+ end
251
+ end
252
+
253
+ describe 'when given host String and options Hash' do
254
+ it 'instantiates Redis::Store and merges options' do
255
+ store = Redis::Store::Factory.create "redis://127.0.0.1", :namespace => 'theplaylist'
256
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
257
+ end
258
+
259
+ it 'instantiates Redis::DistributedStore and merges options' do
260
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380", :namespace => 'theplaylist'
261
+ _(store.nodes.map { |node| node.to_s }).must_equal([
262
+ "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
263
+ "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist",
264
+ ])
265
+ end
266
+
267
+ it 'instantiates Redis::Store and sets namespace from String' do
268
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
269
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class InterfacedRedis < Redis
4
+ include Redis::Store::Interface
5
+ end
6
+
7
+ describe Redis::Store::Interface do
8
+ before do
9
+ @r = InterfacedRedis.new
10
+ end
11
+
12
+ it "should get an element" do
13
+ lambda { @r.get("key", :option => true) } # .wont_raise ArgumentError
14
+ end
15
+
16
+ it "should set an element" do
17
+ lambda { @r.set("key", "value", :option => true) } # .wont_raise ArgumentError
18
+ end
19
+
20
+ it "should setnx an element" do
21
+ lambda { @r.setnx("key", "value", :option => true) } # .wont_raise ArgumentError
22
+ end
23
+
24
+ it "should setex an element" do
25
+ lambda { @r.setex("key", 1, "value", :option => true) } # .wont_raise ArgumentError
26
+ end
27
+ end