jashmenn-dalli 1.0.3

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,54 @@
1
+ $TESTING = true
2
+ require 'rubygems'
3
+ # require 'simplecov'
4
+ # SimpleCov.start
5
+ RAILS_VERSION = ENV['RAILS_VERSION'] || '~> 3.0.0'
6
+ #puts "Testing with Rails #{RAILS_VERSION}"
7
+ gem 'rails', RAILS_VERSION
8
+
9
+ require 'test/unit'
10
+ require 'shoulda'
11
+ require 'memcached_mock'
12
+ require 'mocha'
13
+
14
+ require 'dalli'
15
+ require 'logger'
16
+
17
+ Dalli.logger = Logger.new(STDOUT)
18
+ Dalli.logger.level = Logger::ERROR
19
+
20
+ class Test::Unit::TestCase
21
+ include MemcachedMock::Helper
22
+
23
+ def rails3?
24
+ RAILS_VERSION =~ /3\.0\./
25
+ end
26
+
27
+ def assert_error(error, regexp=nil, &block)
28
+ ex = assert_raise(error, &block)
29
+ assert_match(regexp, ex.message, "#{ex.class.name}: #{ex.message}\n#{ex.backtrace.join("\n\t")}")
30
+ end
31
+
32
+ def with_activesupport
33
+ case
34
+ when rails3?
35
+ require 'active_support/all'
36
+ else
37
+ require 'active_support'
38
+ require 'active_support/cache/dalli_store23'
39
+ end
40
+ yield
41
+ end
42
+
43
+ def with_actionpack
44
+ case
45
+ when rails3?
46
+ require 'action_dispatch'
47
+ require 'action_controller'
48
+ # when '2.3.0'
49
+ # raise NotImplementedError
50
+ end
51
+ yield
52
+ end
53
+
54
+ end
@@ -0,0 +1,106 @@
1
+ require "socket"
2
+
3
+ $started = {}
4
+
5
+ module MemcachedMock
6
+ def self.start(port=19123, &block)
7
+ server = TCPServer.new("localhost", port)
8
+ session = server.accept
9
+ block.call session
10
+ end
11
+
12
+ def self.delayed_start(port=19123, wait=1, &block)
13
+ server = TCPServer.new("localhost", port)
14
+ sleep wait
15
+ block.call server
16
+ end
17
+
18
+ module Helper
19
+ # Forks the current process and starts a new mock Memcached server on
20
+ # port 22122.
21
+ #
22
+ # memcached_mock(lambda {|sock| socket.write('123') }) do
23
+ # assert_equal "PONG", Dalli::Client.new('localhost:22122').get('abc')
24
+ # end
25
+ #
26
+ def memcached_mock(proc, meth = :start)
27
+ begin
28
+ pid = fork do
29
+ trap("TERM") { exit }
30
+
31
+ MemcachedMock.send(meth) do |*args|
32
+ proc.call(*args)
33
+ end
34
+ end
35
+
36
+ sleep 0.3 # Give time for the socket to start listening.
37
+ yield
38
+ ensure
39
+ if pid
40
+ Process.kill("TERM", pid)
41
+ Process.wait(pid)
42
+ end
43
+ end
44
+ end
45
+
46
+ PATHS = %w(
47
+ /usr/local/bin/
48
+ /opt/local/bin/
49
+ /usr/bin/
50
+ )
51
+
52
+ def find_memcached
53
+ output = `memcached -h | head -1`.strip
54
+ if output && output =~ /^memcached (\d.\d.\d+)/ && $1 > '1.4'
55
+ return (puts "Found #{output} in PATH"; '')
56
+ end
57
+ PATHS.each do |path|
58
+ output = `memcached -h | head -1`.strip
59
+ if output && output =~ /^memcached (\d\.\d\.\d+)/ && $1 > '1.4'
60
+ return (puts "Found #{output} in #{path}"; path)
61
+ end
62
+ end
63
+
64
+ raise Errno::ENOENT, "Unable to find memcached 1.4+ locally"
65
+ nil
66
+ end
67
+
68
+ def memcached(port=19122, args='')
69
+ Memcached.path ||= find_memcached
70
+ cmd = "#{Memcached.path}memcached #{args} -p #{port}"
71
+ $started[port] ||= begin
72
+ #puts "Starting: #{cmd}..."
73
+ pid = IO.popen(cmd).pid
74
+ at_exit do
75
+ begin
76
+ Process.kill("TERM", pid)
77
+ Process.wait(pid)
78
+ rescue Errno::ECHILD, Errno::ESRCH
79
+ end
80
+ end
81
+ sleep 0.1
82
+ pid
83
+ end
84
+
85
+ yield Dalli::Client.new(["localhost:#{port}", "127.0.0.1:#{port}"])
86
+ end
87
+
88
+ def memcached_kill(port)
89
+ pid = $started.delete(port)
90
+ if pid
91
+ begin
92
+ Process.kill("TERM", pid)
93
+ Process.wait(pid)
94
+ rescue Errno::ECHILD, Errno::ESRCH
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+ end
101
+
102
+ module Memcached
103
+ class << self
104
+ attr_accessor :path
105
+ end
106
+ end
@@ -0,0 +1,177 @@
1
+ require 'helper'
2
+
3
+ class TestActiveSupport < Test::Unit::TestCase
4
+ context 'active_support caching' do
5
+
6
+ should 'support fetch' do
7
+ with_activesupport do
8
+ memcached do
9
+ connect
10
+ mvalue = @mc.fetch('somekeywithoutspaces', :expires_in => 1.second) { 123 }
11
+ dvalue = @dalli.fetch('someotherkeywithoutspaces', :expires_in => 1.second) { 123 }
12
+ assert_equal 123, dvalue
13
+ assert_equal mvalue, dvalue
14
+
15
+ o = Object.new
16
+ o.instance_variable_set :@foo, 'bar'
17
+ mvalue = @mc.fetch(rand_key, :raw => true) { o }
18
+ dvalue = @dalli.fetch(rand_key, :raw => true) { o }
19
+ assert_equal mvalue, dvalue
20
+ assert_equal o, mvalue
21
+
22
+ mvalue = @mc.fetch(rand_key) { o }
23
+ dvalue = @dalli.fetch(rand_key) { o }
24
+ assert_equal mvalue, dvalue
25
+ assert_equal o, dvalue
26
+ end
27
+ end
28
+ end
29
+
30
+ should 'support keys with spaces on Rails3' do
31
+ with_activesupport do
32
+ memcached do
33
+ connect
34
+ case
35
+ when rails3?
36
+ dvalue = @mc.fetch('some key with spaces', :expires_in => 1.second) { 123 }
37
+ mvalue = @dalli.fetch('some other key with spaces', :expires_in => 1.second) { 123 }
38
+ assert_equal mvalue, dvalue
39
+ else
40
+ assert_raises ArgumentError do
41
+ @mc.fetch('some key with spaces', :expires_in => 1.second) { 123 }
42
+ end
43
+ assert_raises ArgumentError do
44
+ @dalli.fetch('some other key with spaces', :expires_in => 1.second) { 123 }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ should 'support read_multi' do
52
+ with_activesupport do
53
+ memcached do
54
+ connect
55
+ x = rand_key
56
+ y = rand_key
57
+ assert_equal({}, @mc.read_multi(x, y))
58
+ assert_equal({}, @dalli.read_multi(x, y))
59
+ @dalli.write(x, '123')
60
+ @dalli.write(y, 123)
61
+ @mc.write(x, '123')
62
+ @mc.write(y, 123)
63
+ assert_equal({ x => '123', y => 123 }, @dalli.read_multi(x, y))
64
+ assert_equal({ x => '123', y => 123 }, @mc.read_multi(x, y))
65
+ end
66
+ end
67
+ end
68
+
69
+ should 'support raw read_multi' do
70
+ with_activesupport do
71
+ memcached do
72
+ connect
73
+ @mc.write("abc", 5, :raw => true)
74
+ @mc.write("cba", 5, :raw => true)
75
+ if RAILS_VERSION =~ /2\.3/
76
+ assert_raise ArgumentError do
77
+ @mc.read_multi("abc", "cba")
78
+ end
79
+ else
80
+ assert_equal({'abc' => '5', 'cba' => '5' }, @mc.read_multi("abc", "cba"))
81
+ end
82
+
83
+ @dalli.write("abc", 5, :raw => true)
84
+ @dalli.write("cba", 5, :raw => true)
85
+ # XXX: API difference between m-c and dalli. Dalli is smarter about
86
+ # what it needs to unmarshal.
87
+ assert_equal({'abc' => '5', 'cba' => '5' }, @dalli.read_multi("abc", "cba"))
88
+ end
89
+ end
90
+ end
91
+
92
+ should 'support read, write and delete' do
93
+ with_activesupport do
94
+ memcached do
95
+ connect
96
+ x = rand_key
97
+ y = rand_key
98
+ assert_nil @mc.read(x)
99
+ assert_nil @dalli.read(y)
100
+ mres = @mc.write(x, 123)
101
+ dres = @dalli.write(y, 123)
102
+ assert_equal mres, dres
103
+
104
+ mres = @mc.read(x)
105
+ dres = @dalli.read(y)
106
+ assert_equal mres, dres
107
+ assert_equal 123, dres
108
+
109
+ mres = @mc.delete(x)
110
+ dres = @dalli.delete(y)
111
+ assert_equal mres, dres
112
+ assert_equal true, dres
113
+ end
114
+ end
115
+ end
116
+
117
+ should 'support increment/decrement commands' do
118
+ with_activesupport do
119
+ memcached do
120
+ connect
121
+ assert_equal true, @mc.write('counter', 0, :raw => true)
122
+ assert_equal 1, @mc.increment('counter')
123
+ assert_equal 2, @mc.increment('counter')
124
+ assert_equal 1, @mc.decrement('counter')
125
+ assert_equal "1", @mc.read('counter', :raw => true)
126
+
127
+ assert_equal true, @dalli.write('counter', 0, :raw => true)
128
+ assert_equal 1, @dalli.increment('counter')
129
+ assert_equal 2, @dalli.increment('counter')
130
+ assert_equal 1, @dalli.decrement('counter')
131
+ assert_equal "1", @dalli.read('counter', :raw => true)
132
+
133
+ assert_equal 0, @mc.increment('counterX')
134
+ assert_equal 0, @mc.increment('counterX')
135
+ assert_equal nil, @mc.read('counterX')
136
+
137
+ assert_equal 1, @dalli.increment('counterX')
138
+ assert_equal 2, @dalli.increment('counterX')
139
+ assert_equal 2, @dalli.read('counterX', :raw => true).to_i
140
+ end
141
+ end
142
+ end
143
+
144
+ should 'support other esoteric commands' do
145
+ with_activesupport do
146
+ memcached do
147
+ connect
148
+ ms = @mc.stats
149
+ ds = @dalli.stats
150
+ assert_equal ms.keys.sort, ds.keys.sort
151
+ assert_equal ms[ms.keys.first].keys.sort, ds[ds.keys.first].keys.sort
152
+
153
+ assert_equal true, @dalli.write(:foo, 'a')
154
+ assert_equal true, @mc.write(:foo, 'a')
155
+
156
+ assert_equal true, @mc.exist?(:foo)
157
+ assert_equal true, @dalli.exist?(:foo)
158
+
159
+ assert_equal false, @mc.exist?(:bar)
160
+ assert_equal false, @dalli.exist?(:bar)
161
+
162
+ @dalli.reset
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def connect
169
+ @dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => 'x')
170
+ @mc = ActiveSupport::Cache.lookup_store(:mem_cache_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => 'a')
171
+ @dalli.clear
172
+ end
173
+
174
+ def rand_key
175
+ rand(1_000_000_000)
176
+ end
177
+ end
@@ -0,0 +1,33 @@
1
+ require 'helper'
2
+
3
+ class TestCompatibility < Test::Unit::TestCase
4
+
5
+ def setup
6
+ require 'dalli/memcache-client'
7
+ end
8
+
9
+ context 'dalli in memcache-client mode' do
10
+
11
+ should 'handle old raw flag to set/add/replace' do
12
+ memcached do |dc|
13
+ assert_equal "STORED\r\n", dc.set('abc', 123, 5, true)
14
+ assert_equal '123', dc.get('abc', true)
15
+
16
+ assert_equal "NOT_STORED\r\n", dc.add('abc', 456, 5, true)
17
+ assert_equal '123', dc.get('abc', true)
18
+
19
+ assert_equal "STORED\r\n", dc.replace('abc', 456, 5, false)
20
+ assert_equal 456, dc.get('abc', false)
21
+
22
+ assert_equal "DELETED\r\n", dc.delete('abc')
23
+ assert_equal "NOT_DELETED\r\n", dc.delete('abc')
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ def teardown
30
+ Dalli::Client.compatibility_mode = false
31
+ end
32
+
33
+ end
@@ -0,0 +1,398 @@
1
+ require 'helper'
2
+ require 'memcached_mock'
3
+
4
+ class TestDalli < Test::Unit::TestCase
5
+
6
+ should "default to localhost:11211" do
7
+ dc = Dalli::Client.new
8
+ ring = dc.send(:ring)
9
+ s1 = ring.servers.first.hostname
10
+ assert_equal 1, ring.servers.size
11
+ dc.close
12
+
13
+ dc = Dalli::Client.new('localhost:11211')
14
+ ring = dc.send(:ring)
15
+ s2 = ring.servers.first.hostname
16
+ assert_equal 1, ring.servers.size
17
+ dc.close
18
+
19
+ dc = Dalli::Client.new(['localhost:11211'])
20
+ ring = dc.send(:ring)
21
+ s3 = ring.servers.first.hostname
22
+ assert_equal 1, ring.servers.size
23
+ dc.close
24
+
25
+ assert_equal s1, s2
26
+ assert_equal s2, s3
27
+ end
28
+
29
+ context 'using a live server' do
30
+
31
+ should "support get/set" do
32
+ memcached do |dc|
33
+ dc.flush
34
+
35
+ val1 = "1234567890"*105000
36
+ assert_error Dalli::DalliError, /too large/ do
37
+ dc.set('a', val1)
38
+ val2 = dc.get('a')
39
+ assert_equal val1, val2
40
+ end
41
+
42
+ val1 = "1234567890"*100000
43
+ dc.set('a', val1)
44
+ val2 = dc.get('a')
45
+ assert_equal val1, val2
46
+
47
+ assert_equal true, dc.set('a', nil)
48
+ assert_nil dc.get('a')
49
+ end
50
+ end
51
+
52
+ should "support the fetch operation" do
53
+ memcached do |dc|
54
+ dc.flush
55
+
56
+ expected = { 'blah' => 'blerg!' }
57
+ executed = false
58
+ value = dc.fetch('fetch_key') do
59
+ executed = true
60
+ expected
61
+ end
62
+ assert_equal expected, value
63
+ assert_equal true, executed
64
+
65
+ executed = false
66
+ value = dc.fetch('fetch_key') do
67
+ executed = true
68
+ expected
69
+ end
70
+ assert_equal expected, value
71
+ assert_equal false, executed
72
+ end
73
+ end
74
+
75
+ should "support the cas operation" do
76
+ memcached do |dc|
77
+ dc.flush
78
+
79
+ expected = { 'blah' => 'blerg!' }
80
+
81
+ resp = dc.cas('cas_key') do |value|
82
+ fail('Value should not exist')
83
+ end
84
+ assert_nil resp
85
+
86
+ mutated = { 'blah' => 'foo!' }
87
+ dc.set('cas_key', expected)
88
+ resp = dc.cas('cas_key') do |value|
89
+ assert_equal expected, value
90
+ mutated
91
+ end
92
+ assert_equal true, resp
93
+
94
+ resp = dc.get('cas_key')
95
+ assert_equal mutated, resp
96
+
97
+ # TODO Need to verify failure when value is mutated between get and add.
98
+ end
99
+ end
100
+
101
+ should "support multi-get" do
102
+ memcached do |dc|
103
+ dc.close
104
+ dc.flush
105
+ resp = dc.get_multi(%w(a b c d e f))
106
+ assert_equal({}, resp)
107
+
108
+ dc.set('a', 'foo')
109
+ dc.set('b', 123)
110
+ dc.set('c', %w(a b c))
111
+ resp = dc.get_multi(%w(a b c d e f))
112
+ assert_equal({ 'a' => 'foo', 'b' => 123, 'c' => %w(a b c) }, resp)
113
+
114
+ # Perform a huge multi-get with 10,000 elements.
115
+ arr = []
116
+ dc.multi do
117
+ 10_000.times do |idx|
118
+ dc.set idx, idx
119
+ arr << idx
120
+ end
121
+ end
122
+
123
+ result = dc.get_multi(arr)
124
+ assert_equal(10_000, result.size)
125
+ assert_equal(1000, result['1000'])
126
+ end
127
+ end
128
+
129
+ should 'support raw incr/decr' do
130
+ memcached do |client|
131
+ client.flush
132
+
133
+ assert_equal true, client.set('fakecounter', 0, 0, :raw => true)
134
+ assert_equal 1, client.incr('fakecounter', 1)
135
+ assert_equal 2, client.incr('fakecounter', 1)
136
+ assert_equal 3, client.incr('fakecounter', 1)
137
+ assert_equal 1, client.decr('fakecounter', 2)
138
+ assert_equal "1", client.get('fakecounter', :raw => true)
139
+
140
+ resp = client.incr('mycounter', 0)
141
+ assert_nil resp
142
+
143
+ resp = client.incr('mycounter', 1, 0, 2)
144
+ assert_equal 2, resp
145
+ resp = client.incr('mycounter', 1)
146
+ assert_equal 3, resp
147
+
148
+ resp = client.set('rawcounter', 10, 0, :raw => true)
149
+ assert_equal true, resp
150
+
151
+ resp = client.get('rawcounter', :raw => true)
152
+ assert_equal '10', resp
153
+
154
+ resp = client.incr('rawcounter', 1)
155
+ assert_equal 11, resp
156
+ end
157
+ end
158
+
159
+ should "support incr/decr operations" do
160
+ memcached do |dc|
161
+ dc.flush
162
+
163
+ resp = dc.decr('counter', 100, 5, 0)
164
+ assert_equal 0, resp
165
+
166
+ resp = dc.decr('counter', 10)
167
+ assert_equal 0, resp
168
+
169
+ resp = dc.incr('counter', 10)
170
+ assert_equal 10, resp
171
+
172
+ current = 10
173
+ 100.times do |x|
174
+ resp = dc.incr('counter', 10)
175
+ assert_equal current + ((x+1)*10), resp
176
+ end
177
+
178
+ resp = dc.decr('10billion', 0, 5, 10)
179
+ # go over the 32-bit mark to verify proper (un)packing
180
+ resp = dc.incr('10billion', 10_000_000_000)
181
+ assert_equal 10_000_000_010, resp
182
+
183
+ resp = dc.decr('10billion', 1)
184
+ assert_equal 10_000_000_009, resp
185
+
186
+ resp = dc.decr('10billion', 0)
187
+ assert_equal 10_000_000_009, resp
188
+
189
+ resp = dc.incr('10billion', 0)
190
+ assert_equal 10_000_000_009, resp
191
+
192
+ assert_nil dc.incr('DNE', 10)
193
+ assert_nil dc.decr('DNE', 10)
194
+
195
+ resp = dc.incr('big', 100, 5, 0xFFFFFFFFFFFFFFFE)
196
+ assert_equal 0xFFFFFFFFFFFFFFFE, resp
197
+ resp = dc.incr('big', 1)
198
+ assert_equal 0xFFFFFFFFFFFFFFFF, resp
199
+
200
+ # rollover the 64-bit value, we'll get something undefined.
201
+ resp = dc.incr('big', 1)
202
+ assert_not_equal 0x10000000000000000, resp
203
+ dc.reset
204
+ end
205
+ end
206
+
207
+ should 'support the append and prepend operations' do
208
+ memcached do |dc|
209
+ resp = dc.flush
210
+ assert_equal true, dc.set('456', 'xyz', 0, :raw => true)
211
+ assert_equal true, dc.prepend('456', '0')
212
+ assert_equal true, dc.append('456', '9')
213
+ assert_equal '0xyz9', dc.get('456', :raw => true)
214
+ assert_equal '0xyz9', dc.get('456')
215
+
216
+ assert_equal false, dc.append('nonexist', 'abc')
217
+ assert_equal false, dc.prepend('nonexist', 'abc')
218
+ end
219
+ end
220
+
221
+ should "pass a simple smoke test" do
222
+ memcached do |dc|
223
+ resp = dc.flush
224
+ assert_not_nil resp
225
+ assert_equal [true, true], resp
226
+
227
+ assert_equal true, dc.set(:foo, 'bar')
228
+ assert_equal 'bar', dc.get(:foo)
229
+
230
+ resp = dc.get('123')
231
+ assert_equal nil, resp
232
+
233
+ resp = dc.set('123', 'xyz')
234
+ assert_equal true, resp
235
+
236
+ resp = dc.get('123')
237
+ assert_equal 'xyz', resp
238
+
239
+ resp = dc.set('123', 'abc')
240
+ assert_equal true, resp
241
+
242
+ dc.prepend('123', '0')
243
+ dc.append('123', '0')
244
+
245
+ assert_raises Dalli::DalliError do
246
+ resp = dc.get('123')
247
+ end
248
+
249
+ dc.close
250
+ dc = nil
251
+
252
+ dc = Dalli::Client.new('localhost:19122')
253
+
254
+ resp = dc.set('456', 'xyz', 0, :raw => true)
255
+ assert_equal true, resp
256
+
257
+ resp = dc.prepend '456', '0'
258
+ assert_equal true, resp
259
+
260
+ resp = dc.append '456', '9'
261
+ assert_equal true, resp
262
+
263
+ resp = dc.get('456', :raw => true)
264
+ assert_equal '0xyz9', resp
265
+
266
+ resp = dc.stats
267
+ assert_equal Hash, resp.class
268
+
269
+ dc.close
270
+ end
271
+ end
272
+
273
+ should "support multithreaded access" do
274
+ memcached do |cache|
275
+ cache.flush
276
+ workers = []
277
+
278
+ cache.set('f', 'zzz')
279
+ assert_equal true, (cache.cas('f') do |value|
280
+ value << 'z'
281
+ end)
282
+ assert_equal 'zzzz', cache.get('f')
283
+
284
+ # Have a bunch of threads perform a bunch of operations at the same time.
285
+ # Verify the result of each operation to ensure the request and response
286
+ # are not intermingled between threads.
287
+ 10.times do
288
+ workers << Thread.new do
289
+ 100.times do
290
+ cache.set('a', 9)
291
+ cache.set('b', 11)
292
+ inc = cache.incr('cat', 10, 0, 10)
293
+ cache.set('f', 'zzz')
294
+ assert_not_nil(cache.cas('f') do |value|
295
+ value << 'z'
296
+ end)
297
+ assert_equal false, cache.add('a', 11)
298
+ assert_equal({ 'a' => 9, 'b' => 11 }, cache.get_multi(['a', 'b']))
299
+ inc = cache.incr('cat', 10)
300
+ assert_equal 0, inc % 5
301
+ dec = cache.decr('cat', 5)
302
+ assert_equal 11, cache.get('b')
303
+ end
304
+ end
305
+ end
306
+
307
+ workers.each { |w| w.join }
308
+ cache.flush
309
+ end
310
+ end
311
+
312
+ should "handle namespaced keys" do
313
+ memcached do |dc|
314
+ dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
315
+ dc.set('namespaced', 1)
316
+ dc2 = Dalli::Client.new('localhost:19122', :namespace => 'b')
317
+ dc2.set('namespaced', 2)
318
+ assert_equal 1, dc.get('namespaced')
319
+ assert_equal 2, dc2.get('namespaced')
320
+ end
321
+ end
322
+
323
+ should "handle namespaced keys in multi_get" do
324
+ memcached do |dc|
325
+ dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
326
+ dc.set('a', 1)
327
+ dc.set('b', 2)
328
+ assert_equal({'a' => 1, 'b' => 2}, dc.get_multi('a', 'b'))
329
+ end
330
+ end
331
+
332
+ should "handle application marshalling issues" do
333
+ memcached do |dc|
334
+ old = Dalli.logger
335
+ Dalli.logger = Logger.new(nil)
336
+ begin
337
+ assert_equal false, dc.set('a', Proc.new { true })
338
+ ensure
339
+ Dalli.logger = old
340
+ end
341
+ end
342
+ end
343
+
344
+ context 'with compression' do
345
+ should 'allow large values' do
346
+ memcached do |dc|
347
+ dalli = Dalli::Client.new(dc.instance_variable_get(:@servers), :compression => true)
348
+
349
+ value = "0"*1024*1024
350
+ assert_raise Dalli::DalliError, /too large/ do
351
+ dc.set('verylarge', value)
352
+ end
353
+ dalli.set('verylarge', value)
354
+ end
355
+ end
356
+ end
357
+
358
+ context 'in low memory conditions' do
359
+
360
+ should 'handle error response correctly' do
361
+ memcached(19125, '-m 1 -M') do |dc|
362
+ failed = false
363
+ value = "1234567890"*100
364
+ 1_000.times do |idx|
365
+ begin
366
+ assert_equal true, dc.set(idx, value)
367
+ rescue Dalli::DalliError
368
+ failed = true
369
+ assert((800..900).include?(idx), "unexpected failure on iteration #{idx}")
370
+ break
371
+ end
372
+ end
373
+ assert failed, 'did not fail under low memory conditions'
374
+ end
375
+ end
376
+
377
+ should 'fit more values with compression' do
378
+ memcached(19126, '-m 1 -M') do |dc|
379
+ dalli = Dalli::Client.new('localhost:19126', :compression => true)
380
+ failed = false
381
+ value = "1234567890"*1000
382
+ 10_000.times do |idx|
383
+ begin
384
+ assert_equal true, dalli.set(idx, value)
385
+ rescue Dalli::DalliError
386
+ failed = true
387
+ assert((6000..7000).include?(idx), "unexpected failure on iteration #{idx}")
388
+ break
389
+ end
390
+ end
391
+ assert failed, 'did not fail under low memory conditions'
392
+ end
393
+ end
394
+
395
+ end
396
+
397
+ end
398
+ end