redis-store 1.0.0.1 → 1.1.0.rc

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.

Potentially problematic release.


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

Files changed (53) hide show
  1. data/Gemfile +2 -34
  2. data/README.md +17 -220
  3. data/Rakefile +7 -54
  4. data/lib/redis-store.rb +11 -44
  5. data/lib/redis/distributed_store.rb +8 -1
  6. data/lib/redis/factory.rb +17 -21
  7. data/lib/redis/store.rb +3 -8
  8. data/lib/redis/store/interface.rb +4 -0
  9. data/lib/redis/store/marshalling.rb +4 -0
  10. data/lib/redis/store/version.rb +1 -8
  11. data/lib/tasks/redis.tasks.rb +167 -0
  12. data/redis-store.gemspec +22 -97
  13. data/{spec → test}/config/node-one.conf +2 -2
  14. data/{spec → test}/config/node-two.conf +2 -2
  15. data/{spec → test}/config/redis.conf +3 -2
  16. data/{spec/redis/distributed_store_spec.rb → test/redis/distributed_store_test.rb} +13 -15
  17. data/test/redis/factory_test.rb +98 -0
  18. data/test/redis/store/interface_test.rb +27 -0
  19. data/test/redis/store/marshalling_test.rb +127 -0
  20. data/test/redis/store/namespace_test.rb +86 -0
  21. data/test/redis/store/version_test.rb +7 -0
  22. data/test/redis/store_test.rb +17 -0
  23. data/test/test_helper.rb +22 -0
  24. metadata +85 -97
  25. data/.travis.yml +0 -7
  26. data/CHANGELOG +0 -311
  27. data/VERSION +0 -1
  28. data/lib/action_controller/session/redis_session_store.rb +0 -81
  29. data/lib/active_support/cache/redis_store.rb +0 -254
  30. data/lib/cache/merb/redis_store.rb +0 -79
  31. data/lib/cache/sinatra/redis_store.rb +0 -131
  32. data/lib/i18n/backend/redis.rb +0 -67
  33. data/lib/rack/cache/redis_entitystore.rb +0 -48
  34. data/lib/rack/cache/redis_metastore.rb +0 -40
  35. data/lib/rack/session/merb.rb +0 -32
  36. data/lib/rack/session/redis.rb +0 -88
  37. data/spec/action_controller/session/redis_session_store_spec.rb +0 -126
  38. data/spec/active_support/cache/redis_store_spec.rb +0 -426
  39. data/spec/cache/merb/redis_store_spec.rb +0 -143
  40. data/spec/cache/sinatra/redis_store_spec.rb +0 -192
  41. data/spec/i18n/backend/redis_spec.rb +0 -72
  42. data/spec/rack/cache/entitystore/pony.jpg +0 -0
  43. data/spec/rack/cache/entitystore/redis_spec.rb +0 -124
  44. data/spec/rack/cache/metastore/redis_spec.rb +0 -259
  45. data/spec/rack/session/redis_spec.rb +0 -234
  46. data/spec/redis/factory_spec.rb +0 -110
  47. data/spec/redis/store/interface_spec.rb +0 -23
  48. data/spec/redis/store/marshalling_spec.rb +0 -119
  49. data/spec/redis/store/namespace_spec.rb +0 -76
  50. data/spec/redis/store/version_spec.rb +0 -7
  51. data/spec/redis/store_spec.rb +0 -13
  52. data/spec/spec_helper.rb +0 -43
  53. data/tasks/redis.tasks.rb +0 -235
@@ -1,259 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Rack
4
- module Cache
5
- class MetaStore
6
- # courtesy of http://github.com/rtomayko/rack-cache team
7
- describe "Rack::Cache::MetaStore::Redis" do
8
- before :each do
9
- @store = Rack::Cache::MetaStore::Redis.resolve uri("redis://127.0.0.1")
10
- @entity_store = Rack::Cache::EntityStore::Redis.resolve uri("redis://127.0.0.1:6380")
11
- @request = mock_request('/', {})
12
- @response = mock_response(200, {}, ['hello world'])
13
- end
14
-
15
- after :each do
16
- @store.cache.flushall
17
- @entity_store.cache.flushall
18
- end
19
-
20
- it "should have the class referenced by homonym constant" do
21
- Rack::Cache::MetaStore::REDIS.should be(Rack::Cache::MetaStore::Redis)
22
- end
23
-
24
- it "should resolve the connection uri" do
25
- cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://127.0.0.1")).cache
26
- cache.should be_kind_of(::Redis::Store)
27
- cache.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
28
-
29
- cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://127.0.0.1:6380")).cache
30
- cache.to_s.should == "Redis Client connected to 127.0.0.1:6380 against DB 0"
31
-
32
- cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://127.0.0.1/13")).cache
33
- cache.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 13"
34
-
35
- cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://:secret@127.0.0.1")).cache
36
- cache.id.should == "redis://127.0.0.1:6379/0"
37
- cache.client.password.should == 'secret'
38
- end
39
-
40
- # Low-level implementation methods ===========================================
41
-
42
- it 'writes a list of negotation tuples with #write' do
43
- lambda { @store.write('/test', [[{}, {}]]) }.should_not raise_error
44
- end
45
-
46
- it 'reads a list of negotation tuples with #read' do
47
- @store.write('/test', [[{},{}],[{},{}]])
48
- tuples = @store.read('/test')
49
- tuples.should == [ [{},{}], [{},{}] ]
50
- end
51
-
52
- it 'reads an empty list with #read when nothing cached at key' do
53
- @store.read('/nothing').should be_empty
54
- end
55
-
56
- it 'removes entries for key with #purge' do
57
- @store.write('/test', [[{},{}]])
58
- @store.read('/test').should_not be_empty
59
-
60
- @store.purge('/test')
61
- @store.read('/test').should be_empty
62
- end
63
-
64
- it 'succeeds when purging non-existing entries' do
65
- @store.read('/test').should be_empty
66
- @store.purge('/test')
67
- end
68
-
69
- it 'returns nil from #purge' do
70
- @store.write('/test', [[{},{}]])
71
- @store.purge('/test').should be_nil
72
- @store.read('/test').should == []
73
- end
74
-
75
- %w[/test http://example.com:8080/ /test?x=y /test?x=y&p=q].each do |key|
76
- it "can read and write key: '#{key}'" do
77
- lambda { @store.write(key, [[{},{}]]) }.should_not raise_error
78
- @store.read(key).should == [[{},{}]]
79
- end
80
- end
81
-
82
- it "can read and write fairly large keys" do
83
- key = "b" * 4096
84
- lambda { @store.write(key, [[{},{}]]) }.should_not raise_error
85
- @store.read(key).should == [[{},{}]]
86
- end
87
-
88
- it "allows custom cache keys from block" do
89
- request = mock_request('/test', {})
90
- request.env['rack-cache.cache_key'] =
91
- lambda { |request| request.path_info.reverse }
92
- @store.cache_key(request).should == 'tset/'
93
- end
94
-
95
- it "allows custom cache keys from class" do
96
- request = mock_request('/test', {})
97
- request.env['rack-cache.cache_key'] = Class.new do
98
- def self.call(request); request.path_info.reverse end
99
- end
100
- @store.cache_key(request).should == 'tset/'
101
- end
102
-
103
- # Abstract methods ===========================================================
104
-
105
- # Stores an entry for the given request args, returns a url encoded cache key
106
- # for the request.
107
- define_method :store_simple_entry do |*request_args|
108
- path, headers = request_args
109
- @request = mock_request(path || '/test', headers || {})
110
- @response = mock_response(200, {'Cache-Control' => 'max-age=420'}, ['test'])
111
- body = @response.body
112
- cache_key = @store.store(@request, @response, @entity_store)
113
- @response.body.should_not equal(body)
114
- cache_key
115
- end
116
-
117
- it 'stores a cache entry' do
118
- cache_key = store_simple_entry
119
- @store.read(cache_key).should_not be_empty
120
- end
121
-
122
- it 'sets the X-Content-Digest response header before storing' do
123
- cache_key = store_simple_entry
124
- req, res = @store.read(cache_key).first
125
- res['X-Content-Digest'].should == 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3'
126
- end
127
-
128
- it 'finds a stored entry with #lookup' do
129
- store_simple_entry
130
- response = @store.lookup(@request, @entity_store)
131
- response.should_not be_nil
132
- response.should be_kind_of(Rack::Cache::Response)
133
- end
134
-
135
- it 'does not find an entry with #lookup when none exists' do
136
- req = mock_request('/test', {'HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'})
137
- @store.lookup(req, @entity_store).should be_nil
138
- end
139
-
140
- it "canonizes urls for cache keys" do
141
- store_simple_entry(path='/test?x=y&p=q')
142
-
143
- hits_req = mock_request(path, {})
144
- miss_req = mock_request('/test?p=x', {})
145
-
146
- @store.lookup(hits_req, @entity_store).should_not be_nil
147
- @store.lookup(miss_req, @entity_store).should be_nil
148
- end
149
-
150
- it 'does not find an entry with #lookup when the body does not exist' do
151
- store_simple_entry
152
- @response.headers['X-Content-Digest'].should_not be_nil
153
- @entity_store.purge(@response.headers['X-Content-Digest'])
154
- @store.lookup(@request, @entity_store).should be_nil
155
- end
156
-
157
- it 'restores response headers properly with #lookup' do
158
- store_simple_entry
159
- response = @store.lookup(@request, @entity_store)
160
- response.headers.should == @response.headers.merge('Content-Length' => '4')
161
- end
162
-
163
- it 'restores response body from entity store with #lookup' do
164
- store_simple_entry
165
- response = @store.lookup(@request, @entity_store)
166
- body = '' ; response.body.each {|p| body << p}
167
- body.should == 'test'
168
- end
169
-
170
- it 'invalidates meta and entity store entries with #invalidate' do
171
- store_simple_entry
172
- @store.invalidate(@request, @entity_store)
173
- response = @store.lookup(@request, @entity_store)
174
- response.should be_kind_of(Rack::Cache::Response)
175
- response.should_not be_fresh
176
- end
177
-
178
- it 'succeeds quietly when #invalidate called with no matching entries' do
179
- req = mock_request('/test', {})
180
- @store.invalidate(req, @entity_store)
181
- @store.lookup(@request, @entity_store).should be_nil
182
- end
183
-
184
- # Vary =======================================================================
185
-
186
- it 'does not return entries that Vary with #lookup' do
187
- req1 = mock_request('/test', {'HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'})
188
- req2 = mock_request('/test', {'HTTP_FOO' => 'Bling', 'HTTP_BAR' => 'Bam'})
189
- res = mock_response(200, {'Vary' => 'Foo Bar'}, ['test'])
190
- @store.store(req1, res, @entity_store)
191
-
192
- @store.lookup(req2, @entity_store).should be_nil
193
- end
194
-
195
- it 'stores multiple responses for each Vary combination' do
196
- req1 = mock_request('/test', {'HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'})
197
- res1 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 1'])
198
- key = @store.store(req1, res1, @entity_store)
199
-
200
- req2 = mock_request('/test', {'HTTP_FOO' => 'Bling', 'HTTP_BAR' => 'Bam'})
201
- res2 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 2'])
202
- @store.store(req2, res2, @entity_store)
203
-
204
- req3 = mock_request('/test', {'HTTP_FOO' => 'Baz', 'HTTP_BAR' => 'Boom'})
205
- res3 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 3'])
206
- @store.store(req3, res3, @entity_store)
207
-
208
- slurp(@store.lookup(req3, @entity_store).body).should == 'test 3'
209
- slurp(@store.lookup(req1, @entity_store).body).should == 'test 1'
210
- slurp(@store.lookup(req2, @entity_store).body).should == 'test 2'
211
-
212
- @store.read(key).length.should == 3
213
- end
214
-
215
- it 'overwrites non-varying responses with #store' do
216
- req1 = mock_request('/test', {'HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'})
217
- res1 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 1'])
218
- key = @store.store(req1, res1, @entity_store)
219
- slurp(@store.lookup(req1, @entity_store).body).should == 'test 1'
220
-
221
- req2 = mock_request('/test', {'HTTP_FOO' => 'Bling', 'HTTP_BAR' => 'Bam'})
222
- res2 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 2'])
223
- @store.store(req2, res2, @entity_store)
224
- slurp(@store.lookup(req2, @entity_store).body).should == 'test 2'
225
-
226
- req3 = mock_request('/test', {'HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'})
227
- res3 = mock_response(200, {'Vary' => 'Foo Bar'}, ['test 3'])
228
- @store.store(req3, res3, @entity_store)
229
- slurp(@store.lookup(req1, @entity_store).body).should == 'test 3'
230
-
231
- @store.read(key).length.should == 2
232
- end
233
-
234
- # Helper Methods =============================================================
235
-
236
- define_method :mock_request do |uri,opts|
237
- env = Rack::MockRequest.env_for(uri, opts || {})
238
- Rack::Cache::Request.new(env)
239
- end
240
-
241
- define_method :mock_response do |status,headers,body|
242
- headers ||= {}
243
- body = Array(body).compact
244
- Rack::Cache::Response.new(status, headers, body)
245
- end
246
-
247
- define_method :slurp do |body|
248
- buf = ''
249
- body.each {|part| buf << part }
250
- buf
251
- end
252
-
253
- define_method :uri do |uri|
254
- URI.parse uri
255
- end
256
- end
257
- end
258
- end
259
- end
@@ -1,234 +0,0 @@
1
- require '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 => "redis://127.0.0.1:6380/1/theplaylist").pool
30
- pool.should be_kind_of(::Redis::Store)
31
- pool.to_s.should == "Redis Client connected to 127.0.0.1:6380 against DB 1 with namespace theplaylist"
32
-
33
- pool = Rack::Session::Redis.new(@incrementor, :redis_server => ["redis://127.0.0.1:6379", "redis://127.0.0.1:6380"]).pool
34
- pool.should be_kind_of(::Redis::DistributedStore)
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