dalli 2.7.2 → 3.0.0

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

Potentially problematic release.


This version of dalli might be problematic. Click here for more details.

@@ -1,128 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'failover' do
4
-
5
- describe 'timeouts' do
6
- it 'not lead to corrupt sockets' do
7
- memcached(29125) do
8
- dc = Dalli::Client.new ['localhost:29125']
9
- begin
10
- Timeout.timeout 0.01 do
11
- 1_000.times do
12
- dc.set("test_123", {:test => "123"})
13
- end
14
- flunk("Did not timeout")
15
- end
16
- rescue Timeout::Error
17
- end
18
-
19
- assert_equal({:test => '123'}, dc.get("test_123"))
20
- end
21
- end
22
- end
23
-
24
-
25
- describe 'assuming some bad servers' do
26
-
27
- it 'silently reconnect if server hiccups' do
28
- memcached(29125) do
29
- dc = Dalli::Client.new ['localhost:29125']
30
- dc.set 'foo', 'bar'
31
- foo = dc.get 'foo'
32
- assert_equal foo, 'bar'
33
-
34
- memcached_kill(29125)
35
- memcached(29125) do
36
-
37
- foo = dc.get 'foo'
38
- assert_nil foo
39
-
40
- memcached_kill(29125)
41
- end
42
- end
43
- end
44
-
45
- it 'handle graceful failover' do
46
- memcached(29125) do
47
- memcached(29126) do
48
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
49
- dc.set 'foo', 'bar'
50
- foo = dc.get 'foo'
51
- assert_equal foo, 'bar'
52
-
53
- memcached_kill(29125)
54
-
55
- dc.set 'foo', 'bar'
56
- foo = dc.get 'foo'
57
- assert_equal foo, 'bar'
58
-
59
- memcached_kill(29126)
60
-
61
- assert_raises Dalli::RingError, :message => "No server available" do
62
- dc.set 'foo', 'bar'
63
- end
64
- end
65
- end
66
- end
67
-
68
- it 'handle them gracefully in get_multi' do
69
- memcached(29125) do
70
- memcached(29126) do
71
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
72
- dc.set 'a', 'a1'
73
- result = dc.get_multi ['a']
74
- assert_equal result, {'a' => 'a1'}
75
-
76
- memcached_kill(29125)
77
-
78
- result = dc.get_multi ['a']
79
- assert_equal result, {'a' => 'a1'}
80
- end
81
- end
82
- end
83
-
84
- it 'handle graceful failover in get_multi' do
85
- memcached(29125) do
86
- memcached(29126) do
87
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
88
- dc.set 'foo', 'foo1'
89
- dc.set 'bar', 'bar1'
90
- result = dc.get_multi ['foo', 'bar']
91
- assert_equal result, {'foo' => 'foo1', 'bar' => 'bar1'}
92
-
93
- memcached_kill(29125)
94
-
95
- dc.set 'foo', 'foo1'
96
- dc.set 'bar', 'bar1'
97
- result = dc.get_multi ['foo', 'bar']
98
- assert_equal result, {'foo' => 'foo1', 'bar' => 'bar1'}
99
-
100
- memcached_kill(29126)
101
-
102
- result = dc.get_multi ['foo', 'bar']
103
- assert_equal result, {}
104
- end
105
- end
106
- end
107
-
108
- it 'stats it still properly report' do
109
- memcached(29125) do
110
- memcached(29126) do
111
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
112
- result = dc.stats
113
- assert_instance_of Hash, result['localhost:29125']
114
- assert_instance_of Hash, result['localhost:29126']
115
-
116
- memcached_kill(29125)
117
-
118
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
119
- result = dc.stats
120
- assert_instance_of NilClass, result['localhost:29125']
121
- assert_instance_of Hash, result['localhost:29126']
122
-
123
- memcached_kill(29126)
124
- end
125
- end
126
- end
127
- end
128
- end
data/test/test_network.rb DELETED
@@ -1,54 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'Network' do
4
-
5
- describe 'assuming a bad network' do
6
-
7
- it 'handle no server available' do
8
- assert_raises Dalli::RingError, :message => "No server available" do
9
- dc = Dalli::Client.new 'localhost:19333'
10
- dc.get 'foo'
11
- end
12
- end
13
-
14
- describe 'with a fake server' do
15
- it 'handle connection reset' do
16
- memcached_mock(lambda {|sock| sock.close }) do
17
- assert_raises Dalli::RingError, :message => "No server available" do
18
- dc = Dalli::Client.new('localhost:19123')
19
- dc.get('abc')
20
- end
21
- end
22
- end
23
-
24
- it 'handle malformed response' do
25
- memcached_mock(lambda {|sock| sock.write('123') }) do
26
- assert_raises Dalli::RingError, :message => "No server available" do
27
- dc = Dalli::Client.new('localhost:19123')
28
- dc.get('abc')
29
- end
30
- end
31
- end
32
-
33
- it 'handle connect timeouts' do
34
- memcached_mock(lambda {|sock| sleep(0.6); sock.close }, :delayed_start) do
35
- assert_raises Dalli::RingError, :message => "No server available" do
36
- dc = Dalli::Client.new('localhost:19123')
37
- dc.get('abc')
38
- end
39
- end
40
- end
41
-
42
- it 'handle read timeouts' do
43
- memcached_mock(lambda {|sock| sleep(0.6); sock.write('giraffe') }) do
44
- assert_raises Dalli::RingError, :message => "No server available" do
45
- dc = Dalli::Client.new('localhost:19123')
46
- dc.get('abc')
47
- end
48
- end
49
- end
50
-
51
- end
52
-
53
- end
54
- end
@@ -1,341 +0,0 @@
1
- require 'helper'
2
-
3
- require 'rack/session/dalli'
4
- require 'rack/lint'
5
- require 'rack/mock'
6
- require 'thread'
7
-
8
- describe Rack::Session::Dalli do
9
- Rack::Session::Dalli::DEFAULT_OPTIONS[:memcache_server] = 'localhost:19129'
10
-
11
- before do
12
- memcached(19129) do
13
- end
14
-
15
- # test memcache connection
16
- Rack::Session::Dalli.new(incrementor)
17
- end
18
-
19
- let(:session_key) { Rack::Session::Dalli::DEFAULT_OPTIONS[:key] }
20
- let(:session_match) do
21
- /#{session_key}=([0-9a-fA-F]+);/
22
- end
23
- let(:incrementor_proc) do
24
- lambda do |env|
25
- env["rack.session"]["counter"] ||= 0
26
- env["rack.session"]["counter"] += 1
27
- Rack::Response.new(env["rack.session"].inspect).to_a
28
- end
29
- end
30
- let(:drop_session) do
31
- Rack::Lint.new(proc do |env|
32
- env['rack.session.options'][:drop] = true
33
- incrementor_proc.call(env)
34
- end)
35
- end
36
- let(:renew_session) do
37
- Rack::Lint.new(proc do |env|
38
- env['rack.session.options'][:renew] = true
39
- incrementor_proc.call(env)
40
- end)
41
- end
42
- let(:defer_session) do
43
- Rack::Lint.new(proc do |env|
44
- env['rack.session.options'][:defer] = true
45
- incrementor_proc.call(env)
46
- end)
47
- end
48
- let(:skip_session) do
49
- Rack::Lint.new(proc do |env|
50
- env['rack.session.options'][:skip] = true
51
- incrementor_proc.call(env)
52
- end)
53
- end
54
- let(:incrementor) { Rack::Lint.new(incrementor_proc) }
55
-
56
- it "faults on no connection" do
57
- assert_raises Dalli::RingError do
58
- Rack::Session::Dalli.new(incrementor, :memcache_server => 'nosuchserver')
59
- end
60
- end
61
-
62
- it "connects to existing server" do
63
- assert_silent do
64
- rsd = Rack::Session::Dalli.new(incrementor, :namespace => 'test:rack:session')
65
- rsd.pool.set('ping', '')
66
- end
67
- end
68
-
69
- it "passes options to MemCache" do
70
- rsd = Rack::Session::Dalli.new(incrementor, :namespace => 'test:rack:session')
71
- assert_equal('test:rack:session', rsd.pool.instance_eval { @options[:namespace] })
72
- end
73
-
74
- it "creates a new cookie" do
75
- rsd = Rack::Session::Dalli.new(incrementor)
76
- res = Rack::MockRequest.new(rsd).get("/")
77
- assert res["Set-Cookie"].include?("#{session_key}=")
78
- assert_equal '{"counter"=>1}', res.body
79
- end
80
-
81
- it "determines session from a cookie" do
82
- rsd = Rack::Session::Dalli.new(incrementor)
83
- req = Rack::MockRequest.new(rsd)
84
- res = req.get("/")
85
- cookie = res["Set-Cookie"]
86
- assert_equal '{"counter"=>2}', req.get("/", "HTTP_COOKIE" => cookie).body
87
- assert_equal '{"counter"=>3}', req.get("/", "HTTP_COOKIE" => cookie).body
88
- end
89
-
90
- it "determines session only from a cookie by default" do
91
- rsd = Rack::Session::Dalli.new(incrementor)
92
- req = Rack::MockRequest.new(rsd)
93
- res = req.get("/")
94
- sid = res["Set-Cookie"][session_match, 1]
95
- assert_equal '{"counter"=>1}', req.get("/?rack.session=#{sid}").body
96
- assert_equal '{"counter"=>1}', req.get("/?rack.session=#{sid}").body
97
- end
98
-
99
- it "determines session from params" do
100
- rsd = Rack::Session::Dalli.new(incrementor, :cookie_only => false)
101
- req = Rack::MockRequest.new(rsd)
102
- res = req.get("/")
103
- sid = res["Set-Cookie"][session_match, 1]
104
- assert_equal '{"counter"=>2}', req.get("/?rack.session=#{sid}").body
105
- assert_equal '{"counter"=>3}', req.get("/?rack.session=#{sid}").body
106
- end
107
-
108
- it "survives nonexistant cookies" do
109
- bad_cookie = "rack.session=blarghfasel"
110
- rsd = Rack::Session::Dalli.new(incrementor)
111
- res = Rack::MockRequest.new(rsd).
112
- get("/", "HTTP_COOKIE" => bad_cookie)
113
- assert_equal '{"counter"=>1}', res.body
114
- cookie = res["Set-Cookie"][session_match]
115
- refute_match(/#{bad_cookie}/, cookie)
116
- end
117
-
118
- it "survives nonexistant blank cookies" do
119
- bad_cookie = "rack.session="
120
- rsd = Rack::Session::Dalli.new(incrementor)
121
- res = Rack::MockRequest.new(rsd).
122
- get("/", "HTTP_COOKIE" => bad_cookie)
123
- cookie = res["Set-Cookie"][session_match]
124
- refute_match(/#{bad_cookie}$/, cookie)
125
- end
126
-
127
- it "maintains freshness" do
128
- rsd = Rack::Session::Dalli.new(incrementor, :expire_after => 3)
129
- res = Rack::MockRequest.new(rsd).get('/')
130
- assert res.body.include?('"counter"=>1')
131
- cookie = res["Set-Cookie"]
132
- res = Rack::MockRequest.new(rsd).get('/', "HTTP_COOKIE" => cookie)
133
- assert_equal cookie, res["Set-Cookie"]
134
- assert res.body.include?('"counter"=>2')
135
- puts 'Sleeping to expire session' if $DEBUG
136
- sleep 4
137
- res = Rack::MockRequest.new(rsd).get('/', "HTTP_COOKIE" => cookie)
138
- refute_equal cookie, res["Set-Cookie"]
139
- assert res.body.include?('"counter"=>1')
140
- end
141
-
142
- it "does not send the same session id if it did not change" do
143
- rsd = Rack::Session::Dalli.new(incrementor)
144
- req = Rack::MockRequest.new(rsd)
145
-
146
- res0 = req.get("/")
147
- cookie = res0["Set-Cookie"][session_match]
148
- assert_equal '{"counter"=>1}', res0.body
149
-
150
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
151
- assert_nil res1["Set-Cookie"]
152
- assert_equal '{"counter"=>2}', res1.body
153
-
154
- res2 = req.get("/", "HTTP_COOKIE" => cookie)
155
- assert_nil res2["Set-Cookie"]
156
- assert_equal '{"counter"=>3}', res2.body
157
- end
158
-
159
- it "deletes cookies with :drop option" do
160
- rsd = Rack::Session::Dalli.new(incrementor)
161
- req = Rack::MockRequest.new(rsd)
162
- drop = Rack::Utils::Context.new(rsd, drop_session)
163
- dreq = Rack::MockRequest.new(drop)
164
-
165
- res1 = req.get("/")
166
- session = (cookie = res1["Set-Cookie"])[session_match]
167
- assert_equal '{"counter"=>1}', res1.body
168
-
169
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
170
- assert_nil res2["Set-Cookie"]
171
- assert_equal '{"counter"=>2}', res2.body
172
-
173
- res3 = req.get("/", "HTTP_COOKIE" => cookie)
174
- refute_equal session, res3["Set-Cookie"][session_match]
175
- assert_equal '{"counter"=>1}', res3.body
176
- end
177
-
178
- it "provides new session id with :renew option" do
179
- rsd = Rack::Session::Dalli.new(incrementor)
180
- req = Rack::MockRequest.new(rsd)
181
- renew = Rack::Utils::Context.new(rsd, renew_session)
182
- rreq = Rack::MockRequest.new(renew)
183
-
184
- res1 = req.get("/")
185
- session = (cookie = res1["Set-Cookie"])[session_match]
186
- assert_equal '{"counter"=>1}', res1.body
187
-
188
- res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
189
- new_cookie = res2["Set-Cookie"]
190
- new_session = new_cookie[session_match]
191
- refute_equal session, new_session
192
- assert_equal '{"counter"=>2}', res2.body
193
-
194
- res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
195
- assert_equal '{"counter"=>3}', res3.body
196
-
197
- # Old cookie was deleted
198
- res4 = req.get("/", "HTTP_COOKIE" => cookie)
199
- assert_equal '{"counter"=>1}', res4.body
200
- end
201
-
202
- it "omits cookie with :defer option but still updates the state" do
203
- rsd = Rack::Session::Dalli.new(incrementor)
204
- count = Rack::Utils::Context.new(rsd, incrementor)
205
- defer = Rack::Utils::Context.new(rsd, defer_session)
206
- dreq = Rack::MockRequest.new(defer)
207
- creq = Rack::MockRequest.new(count)
208
-
209
- res0 = dreq.get("/")
210
- assert_nil res0["Set-Cookie"]
211
- assert_equal '{"counter"=>1}', res0.body
212
-
213
- res0 = creq.get("/")
214
- res1 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
215
- assert_equal '{"counter"=>2}', res1.body
216
- res2 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
217
- assert_equal '{"counter"=>3}', res2.body
218
- end
219
-
220
- it "omits cookie and state update with :skip option" do
221
- rsd = Rack::Session::Dalli.new(incrementor)
222
- count = Rack::Utils::Context.new(rsd, incrementor)
223
- skip = Rack::Utils::Context.new(rsd, skip_session)
224
- sreq = Rack::MockRequest.new(skip)
225
- creq = Rack::MockRequest.new(count)
226
-
227
- res0 = sreq.get("/")
228
- assert_nil res0["Set-Cookie"]
229
- assert_equal '{"counter"=>1}', res0.body
230
-
231
- res0 = creq.get("/")
232
- res1 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
233
- assert_equal '{"counter"=>2}', res1.body
234
- res2 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
235
- assert_equal '{"counter"=>2}', res2.body
236
- end
237
-
238
- it "updates deep hashes correctly" do
239
- hash_check = proc do |env|
240
- session = env['rack.session']
241
- unless session.include? 'test'
242
- session.update :a => :b, :c => { :d => :e },
243
- :f => { :g => { :h => :i} }, 'test' => true
244
- else
245
- session[:f][:g][:h] = :j
246
- end
247
- [200, {}, [session.inspect]]
248
- end
249
- rsd = Rack::Session::Dalli.new(hash_check)
250
- req = Rack::MockRequest.new(rsd)
251
-
252
- res0 = req.get("/")
253
- session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
254
- ses0 = rsd.pool.get(session_id, true)
255
-
256
- req.get("/", "HTTP_COOKIE" => cookie)
257
- ses1 = rsd.pool.get(session_id, true)
258
-
259
- refute_equal ses0, ses1
260
- end
261
-
262
- # anyone know how to do this better?
263
- it "cleanly merges sessions when multithreaded" do
264
- unless $DEBUG
265
- assert_equal 1, 1 # fake assertion to appease the mighty bacon
266
- next
267
- end
268
- warn 'Running multithread test for Session::Dalli'
269
- rsd = Rack::Session::Dalli.new(incrementor)
270
- req = Rack::MockRequest.new(rsd)
271
-
272
- res = req.get('/')
273
- assert_equal '{"counter"=>1}', res.body
274
- cookie = res["Set-Cookie"]
275
- session_id = cookie[session_match, 1]
276
-
277
- delta_incrementor = lambda do |env|
278
- # emulate disconjoinment of threading
279
- env['rack.session'] = env['rack.session'].dup
280
- Thread.stop
281
- env['rack.session'][(Time.now.usec*rand).to_i] = true
282
- incrementor.call(env)
283
- end
284
- tses = Rack::Utils::Context.new rsd, delta_incrementor
285
- treq = Rack::MockRequest.new(tses)
286
- tnum = rand(7).to_i+5
287
- r = Array.new(tnum) do
288
- Thread.new(treq) do |run|
289
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
290
- end
291
- end.reverse.map{|t| t.run.join.value }
292
- r.each do |request|
293
- assert_equal cookie, request['Set-Cookie']
294
- assert request.body.include?('"counter"=>2')
295
- end
296
-
297
- session = rsd.pool.get(session_id)
298
- assert_equal tnum+1, session.size # counter
299
- assert_equal 2, session['counter'] # meeeh
300
-
301
- tnum = rand(7).to_i+5
302
- r = Array.new(tnum) do |i|
303
- app = Rack::Utils::Context.new rsd, time_delta
304
- req = Rack::MockRequest.new app
305
- Thread.new(req) do |run|
306
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
307
- end
308
- end.reverse.map{|t| t.run.join.value }
309
- r.each do |request|
310
- assert_equal cookie, request['Set-Cookie']
311
- assert request.body.include?('"counter"=>3')
312
- end
313
-
314
- session = rsd.pool.get(session_id)
315
- assert_equal tnum+1, session.size
316
- assert_equal 3, session['counter']
317
-
318
- drop_counter = proc do |env|
319
- env['rack.session'].delete 'counter'
320
- env['rack.session']['foo'] = 'bar'
321
- [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
322
- end
323
- tses = Rack::Utils::Context.new rsd, drop_counter
324
- treq = Rack::MockRequest.new(tses)
325
- tnum = rand(7).to_i+5
326
- r = Array.new(tnum) do
327
- Thread.new(treq) do |run|
328
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
329
- end
330
- end.reverse.map{|t| t.run.join.value }
331
- r.each do |request|
332
- assert_equal cookie, request['Set-Cookie']
333
- assert request.body.include?('"foo"=>"bar"')
334
- end
335
-
336
- session = rsd.pool.get(session_id)
337
- assert_equal r.size+1, session.size
338
- assert_nil session['counter']
339
- assert_equal 'bar', session['foo']
340
- end
341
- end
data/test/test_ring.rb DELETED
@@ -1,85 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'Ring' do
4
-
5
- describe 'a ring of servers' do
6
-
7
- it "have the continuum sorted by value" do
8
- servers = [stub(:hostname => "localhost", :port => "11211", :weight => 1),
9
- stub(:hostname => "localhost", :port => "9500", :weight => 1)]
10
- ring = Dalli::Ring.new(servers, {})
11
- previous_value = 0
12
- ring.continuum.each do |entry|
13
- assert entry.value > previous_value
14
- previous_value = entry.value
15
- end
16
- end
17
-
18
- it 'raise when no servers are available/defined' do
19
- ring = Dalli::Ring.new([], {})
20
- assert_raises Dalli::RingError, :message => "No server available" do
21
- ring.server_for_key('test')
22
- end
23
- end
24
-
25
- describe 'containing only a single server' do
26
- it "raise correctly when it's not alive" do
27
- servers = [
28
- Dalli::Server.new("localhost:12345"),
29
- ]
30
- ring = Dalli::Ring.new(servers, {})
31
- assert_raises Dalli::RingError, :message => "No server available" do
32
- ring.server_for_key('test')
33
- end
34
- end
35
-
36
- it "return the server when it's alive" do
37
- servers = [
38
- Dalli::Server.new("localhost:19191"),
39
- ]
40
- ring = Dalli::Ring.new(servers, {})
41
- memcached(19191) do |mc|
42
- ring = mc.send(:ring)
43
- assert_equal ring.servers.first.port, ring.server_for_key('test').port
44
- end
45
- end
46
- end
47
-
48
- describe 'containing multiple servers' do
49
- it "raise correctly when no server is alive" do
50
- servers = [
51
- Dalli::Server.new("localhost:12345"),
52
- Dalli::Server.new("localhost:12346"),
53
- ]
54
- ring = Dalli::Ring.new(servers, {})
55
- assert_raises Dalli::RingError, :message => "No server available" do
56
- ring.server_for_key('test')
57
- end
58
- end
59
-
60
- it "return an alive server when at least one is alive" do
61
- servers = [
62
- Dalli::Server.new("localhost:12346"),
63
- Dalli::Server.new("localhost:19191"),
64
- ]
65
- ring = Dalli::Ring.new(servers, {})
66
- memcached(19191) do |mc|
67
- ring = mc.send(:ring)
68
- assert_equal ring.servers.first.port, ring.server_for_key('test').port
69
- end
70
- end
71
- end
72
-
73
- it 'detect when a dead server is up again' do
74
- memcached(19997) do
75
- down_retry_delay = 0.5
76
- dc = Dalli::Client.new(['localhost:19997', 'localhost:19998'], :down_retry_delay => down_retry_delay)
77
- assert_equal 1, dc.stats.values.compact.count
78
-
79
- memcached(19998) do
80
- assert_equal 2, dc.stats.values.compact.count
81
- end
82
- end
83
- end
84
- end
85
- end