honkster-redis-store 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,234 @@
1
+ require File.join(File.dirname(__FILE__), "/../../spec_helper")
2
+
3
+ module Rack
4
+ module Session
5
+ describe "Rack::Session::Redis" do
6
+ before(:each) do
7
+ @session_key = Rack::Session::Redis::DEFAULT_OPTIONS[:key]
8
+ @session_match = /#{@session_key}=[0-9a-fA-F]+;/
9
+ @incrementor = lambda do |env|
10
+ env["rack.session"]["counter"] ||= 0
11
+ env["rack.session"]["counter"] += 1
12
+ Rack::Response.new(env["rack.session"].inspect).to_a
13
+ end
14
+ @drop_session = proc do |env|
15
+ env['rack.session.options'][:drop] = true
16
+ @incrementor.call(env)
17
+ end
18
+ @renew_session = proc do |env|
19
+ env['rack.session.options'][:renew] = true
20
+ @incrementor.call(env)
21
+ end
22
+ @defer_session = proc do |env|
23
+ env['rack.session.options'][:defer] = true
24
+ @incrementor.call(env)
25
+ end
26
+ end
27
+
28
+ it "should specify connection params" do
29
+ pool = Rack::Session::Redis.new(@incrementor, :redis_server => "localhost:6380/1").pool
30
+ pool.should be_kind_of(MarshaledRedis)
31
+ pool.to_s.should == "Redis Client connected to localhost:6380 against DB 1"
32
+
33
+ pool = Rack::Session::Redis.new(@incrementor, :redis_server => ["localhost:6379", "localhost:6380"]).pool
34
+ pool.should be_kind_of(DistributedMarshaledRedis)
35
+ end
36
+
37
+ it "creates a new cookie" do
38
+ pool = Rack::Session::Redis.new(@incrementor)
39
+ res = Rack::MockRequest.new(pool).get("/")
40
+ res["Set-Cookie"].should match(/#{@session_key}=/)
41
+ res.body.should == '{"counter"=>1}'
42
+ end
43
+
44
+ it "determines session from a cookie" do
45
+ pool = Rack::Session::Redis.new(@incrementor)
46
+ req = Rack::MockRequest.new(pool)
47
+ res = req.get("/")
48
+ cookie = res["Set-Cookie"]
49
+ req.get("/", "HTTP_COOKIE" => cookie).body.should == '{"counter"=>2}'
50
+ req.get("/", "HTTP_COOKIE" => cookie).body.should == '{"counter"=>3}'
51
+ end
52
+
53
+ it "survives nonexistant cookies" do
54
+ bad_cookie = "rack.session=blarghfasel"
55
+ pool = Rack::Session::Redis.new(@incrementor)
56
+ res = Rack::MockRequest.new(pool).
57
+ get("/", "HTTP_COOKIE" => bad_cookie)
58
+ res.body.should == '{"counter"=>1}'
59
+ cookie = res["Set-Cookie"][@session_match]
60
+ cookie.should_not match(/#{bad_cookie}/)
61
+ end
62
+
63
+ it "should maintain freshness" do
64
+ pool = Rack::Session::Redis.new(@incrementor, :expire_after => 3)
65
+ res = Rack::MockRequest.new(pool).get('/')
66
+ res.body.should include('"counter"=>1')
67
+ cookie = res["Set-Cookie"]
68
+ res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
69
+ res["Set-Cookie"].should == cookie
70
+ res.body.should include('"counter"=>2')
71
+ puts 'Sleeping to expire session' if $DEBUG
72
+ sleep 4
73
+ res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
74
+ res["Set-Cookie"].should_not == cookie
75
+ res.body.should include('"counter"=>1')
76
+ end
77
+
78
+ it "deletes cookies with :drop option" do
79
+ pool = Rack::Session::Redis.new(@incrementor)
80
+ req = Rack::MockRequest.new(pool)
81
+ drop = Rack::Utils::Context.new(pool, @drop_session)
82
+ dreq = Rack::MockRequest.new(drop)
83
+
84
+ res0 = req.get("/")
85
+ session = (cookie = res0["Set-Cookie"])[@session_match]
86
+ res0.body.should == '{"counter"=>1}'
87
+
88
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
89
+ res1["Set-Cookie"][@session_match].should == session
90
+ res1.body.should == '{"counter"=>2}'
91
+
92
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
93
+ res2["Set-Cookie"].should be_nil
94
+ res2.body.should == '{"counter"=>3}'
95
+
96
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
97
+ res3["Set-Cookie"][@session_match].should_not == session
98
+ res3.body.should == '{"counter"=>1}'
99
+ end
100
+
101
+ it "provides new session id with :renew option" do
102
+ pool = Rack::Session::Redis.new(@incrementor)
103
+ req = Rack::MockRequest.new(pool)
104
+ renew = Rack::Utils::Context.new(pool, @renew_session)
105
+ rreq = Rack::MockRequest.new(renew)
106
+
107
+ res0 = req.get("/")
108
+ session = (cookie = res0["Set-Cookie"])[@session_match]
109
+ res0.body.should == '{"counter"=>1}'
110
+
111
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
112
+ res1["Set-Cookie"][@session_match].should == session
113
+ res1.body.should == '{"counter"=>2}'
114
+
115
+ res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
116
+ new_cookie = res2["Set-Cookie"]
117
+ new_session = new_cookie[@session_match]
118
+ new_session.should_not == session
119
+ res2.body.should == '{"counter"=>3}'
120
+
121
+ res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
122
+ res3["Set-Cookie"][@session_match].should == new_session
123
+ res3.body.should == '{"counter"=>4}'
124
+ end
125
+
126
+ specify "omits cookie with :defer option" do
127
+ pool = Rack::Session::Redis.new(@incrementor)
128
+ req = Rack::MockRequest.new(pool)
129
+ defer = Rack::Utils::Context.new(pool, @defer_session)
130
+ dreq = Rack::MockRequest.new(defer)
131
+
132
+ res0 = req.get("/")
133
+ session = (cookie = res0["Set-Cookie"])[@session_match]
134
+ res0.body.should == '{"counter"=>1}'
135
+
136
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
137
+ res1["Set-Cookie"][@session_match].should == session
138
+ res1.body.should == '{"counter"=>2}'
139
+
140
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
141
+ res2["Set-Cookie"].should be_nil
142
+ res2.body.should == '{"counter"=>3}'
143
+
144
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
145
+ res3["Set-Cookie"][@session_match].should == session
146
+ res3.body.should == '{"counter"=>4}'
147
+ end
148
+
149
+ # anyone know how to do this better?
150
+ specify "multithread: should cleanly merge sessions" do
151
+ next unless $DEBUG
152
+ warn 'Running multithread test for Session::Redis'
153
+ pool = Rack::Session::Redis.new(@incrementor)
154
+ req = Rack::MockRequest.new(pool)
155
+
156
+ res = req.get('/')
157
+ res.body.should == '{"counter"=>1}'
158
+ cookie = res["Set-Cookie"]
159
+ sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
160
+
161
+ delta_incrementor = lambda do |env|
162
+ # emulate disconjoinment of threading
163
+ env['rack.session'] = env['rack.session'].dup
164
+ Thread.stop
165
+ env['rack.session'][(Time.now.usec*rand).to_i] = true
166
+ @incrementor.call(env)
167
+ end
168
+ tses = Rack::Utils::Context.new pool, delta_incrementor
169
+ treq = Rack::MockRequest.new(tses)
170
+ tnum = rand(7).to_i+5
171
+ r = Array.new(tnum) do
172
+ Thread.new(treq) do |run|
173
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
174
+ end
175
+ end.reverse.map{|t| t.run.join.value }
176
+ r.each do |res|
177
+ res['Set-Cookie'].should == cookie
178
+ res.body.should include('"counter"=>2')
179
+ end
180
+
181
+ session = pool.pool.get(sess_id)
182
+ session.size.should == tnum+1 # counter
183
+ session['counter'].should == 2 # meeeh
184
+
185
+ tnum = rand(7).to_i+5
186
+ r = Array.new(tnum) do |i|
187
+ delta_time = proc do |env|
188
+ env['rack.session'][i] = Time.now
189
+ Thread.stop
190
+ env['rack.session'] = env['rack.session'].dup
191
+ env['rack.session'][i] -= Time.now
192
+ @incrementor.call(env)
193
+ end
194
+ app = Rack::Utils::Context.new pool, time_delta
195
+ req = Rack::MockRequest.new app
196
+ Thread.new(req) do |run|
197
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
198
+ end
199
+ end.reverse.map{|t| t.run.join.value }
200
+ r.each do |res|
201
+ res['Set-Cookie'].should == cookie
202
+ res.body.should include('"counter"=>3')
203
+ end
204
+
205
+ session = pool.pool.get(sess_id)
206
+ session.size.should == tnum+1
207
+ session['counter'].should == 3
208
+
209
+ drop_counter = proc do |env|
210
+ env['rack.session'].del 'counter'
211
+ env['rack.session']['foo'] = 'bar'
212
+ [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
213
+ end
214
+ tses = Rack::Utils::Context.new pool, drop_counter
215
+ treq = Rack::MockRequest.new(tses)
216
+ tnum = rand(7).to_i+5
217
+ r = Array.new(tnum) do
218
+ Thread.new(treq) do |run|
219
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
220
+ end
221
+ end.reverse.map{|t| t.run.join.value }
222
+ r.each do |res|
223
+ res['Set-Cookie'].should == cookie
224
+ res.body.should include('"foo"=>"bar"')
225
+ end
226
+
227
+ session = pool.pool.get(sess_id)
228
+ session.size.should == r.size+1
229
+ session['counter'].should be_nil
230
+ session['foo'].should == 'bar'
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "DistributedMarshaledRedis" do
4
+ before(:each) do
5
+ @dmr = DistributedMarshaledRedis.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.marshalled_set "rabbit", @rabbit
12
+ end
13
+
14
+ after(:all) do
15
+ @dmr.ring.nodes.each { |server| server.flushdb }
16
+ end
17
+
18
+ it "should accept connection params" do
19
+ dmr = DistributedMarshaledRedis.new [ :host => "localhost", :port => "6380", :db => "1" ]
20
+ dmr.ring.should have(1).node
21
+ mr = dmr.ring.nodes.first
22
+ mr.to_s.should == "Redis Client connected to localhost:6380 against DB 1"
23
+ end
24
+
25
+ it "should set an object" do
26
+ @dmr.marshalled_set "rabbit", @white_rabbit
27
+ @dmr.marshalled_get("rabbit").should == @white_rabbit
28
+ end
29
+
30
+ it "should get an object" do
31
+ @dmr.marshalled_get("rabbit").should == @rabbit
32
+ end
33
+ end
@@ -0,0 +1,54 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "MarshaledRedis" do
4
+ before(:each) do
5
+ @store = MarshaledRedis.new
6
+ @rabbit = OpenStruct.new :name => "bunny"
7
+ @white_rabbit = OpenStruct.new :color => "white"
8
+ @store.marshalled_set "rabbit", @rabbit
9
+ @store.del "rabbit2"
10
+ end
11
+
12
+ after :each do
13
+ @store.quit
14
+ end
15
+
16
+ it "should unmarshal an object on get" do
17
+ @store.marshalled_get("rabbit").should === @rabbit
18
+ end
19
+
20
+ it "should marshal object on set" do
21
+ @store.marshalled_set "rabbit", @white_rabbit
22
+ @store.marshalled_get("rabbit").should === @white_rabbit
23
+ end
24
+
25
+ it "should not unmarshal object on get if raw option is true" do
26
+ @store.marshalled_get("rabbit", :raw => true).should == "\004\bU:\017OpenStruct{\006:\tname\"\nbunny"
27
+ end
28
+
29
+ it "should not marshal object on set if raw option is true" do
30
+ @store.marshalled_set "rabbit", @white_rabbit, :raw => true
31
+ @store.marshalled_get("rabbit", :raw => true).should == %(#<OpenStruct color="white">)
32
+ end
33
+
34
+ it "should not unmarshal object if getting an empty string" do
35
+ @store.marshalled_set "empty_string", ""
36
+ lambda { @store.marshalled_get("empty_string").should == "" }.should_not raise_error
37
+ end
38
+
39
+ it "should not set an object if already exist" do
40
+ @store.marshalled_setnx "rabbit", @white_rabbit
41
+ @store.marshalled_get("rabbit").should === @rabbit
42
+ end
43
+
44
+ it "should marshal object on set_unless_exists" do
45
+ @store.marshalled_setnx "rabbit2", @white_rabbit
46
+ @store.marshalled_get("rabbit2").should === @white_rabbit
47
+ end
48
+
49
+ it "should not marshal object on set_unless_exists if raw option is true" do
50
+ @store.marshalled_setnx "rabbit2", @white_rabbit, :raw => true
51
+ @store.marshalled_get("rabbit2", :raw => true).should == %(#<OpenStruct color="white">)
52
+ end
53
+ end
54
+
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "RedisFactory" do
4
+ describe ".create" do
5
+ context "when not given any arguments" do
6
+ it "should instantiate a MarshaledRedis store" do
7
+ store = RedisFactory.create
8
+ store.should be_kind_of(MarshaledRedis)
9
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
10
+ end
11
+ end
12
+
13
+ context "when given a Hash" do
14
+ it "should allow to specify host" do
15
+ store = RedisFactory.create :host => "localhost"
16
+ store.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
17
+ end
18
+
19
+ it "should allow to specify port" do
20
+ store = RedisFactory.create :host => "localhost", :port => 6380
21
+ store.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
22
+ end
23
+
24
+ it "should allow to specify db" do
25
+ store = RedisFactory.create :host => "localhost", :port => 6380, :db => 13
26
+ store.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
27
+ end
28
+
29
+ it "should instantiate a DistributedMarshaledRedis store" do
30
+ store = RedisFactory.create(
31
+ {:host => "localhost", :port => 6379},
32
+ {:host => "localhost", :port => 6380}
33
+ )
34
+ store.should be_kind_of(DistributedMarshaledRedis)
35
+ store.nodes.map {|node| node.to_s}.should == [
36
+ "Redis Client connected to localhost:6379 against DB 0",
37
+ "Redis Client connected to localhost:6380 against DB 0",
38
+ ]
39
+ end
40
+ end
41
+
42
+ context "when given a String" do
43
+ it "should allow to specify host" do
44
+ store = RedisFactory.create "localhost"
45
+ store.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
46
+ end
47
+
48
+ it "should allow to specify port" do
49
+ store = RedisFactory.create "localhost:6380"
50
+ store.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
51
+ end
52
+
53
+ it "should allow to specify db" do
54
+ store = RedisFactory.create "localhost:6380/13"
55
+ store.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
56
+ end
57
+
58
+ it "should instantiate a DistributedMarshaledRedis store" do
59
+ store = RedisFactory.create "localhost:6379", "localhost:6380"
60
+ store.should be_kind_of(DistributedMarshaledRedis)
61
+ store.nodes.map {|node| node.to_s}.should == [
62
+ "Redis Client connected to localhost:6379 against DB 0",
63
+ "Redis Client connected to localhost:6380 against DB 0",
64
+ ]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,24 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "/../lib"))
2
+ ARGV << "-b"
3
+ require "rubygems"
4
+ require "bundler"
5
+ Bundler.setup
6
+
7
+ #require "vendor/gems/environment"
8
+ require "ostruct"
9
+ require "spec"
10
+ require "spec/autorun"
11
+ require "redis"
12
+ require "merb"
13
+ require "rack/cache"
14
+ require "rack/cache/metastore"
15
+ require "rack/cache/entitystore"
16
+ require "redis-store"
17
+ require "active_support"
18
+ require "action_controller/session/abstract_store"
19
+ require "cache/rails/redis_store"
20
+ require "cache/rails/redis_session_store"
21
+ require "cache/sinatra/redis_store"
22
+
23
+ class Redis; attr_reader :host, :port, :db end
24
+ $DEBUG = ENV["DEBUG"] === "true"
@@ -0,0 +1,78 @@
1
+ # steal the cool tasks from redis-rb
2
+ require 'rbconfig'
3
+ require "rubygems"
4
+ require "bundler"
5
+ Bundler.setup
6
+ redis_path = $:.
7
+ find {|path| path =~ /redis-/ }.
8
+ split("/").
9
+ tap do |array|
10
+ array.replace(
11
+ array[0..array.index(array.find {|segment| segment =~ /redis-/})]
12
+ )
13
+ end.
14
+ join("/")
15
+
16
+ load "#{redis_path}/tasks/redis.tasks.rb"
17
+
18
+ class RedisRunner
19
+ def self.port
20
+ 6379
21
+ end
22
+
23
+ def self.stop
24
+ system %(echo "SHUTDOWN" | nc localhost #{port})
25
+ end
26
+ end
27
+
28
+ class SingleRedisRunner < RedisRunner
29
+ def self.redisconfdir
30
+ File.expand_path(File.dirname(__FILE__) + "/../spec/config/single.conf")
31
+ end
32
+ end
33
+
34
+ class MasterRedisRunner < RedisRunner
35
+ def self.redisconfdir
36
+ File.expand_path(File.dirname(__FILE__) + "/../spec/config/master.conf")
37
+ end
38
+
39
+ def self.dtach_socket
40
+ "/tmp/redis_master.dtach"
41
+ end
42
+
43
+ def self.port
44
+ 6380
45
+ end
46
+ end
47
+
48
+ class SlaveRedisRunner < RedisRunner
49
+ def self.redisconfdir
50
+ File.expand_path(File.dirname(__FILE__) + "/../spec/config/slave.conf")
51
+ end
52
+
53
+ def self.dtach_socket
54
+ "/tmp/redis_slave.dtach"
55
+ end
56
+
57
+ def self.port
58
+ 6381
59
+ end
60
+ end
61
+
62
+ class RedisClusterRunner
63
+ def self.runners
64
+ [ SingleRedisRunner, MasterRedisRunner, SlaveRedisRunner ]
65
+ end
66
+
67
+ def self.start_detached
68
+ runners.each do |runner|
69
+ runner.start_detached
70
+ end
71
+ end
72
+
73
+ def self.stop
74
+ runners.each do |runner|
75
+ runner.stop
76
+ end
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: honkster-redis-store
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 3
8
+ - 10
9
+ version: 0.3.10
10
+ platform: ruby
11
+ authors:
12
+ - Luca Guidi
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-23 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.
22
+ email: guidi.luca@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.md
29
+ files:
30
+ - .gitignore
31
+ - Gemfile
32
+ - MIT-LICENSE
33
+ - README.md
34
+ - Rakefile
35
+ - VERSION
36
+ - lib/cache/merb/redis_store.rb
37
+ - lib/cache/rails/redis_session_store.rb
38
+ - lib/cache/rails/redis_store.rb
39
+ - lib/cache/sinatra/redis_store.rb
40
+ - lib/rack/cache/redis_entitystore.rb
41
+ - lib/rack/cache/redis_metastore.rb
42
+ - lib/rack/session/merb.rb
43
+ - lib/rack/session/redis.rb
44
+ - lib/redis-store.rb
45
+ - lib/redis/distributed_marshaled_redis.rb
46
+ - lib/redis/marshaled_redis.rb
47
+ - lib/redis/redis_factory.rb
48
+ - redis-store.gemspec
49
+ - spec/cache/merb/redis_store_spec.rb
50
+ - spec/cache/rails/redis_session_store_spec.rb
51
+ - spec/cache/rails/redis_store_spec.rb
52
+ - spec/cache/sinatra/redis_store_spec.rb
53
+ - spec/config/master.conf
54
+ - spec/config/single.conf
55
+ - spec/config/slave.conf
56
+ - spec/rack/cache/entitystore/pony.jpg
57
+ - spec/rack/cache/entitystore/redis_spec.rb
58
+ - spec/rack/cache/metastore/redis_spec.rb
59
+ - spec/rack/session/redis_spec.rb
60
+ - spec/redis/distributed_marshaled_redis_spec.rb
61
+ - spec/redis/marshaled_redis_spec.rb
62
+ - spec/redis/redis_factory_spec.rb
63
+ - spec/spec_helper.rb
64
+ - tasks/redis.tasks.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/jodosha/redis-store
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --charset=UTF-8
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 1.3.6
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.
95
+ test_files:
96
+ - spec/spec_helper.rb
97
+ - spec/cache/sinatra/redis_store_spec.rb
98
+ - spec/cache/merb/redis_store_spec.rb
99
+ - spec/cache/rails/redis_session_store_spec.rb
100
+ - spec/cache/rails/redis_store_spec.rb
101
+ - spec/rack/cache/metastore/redis_spec.rb
102
+ - spec/rack/cache/entitystore/redis_spec.rb
103
+ - spec/rack/session/redis_spec.rb
104
+ - spec/redis/marshaled_redis_spec.rb
105
+ - spec/redis/distributed_marshaled_redis_spec.rb
106
+ - spec/redis/redis_factory_spec.rb