tokyo_store 0.3.0
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.
- data/.document +5 -0
- data/.gitignore +6 -0
- data/LICENSE +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +44 -0
- data/VERSION +1 -0
- data/benchmark/cache.rb +134 -0
- data/benchmark/session.rb +75 -0
- data/lib/cache/tokyo_store.rb +139 -0
- data/lib/rack/cache/tokyo_entitystore.rb +0 -0
- data/lib/rack/cache/tokyo_metastore.rb +0 -0
- data/lib/rack/session/cabinet.rb +70 -0
- data/lib/rack/session/rufus_tyrant.rb +81 -0
- data/lib/rack/session/tyrant.rb +70 -0
- data/lib/tokyo_store.rb +16 -0
- data/spec/cache/tokyo_store_spec.rb +256 -0
- data/spec/rack/cache/tokyo_spec.rb +0 -0
- data/spec/rack/session/cabinet_spec.rb +242 -0
- data/spec/rack/session/rufus_tyrant_spec.rb +246 -0
- data/spec/rack/session/tyrant_spec.rb +249 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/tokyo_store_spec.rb +43 -0
- data/tokyo_store.gemspec +65 -0
- metadata +85 -0
File without changes
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# Code from http://github.com/jodosha/redis-store
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Session
|
6
|
+
describe "Rack::Session::Cabinet" do
|
7
|
+
before(:each) do
|
8
|
+
@session_key = Rack::Session::Cabinet::DEFAULT_OPTIONS[:key]
|
9
|
+
@session_match = /#{@session_key}=[0-9a-fA-F]+;/
|
10
|
+
@incrementor = lambda do |env|
|
11
|
+
env["rack.session"]["counter"] ||= 0
|
12
|
+
env["rack.session"]["counter"] += 1
|
13
|
+
Rack::Response.new(env["rack.session"].inspect).to_a
|
14
|
+
end
|
15
|
+
@drop_session = proc do |env|
|
16
|
+
env['rack.session.options'][:drop] = true
|
17
|
+
@incrementor.call(env)
|
18
|
+
end
|
19
|
+
@renew_session = proc do |env|
|
20
|
+
env['rack.session.options'][:renew] = true
|
21
|
+
@incrementor.call(env)
|
22
|
+
end
|
23
|
+
@defer_session = proc do |env|
|
24
|
+
env['rack.session.options'][:defer] = true
|
25
|
+
@incrementor.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should specify connection params" do
|
30
|
+
pool = Rack::Session::Cabinet.new(@incrementor, :cabinet_file => "/tmp/some.tch").pool
|
31
|
+
pool.should be_kind_of(TokyoCabinet::HDB)
|
32
|
+
pool.path.should eql("/tmp/some.tch")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise tokyo error on connect" do
|
36
|
+
lambda{ Rack::Session::Tokyo.new(@incrementor, :cabinet_file => "/tmp/session.tch").pool }.
|
37
|
+
should_not raise_error(Rufus::Tokyo::TokyoError)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
it "creates a new cookie" do
|
42
|
+
pool = Rack::Session::Cabinet.new(@incrementor)
|
43
|
+
res = Rack::MockRequest.new(pool).get("/")
|
44
|
+
res["Set-Cookie"].should match(/#{@session_key}=/)
|
45
|
+
res.body.should eql('{"counter"=>1}')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "determines session from a cookie" do
|
49
|
+
pool = Rack::Session::Cabinet.new(@incrementor)
|
50
|
+
req = Rack::MockRequest.new(pool)
|
51
|
+
res = req.get("/")
|
52
|
+
cookie = res["Set-Cookie"]
|
53
|
+
req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>2}')
|
54
|
+
req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>3}')
|
55
|
+
end
|
56
|
+
|
57
|
+
it "survives nonexistant cookies" do
|
58
|
+
bad_cookie = "rack.session=blsarghfasel"
|
59
|
+
pool = Rack::Session::Cabinet.new(@incrementor)
|
60
|
+
res = Rack::MockRequest.new(pool).get("/", "HTTP_COOKIE" => bad_cookie)
|
61
|
+
res.body.should eql('{"counter"=>1}')
|
62
|
+
cookie = res["Set-Cookie"][@session_match]
|
63
|
+
cookie.should_not match(/#{bad_cookie}/)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Expire isn't supported by cabinet. Implement in ruby?
|
67
|
+
# it "should maintain freshness" do
|
68
|
+
# pool = Rack::Session::Cabinet.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::Cabinet.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::Cabinet.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::Cabinet.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::Cabinet'
|
157
|
+
pool = Rack::Session::Cabinet.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
|
+
|
237
|
+
after(:all) do
|
238
|
+
Rack::Session::Cabinet.new(@incrementor).pool.clear
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
# Code from http://github.com/jodosha/redis-store
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Session
|
6
|
+
describe "Rack::Session::RufusTyrant" do
|
7
|
+
before(:each) do
|
8
|
+
@session_key = Rack::Session::RufusTyrant::DEFAULT_OPTIONS[:key]
|
9
|
+
@session_match = /#{@session_key}=[0-9a-fA-F]+;/
|
10
|
+
@incrementor = lambda do |env|
|
11
|
+
env["rack.session"]["counter"] ||= 0
|
12
|
+
env["rack.session"]["counter"] += 1
|
13
|
+
Rack::Response.new(env["rack.session"].inspect).to_a
|
14
|
+
end
|
15
|
+
@drop_session = proc do |env|
|
16
|
+
env['rack.session.options'][:drop] = true
|
17
|
+
@incrementor.call(env)
|
18
|
+
end
|
19
|
+
@renew_session = proc do |env|
|
20
|
+
env['rack.session.options'][:renew] = true
|
21
|
+
@incrementor.call(env)
|
22
|
+
end
|
23
|
+
@defer_session = proc do |env|
|
24
|
+
env['rack.session.options'][:defer] = true
|
25
|
+
@incrementor.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should specify connection params" do
|
30
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor, :tyrant_server => "127.0.0.1:1978").pool
|
31
|
+
pool.should be_kind_of(Rufus::Tokyo::Tyrant)
|
32
|
+
pool.host.should eql("127.0.0.1")
|
33
|
+
pool.port.should eql(1978)
|
34
|
+
|
35
|
+
# pool = Rack::Session::RufusTyrant.new(@incrementor, :tokyo_server => ["localhost:6379", "localhost:6380"]).pool
|
36
|
+
# pool.should be_kind_of(DistributedMarshaledRufusTyrant)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise tokyo error on connect" do
|
40
|
+
lambda{ Rack::Session::RufusTyrant.new(@incrementor, :tyrant_server => "localhost:6380").pool }.
|
41
|
+
should_not raise_error(Rufus::Tokyo::TokyoError)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it "creates a new cookie" do
|
46
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
47
|
+
res = Rack::MockRequest.new(pool).get("/")
|
48
|
+
res["Set-Cookie"].should match(/#{@session_key}=/)
|
49
|
+
res.body.should eql('{"counter"=>1}')
|
50
|
+
end
|
51
|
+
|
52
|
+
it "determines session from a cookie" do
|
53
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
54
|
+
req = Rack::MockRequest.new(pool)
|
55
|
+
res = req.get("/")
|
56
|
+
cookie = res["Set-Cookie"]
|
57
|
+
req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>2}')
|
58
|
+
req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>3}')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "survives nonexistant cookies" do
|
62
|
+
bad_cookie = "rack.session=blsarghfasel"
|
63
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
64
|
+
res = Rack::MockRequest.new(pool).get("/", "HTTP_COOKIE" => bad_cookie)
|
65
|
+
res.body.should eql('{"counter"=>1}')
|
66
|
+
cookie = res["Set-Cookie"][@session_match]
|
67
|
+
cookie.should_not match(/#{bad_cookie}/)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Expire isn't supported by cabinet. Implement in ruby?
|
71
|
+
# it "should maintain freshness" do
|
72
|
+
# pool = Rack::Session::RufusTyrant.new(@incrementor, :expire_after => 3)
|
73
|
+
# res = Rack::MockRequest.new(pool).get('/')
|
74
|
+
# res.body.should include('"counter"=>1')
|
75
|
+
# cookie = res["Set-Cookie"]
|
76
|
+
# res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
77
|
+
# res["Set-Cookie"].should == cookie
|
78
|
+
# res.body.should include('"counter"=>2')
|
79
|
+
# puts 'Sleeping to expire session' if $DEBUG
|
80
|
+
# sleep 4
|
81
|
+
# res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
82
|
+
# res["Set-Cookie"].should_not == cookie
|
83
|
+
# res.body.should include('"counter"=>1')
|
84
|
+
# end
|
85
|
+
|
86
|
+
it "deletes cookies with :drop option" do
|
87
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
88
|
+
req = Rack::MockRequest.new(pool)
|
89
|
+
drop = Rack::Utils::Context.new(pool, @drop_session)
|
90
|
+
dreq = Rack::MockRequest.new(drop)
|
91
|
+
|
92
|
+
res0 = req.get("/")
|
93
|
+
session = (cookie = res0["Set-Cookie"])[@session_match]
|
94
|
+
res0.body.should == '{"counter"=>1}'
|
95
|
+
|
96
|
+
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
97
|
+
res1["Set-Cookie"][@session_match].should == session
|
98
|
+
res1.body.should == '{"counter"=>2}'
|
99
|
+
|
100
|
+
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
101
|
+
res2["Set-Cookie"].should be_nil
|
102
|
+
res2.body.should == '{"counter"=>3}'
|
103
|
+
|
104
|
+
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
105
|
+
res3["Set-Cookie"][@session_match].should_not == session
|
106
|
+
res3.body.should == '{"counter"=>1}'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "provides new session id with :renew option" do
|
110
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
111
|
+
req = Rack::MockRequest.new(pool)
|
112
|
+
renew = Rack::Utils::Context.new(pool, @renew_session)
|
113
|
+
rreq = Rack::MockRequest.new(renew)
|
114
|
+
|
115
|
+
res0 = req.get("/")
|
116
|
+
session = (cookie = res0["Set-Cookie"])[@session_match]
|
117
|
+
res0.body.should == '{"counter"=>1}'
|
118
|
+
|
119
|
+
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
120
|
+
res1["Set-Cookie"][@session_match].should == session
|
121
|
+
res1.body.should == '{"counter"=>2}'
|
122
|
+
|
123
|
+
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
124
|
+
new_cookie = res2["Set-Cookie"]
|
125
|
+
new_session = new_cookie[@session_match]
|
126
|
+
new_session.should_not == session
|
127
|
+
res2.body.should == '{"counter"=>3}'
|
128
|
+
|
129
|
+
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
130
|
+
res3["Set-Cookie"][@session_match].should == new_session
|
131
|
+
res3.body.should == '{"counter"=>4}'
|
132
|
+
end
|
133
|
+
|
134
|
+
specify "omits cookie with :defer option" do
|
135
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
136
|
+
req = Rack::MockRequest.new(pool)
|
137
|
+
defer = Rack::Utils::Context.new(pool, @defer_session)
|
138
|
+
dreq = Rack::MockRequest.new(defer)
|
139
|
+
|
140
|
+
res0 = req.get("/")
|
141
|
+
session = (cookie = res0["Set-Cookie"])[@session_match]
|
142
|
+
res0.body.should == '{"counter"=>1}'
|
143
|
+
|
144
|
+
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
145
|
+
res1["Set-Cookie"][@session_match].should == session
|
146
|
+
res1.body.should == '{"counter"=>2}'
|
147
|
+
|
148
|
+
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
149
|
+
res2["Set-Cookie"].should be_nil
|
150
|
+
res2.body.should == '{"counter"=>3}'
|
151
|
+
|
152
|
+
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
153
|
+
res3["Set-Cookie"][@session_match].should == session
|
154
|
+
res3.body.should == '{"counter"=>4}'
|
155
|
+
end
|
156
|
+
|
157
|
+
# anyone know how to do this better?
|
158
|
+
specify "multithread: should cleanly merge sessions" do
|
159
|
+
next unless $DEBUG
|
160
|
+
warn 'Running multithread test for Session::RufusTyrant'
|
161
|
+
pool = Rack::Session::RufusTyrant.new(@incrementor)
|
162
|
+
req = Rack::MockRequest.new(pool)
|
163
|
+
|
164
|
+
res = req.get('/')
|
165
|
+
res.body.should == '{"counter"=>1}'
|
166
|
+
cookie = res["Set-Cookie"]
|
167
|
+
sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
|
168
|
+
|
169
|
+
delta_incrementor = lambda do |env|
|
170
|
+
# emulate disconjoinment of threading
|
171
|
+
env['rack.session'] = env['rack.session'].dup
|
172
|
+
Thread.stop
|
173
|
+
env['rack.session'][(Time.now.usec*rand).to_i] = true
|
174
|
+
@incrementor.call(env)
|
175
|
+
end
|
176
|
+
tses = Rack::Utils::Context.new pool, delta_incrementor
|
177
|
+
treq = Rack::MockRequest.new(tses)
|
178
|
+
tnum = rand(7).to_i+5
|
179
|
+
r = Array.new(tnum) do
|
180
|
+
Thread.new(treq) do |run|
|
181
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
182
|
+
end
|
183
|
+
end.reverse.map{|t| t.run.join.value }
|
184
|
+
r.each do |res|
|
185
|
+
res['Set-Cookie'].should == cookie
|
186
|
+
res.body.should include('"counter"=>2')
|
187
|
+
end
|
188
|
+
|
189
|
+
session = pool.pool.get(sess_id)
|
190
|
+
session.size.should == tnum+1 # counter
|
191
|
+
session['counter'].should == 2 # meeeh
|
192
|
+
|
193
|
+
tnum = rand(7).to_i+5
|
194
|
+
r = Array.new(tnum) do |i|
|
195
|
+
delta_time = proc do |env|
|
196
|
+
env['rack.session'][i] = Time.now
|
197
|
+
Thread.stop
|
198
|
+
env['rack.session'] = env['rack.session'].dup
|
199
|
+
env['rack.session'][i] -= Time.now
|
200
|
+
@incrementor.call(env)
|
201
|
+
end
|
202
|
+
app = Rack::Utils::Context.new pool, time_delta
|
203
|
+
req = Rack::MockRequest.new app
|
204
|
+
Thread.new(req) do |run|
|
205
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
206
|
+
end
|
207
|
+
end.reverse.map{|t| t.run.join.value }
|
208
|
+
r.each do |res|
|
209
|
+
res['Set-Cookie'].should == cookie
|
210
|
+
res.body.should include('"counter"=>3')
|
211
|
+
end
|
212
|
+
|
213
|
+
session = pool.pool.get(sess_id)
|
214
|
+
session.size.should == tnum+1
|
215
|
+
session['counter'].should == 3
|
216
|
+
|
217
|
+
drop_counter = proc do |env|
|
218
|
+
env['rack.session'].delete 'counter'
|
219
|
+
env['rack.session']['foo'] = 'bar'
|
220
|
+
[200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
|
221
|
+
end
|
222
|
+
tses = Rack::Utils::Context.new pool, drop_counter
|
223
|
+
treq = Rack::MockRequest.new(tses)
|
224
|
+
tnum = rand(7).to_i+5
|
225
|
+
r = Array.new(tnum) do
|
226
|
+
Thread.new(treq) do |run|
|
227
|
+
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
228
|
+
end
|
229
|
+
end.reverse.map{|t| t.run.join.value }
|
230
|
+
r.each do |res|
|
231
|
+
res['Set-Cookie'].should == cookie
|
232
|
+
res.body.should include('"foo"=>"bar"')
|
233
|
+
end
|
234
|
+
|
235
|
+
session = pool.pool.get(sess_id)
|
236
|
+
session.size.should == r.size+1
|
237
|
+
session['counter'].should be_nil
|
238
|
+
session['foo'].should == 'bar'
|
239
|
+
end
|
240
|
+
|
241
|
+
after(:all) do
|
242
|
+
Rack::Session::RufusTyrant.new(@incrementor).pool.clear
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|