redis-store 0.3.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of redis-store might be problematic. Click here for more details.

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