honkster-redis-store 0.3.10

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.
@@ -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