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.
@@ -0,0 +1,249 @@
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
+ class Tyrant
7
+ attr_reader :host, :port
8
+ end
9
+ describe "Rack::Session::Tyrant" do
10
+ before(:each) do
11
+ @session_key = Rack::Session::Tyrant::DEFAULT_OPTIONS[:key]
12
+ @session_match = /#{@session_key}=[0-9a-fA-F]+;/
13
+ @incrementor = lambda do |env|
14
+ env["rack.session"]["counter"] ||= 0
15
+ env["rack.session"]["counter"] += 1
16
+ Rack::Response.new(env["rack.session"].inspect).to_a
17
+ end
18
+ @drop_session = proc do |env|
19
+ env['rack.session.options'][:drop] = true
20
+ @incrementor.call(env)
21
+ end
22
+ @renew_session = proc do |env|
23
+ env['rack.session.options'][:renew] = true
24
+ @incrementor.call(env)
25
+ end
26
+ @defer_session = proc do |env|
27
+ env['rack.session.options'][:defer] = true
28
+ @incrementor.call(env)
29
+ end
30
+ end
31
+
32
+ it "should specify connection params" do
33
+ pool = Rack::Session::Tyrant.new(@incrementor, :tyrant_server => "127.0.0.1:1978").pool
34
+ pool.should be_kind_of(TokyoTyrant::RDB)
35
+ #pool.host.should eql("127.0.0.1")
36
+ #pool.port.should eql("1978")
37
+
38
+ # pool = Rack::Session::Tyrant.new(@incrementor, :tokyo_server => ["localhost:6379", "localhost:6380"]).pool
39
+ # pool.should be_kind_of(DistributedMarshaledTyrant)
40
+ end
41
+
42
+ it "should not raise error on connect" do
43
+ lambda{ Rack::Session::Tyrant.new(@incrementor, :tyrant_server => "localhost:6380").pool }.
44
+ should_not raise_error
45
+ end
46
+
47
+
48
+ it "creates a new cookie" do
49
+ pool = Rack::Session::Tyrant.new(@incrementor)
50
+ res = Rack::MockRequest.new(pool).get("/")
51
+ res["Set-Cookie"].should match(/#{@session_key}=/)
52
+ res.body.should eql('{"counter"=>1}')
53
+ end
54
+
55
+ it "determines session from a cookie" do
56
+ pool = Rack::Session::Tyrant.new(@incrementor)
57
+ req = Rack::MockRequest.new(pool)
58
+ res = req.get("/")
59
+ cookie = res["Set-Cookie"]
60
+ req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>2}')
61
+ req.get("/", "HTTP_COOKIE" => cookie).body.should eql('{"counter"=>3}')
62
+ end
63
+
64
+ it "survives nonexistant cookies" do
65
+ bad_cookie = "rack.session=blsarghfasel"
66
+ pool = Rack::Session::Tyrant.new(@incrementor)
67
+ res = Rack::MockRequest.new(pool).get("/", "HTTP_COOKIE" => bad_cookie)
68
+ res.body.should eql('{"counter"=>1}')
69
+ cookie = res["Set-Cookie"][@session_match]
70
+ cookie.should_not match(/#{bad_cookie}/)
71
+ end
72
+
73
+ # Expire isn't supported by cabinet. Implement in ruby?
74
+ # it "should maintain freshness" do
75
+ # pool = Rack::Session::Tyrant.new(@incrementor, :expire_after => 3)
76
+ # res = Rack::MockRequest.new(pool).get('/')
77
+ # res.body.should include('"counter"=>1')
78
+ # cookie = res["Set-Cookie"]
79
+ # res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
80
+ # res["Set-Cookie"].should == cookie
81
+ # res.body.should include('"counter"=>2')
82
+ # puts 'Sleeping to expire session' if $DEBUG
83
+ # sleep 4
84
+ # res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
85
+ # res["Set-Cookie"].should_not == cookie
86
+ # res.body.should include('"counter"=>1')
87
+ # end
88
+
89
+ it "deletes cookies with :drop option" do
90
+ pool = Rack::Session::Tyrant.new(@incrementor)
91
+ req = Rack::MockRequest.new(pool)
92
+ drop = Rack::Utils::Context.new(pool, @drop_session)
93
+ dreq = Rack::MockRequest.new(drop)
94
+
95
+ res0 = req.get("/")
96
+ session = (cookie = res0["Set-Cookie"])[@session_match]
97
+ res0.body.should == '{"counter"=>1}'
98
+
99
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
100
+ res1["Set-Cookie"][@session_match].should == session
101
+ res1.body.should == '{"counter"=>2}'
102
+
103
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
104
+ res2["Set-Cookie"].should be_nil
105
+ res2.body.should == '{"counter"=>3}'
106
+
107
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
108
+ res3["Set-Cookie"][@session_match].should_not == session
109
+ res3.body.should == '{"counter"=>1}'
110
+ end
111
+
112
+ it "provides new session id with :renew option" do
113
+ pool = Rack::Session::Tyrant.new(@incrementor)
114
+ req = Rack::MockRequest.new(pool)
115
+ renew = Rack::Utils::Context.new(pool, @renew_session)
116
+ rreq = Rack::MockRequest.new(renew)
117
+
118
+ res0 = req.get("/")
119
+ session = (cookie = res0["Set-Cookie"])[@session_match]
120
+ res0.body.should == '{"counter"=>1}'
121
+
122
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
123
+ res1["Set-Cookie"][@session_match].should == session
124
+ res1.body.should == '{"counter"=>2}'
125
+
126
+ res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
127
+ new_cookie = res2["Set-Cookie"]
128
+ new_session = new_cookie[@session_match]
129
+ new_session.should_not == session
130
+ res2.body.should == '{"counter"=>3}'
131
+
132
+ res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
133
+ res3["Set-Cookie"][@session_match].should == new_session
134
+ res3.body.should == '{"counter"=>4}'
135
+ end
136
+
137
+ specify "omits cookie with :defer option" do
138
+ pool = Rack::Session::Tyrant.new(@incrementor)
139
+ req = Rack::MockRequest.new(pool)
140
+ defer = Rack::Utils::Context.new(pool, @defer_session)
141
+ dreq = Rack::MockRequest.new(defer)
142
+
143
+ res0 = req.get("/")
144
+ session = (cookie = res0["Set-Cookie"])[@session_match]
145
+ res0.body.should == '{"counter"=>1}'
146
+
147
+ res1 = req.get("/", "HTTP_COOKIE" => cookie)
148
+ res1["Set-Cookie"][@session_match].should == session
149
+ res1.body.should == '{"counter"=>2}'
150
+
151
+ res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
152
+ res2["Set-Cookie"].should be_nil
153
+ res2.body.should == '{"counter"=>3}'
154
+
155
+ res3 = req.get("/", "HTTP_COOKIE" => cookie)
156
+ res3["Set-Cookie"][@session_match].should == session
157
+ res3.body.should == '{"counter"=>4}'
158
+ end
159
+
160
+ # anyone know how to do this better?
161
+ specify "multithread: should cleanly merge sessions" do
162
+ next unless $DEBUG
163
+ warn 'Running multithread test for Session::Tyrant'
164
+ pool = Rack::Session::Tyrant.new(@incrementor)
165
+ req = Rack::MockRequest.new(pool)
166
+
167
+ res = req.get('/')
168
+ res.body.should == '{"counter"=>1}'
169
+ cookie = res["Set-Cookie"]
170
+ sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
171
+
172
+ delta_incrementor = lambda do |env|
173
+ # emulate disconjoinment of threading
174
+ env['rack.session'] = env['rack.session'].dup
175
+ Thread.stop
176
+ env['rack.session'][(Time.now.usec*rand).to_i] = true
177
+ @incrementor.call(env)
178
+ end
179
+ tses = Rack::Utils::Context.new pool, delta_incrementor
180
+ treq = Rack::MockRequest.new(tses)
181
+ tnum = rand(7).to_i+5
182
+ r = Array.new(tnum) do
183
+ Thread.new(treq) do |run|
184
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
185
+ end
186
+ end.reverse.map{|t| t.run.join.value }
187
+ r.each do |res|
188
+ res['Set-Cookie'].should == cookie
189
+ res.body.should include('"counter"=>2')
190
+ end
191
+
192
+ session = pool.pool.get(sess_id)
193
+ session.size.should == tnum+1 # counter
194
+ session['counter'].should == 2 # meeeh
195
+
196
+ tnum = rand(7).to_i+5
197
+ r = Array.new(tnum) do |i|
198
+ delta_time = proc do |env|
199
+ env['rack.session'][i] = Time.now
200
+ Thread.stop
201
+ env['rack.session'] = env['rack.session'].dup
202
+ env['rack.session'][i] -= Time.now
203
+ @incrementor.call(env)
204
+ end
205
+ app = Rack::Utils::Context.new pool, time_delta
206
+ req = Rack::MockRequest.new app
207
+ Thread.new(req) do |run|
208
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
209
+ end
210
+ end.reverse.map{|t| t.run.join.value }
211
+ r.each do |res|
212
+ res['Set-Cookie'].should == cookie
213
+ res.body.should include('"counter"=>3')
214
+ end
215
+
216
+ session = pool.pool.get(sess_id)
217
+ session.size.should == tnum+1
218
+ session['counter'].should == 3
219
+
220
+ drop_counter = proc do |env|
221
+ env['rack.session'].delete 'counter'
222
+ env['rack.session']['foo'] = 'bar'
223
+ [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
224
+ end
225
+ tses = Rack::Utils::Context.new pool, drop_counter
226
+ treq = Rack::MockRequest.new(tses)
227
+ tnum = rand(7).to_i+5
228
+ r = Array.new(tnum) do
229
+ Thread.new(treq) do |run|
230
+ run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
231
+ end
232
+ end.reverse.map{|t| t.run.join.value }
233
+ r.each do |res|
234
+ res['Set-Cookie'].should == cookie
235
+ res.body.should include('"foo"=>"bar"')
236
+ end
237
+
238
+ session = pool.pool.get(sess_id)
239
+ session.size.should == r.size+1
240
+ session['counter'].should be_nil
241
+ session['foo'].should == 'bar'
242
+ end
243
+
244
+ after(:all) do
245
+ Rack::Session::Tyrant.new(@incrementor).pool.clear
246
+ end
247
+ end
248
+ end
249
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --loadby mtime
3
+ --reverse
@@ -0,0 +1,13 @@
1
+ $: << File.join(File.dirname(__FILE__), "/../lib")
2
+ %W{rubygems spec rack/cache activesupport }.each { |l| require l }
3
+ require 'tokyo_store'
4
+ require 'rack/session/rufus_tyrant'
5
+ require 'rack/session/tyrant'
6
+ require 'rack/session/cabinet'
7
+ require 'cache/tokyo_store'
8
+ #require 'rack/cache/tokyo'
9
+
10
+ #Simple class to test marshal
11
+ class City; attr_accessor :name, :pop;end
12
+
13
+ Spec::Runner.configure do |config|;end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ if ENV['CABINET']
4
+ describe "TokyoStore" do
5
+ it "should store fragment cache" do
6
+ HDB.should_receive(:new).and_return(@mock_hdb = mock("HDB"))
7
+ @mock_hdb.should_receive(:open).with('data.tch', 6).and_return(true)
8
+ store = ActiveSupport::Cache.lookup_store :tokyo_store, "data.tch"
9
+ store.should be_kind_of ActiveSupport::Cache::TokyoStore
10
+ end
11
+
12
+ it "should fail" do
13
+ tokyo = HDB.new
14
+ tokyo.open('data.tch')
15
+ HDB.should_not_receive(:new)
16
+ store = ActiveSupport::Cache.lookup_store :tokyo_store, tokyo
17
+ store.should be_kind_of ActiveSupport::Cache::TokyoStore
18
+ end
19
+
20
+ describe "Similar" do
21
+
22
+ before(:all) do
23
+ @cache = ActiveSupport::Cache::TokyoStore.new 'data.tcb'
24
+ end
25
+
26
+ it "test_should_read_and_write_strings" do
27
+ @cache.write('foo', 'bar')
28
+ @cache.read('foo').should eql('bar')
29
+ end
30
+
31
+ it "test_should_read_and_write_hash" do
32
+ @cache.write('foo', {:a => "b"})
33
+ @cache.read('foo').should eql({:a => "b"})
34
+ end
35
+
36
+ it "test_should_read_and_write_hash" do
37
+ @cache.write('foo', {:a => "b", :c => "d"})
38
+ @cache.read('foo').should eql({:a => "b", :c => "d"})
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{tokyo_store}
5
+ s.version = "0.3.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Marcos Piccinini"]
9
+ s.date = %q{2009-07-19}
10
+ s.email = %q{x@nofxx.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "benchmark/cache.rb",
23
+ "benchmark/session.rb",
24
+ "lib/cache/tokyo_store.rb",
25
+ "lib/rack/cache/tokyo_entitystore.rb",
26
+ "lib/rack/cache/tokyo_metastore.rb",
27
+ "lib/rack/session/cabinet.rb",
28
+ "lib/rack/session/rufus_tyrant.rb",
29
+ "lib/rack/session/tyrant.rb",
30
+ "lib/tokyo_store.rb",
31
+ "spec/cache/tokyo_store_spec.rb",
32
+ "spec/rack/cache/tokyo_spec.rb",
33
+ "spec/rack/session/cabinet_spec.rb",
34
+ "spec/rack/session/rufus_tyrant_spec.rb",
35
+ "spec/rack/session/tyrant_spec.rb",
36
+ "spec/spec.opts",
37
+ "spec/spec_helper.rb",
38
+ "spec/tokyo_store_spec.rb",
39
+ "tokyo_store.gemspec"
40
+ ]
41
+ s.homepage = %q{http://github.com/nofxx/tokyo_store}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.4}
45
+ s.summary = %q{Tokyo Tyrant rails session store}
46
+ s.test_files = [
47
+ "spec/rack/cache/tokyo_spec.rb",
48
+ "spec/rack/session/rufus_tyrant_spec.rb",
49
+ "spec/rack/session/cabinet_spec.rb",
50
+ "spec/rack/session/tyrant_spec.rb",
51
+ "spec/tokyo_store_spec.rb",
52
+ "spec/cache/tokyo_store_spec.rb",
53
+ "spec/spec_helper.rb"
54
+ ]
55
+
56
+ if s.respond_to? :specification_version then
57
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
+ s.specification_version = 3
59
+
60
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
+ else
62
+ end
63
+ else
64
+ end
65
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tokyo_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Marcos Piccinini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-19 00:00:00 -03:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: x@nofxx.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - benchmark/cache.rb
33
+ - benchmark/session.rb
34
+ - lib/cache/tokyo_store.rb
35
+ - lib/rack/cache/tokyo_entitystore.rb
36
+ - lib/rack/cache/tokyo_metastore.rb
37
+ - lib/rack/session/cabinet.rb
38
+ - lib/rack/session/rufus_tyrant.rb
39
+ - lib/rack/session/tyrant.rb
40
+ - lib/tokyo_store.rb
41
+ - spec/cache/tokyo_store_spec.rb
42
+ - spec/rack/cache/tokyo_spec.rb
43
+ - spec/rack/session/cabinet_spec.rb
44
+ - spec/rack/session/rufus_tyrant_spec.rb
45
+ - spec/rack/session/tyrant_spec.rb
46
+ - spec/spec.opts
47
+ - spec/spec_helper.rb
48
+ - spec/tokyo_store_spec.rb
49
+ - tokyo_store.gemspec
50
+ has_rdoc: true
51
+ homepage: http://github.com/nofxx/tokyo_store
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Tokyo Tyrant rails session store
78
+ test_files:
79
+ - spec/rack/cache/tokyo_spec.rb
80
+ - spec/rack/session/rufus_tyrant_spec.rb
81
+ - spec/rack/session/cabinet_spec.rb
82
+ - spec/rack/session/tyrant_spec.rb
83
+ - spec/tokyo_store_spec.rb
84
+ - spec/cache/tokyo_store_spec.rb
85
+ - spec/spec_helper.rb