mob-dalli 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,450 @@
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 unix sockets' do
30
+ should 'pass smoke test' do
31
+ memcached(nil,'',{:unix => true}) do |dc|
32
+ # get/set
33
+ dc.flush
34
+ assert_nil dc.get(:a)
35
+ assert dc.set(:a,1)
36
+ assert_equal 1, dc.get(:a)
37
+
38
+ # replace
39
+ dc.set(:a,1)
40
+ dc.replace(:a,2)
41
+ assert_equal 2, dc.get(:a)
42
+
43
+ # delete
44
+ dc.delete(:a)
45
+ assert_nil dc.get(:a)
46
+
47
+ # fetch
48
+ executed, expected = false, 1
49
+
50
+ value = dc.fetch(:fetched) do
51
+ executed = true
52
+ expected
53
+ end
54
+
55
+ assert executed
56
+ assert_equal expected, value
57
+
58
+ executed = false
59
+ value = dc.fetch(:fetched) do
60
+ executed = true
61
+ expected
62
+ end
63
+
64
+ assert !executed
65
+ assert_equal expected, value
66
+
67
+ # cas
68
+ dc.set(:a,1)
69
+ 3.times { dc.cas(:a){|a| a+=1} }
70
+ assert_equal 4, dc.get(:a)
71
+
72
+ # get_multi
73
+ resp = dc.get_multi(%w(b c d))
74
+ assert_equal({}, resp)
75
+ dc.set("b",1)
76
+ dc.set("c",11)
77
+ resp = dc.get_multi(%w(b c d))
78
+ assert_equal({"b" => 1, "c" => 11}, resp)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'using a live server' do
84
+
85
+ should "support get/set" do
86
+ memcached do |dc|
87
+ dc.flush
88
+
89
+ val1 = "1234567890"*105000
90
+ assert_error Dalli::DalliError, /too large/ do
91
+ dc.set('a', val1)
92
+ val2 = dc.get('a')
93
+ assert_equal val1, val2
94
+ end
95
+
96
+ val1 = "1234567890"*100000
97
+ dc.set('a', val1)
98
+ val2 = dc.get('a')
99
+ assert_equal val1, val2
100
+
101
+ assert_equal true, dc.set('a', nil)
102
+ assert_nil dc.get('a')
103
+ end
104
+ end
105
+
106
+ should "support the fetch operation" do
107
+ memcached do |dc|
108
+ dc.flush
109
+
110
+ expected = { 'blah' => 'blerg!' }
111
+ executed = false
112
+ value = dc.fetch('fetch_key') do
113
+ executed = true
114
+ expected
115
+ end
116
+ assert_equal expected, value
117
+ assert_equal true, executed
118
+
119
+ executed = false
120
+ value = dc.fetch('fetch_key') do
121
+ executed = true
122
+ expected
123
+ end
124
+ assert_equal expected, value
125
+ assert_equal false, executed
126
+ end
127
+ end
128
+
129
+ should "support the cas operation" do
130
+ memcached do |dc|
131
+ dc.flush
132
+
133
+ expected = { 'blah' => 'blerg!' }
134
+
135
+ resp = dc.cas('cas_key') do |value|
136
+ fail('Value should not exist')
137
+ end
138
+ assert_nil resp
139
+
140
+ mutated = { 'blah' => 'foo!' }
141
+ dc.set('cas_key', expected)
142
+ resp = dc.cas('cas_key') do |value|
143
+ assert_equal expected, value
144
+ mutated
145
+ end
146
+ assert_equal true, resp
147
+
148
+ resp = dc.get('cas_key')
149
+ assert_equal mutated, resp
150
+ end
151
+ end
152
+
153
+ should "support multi-get" do
154
+ memcached do |dc|
155
+ dc.close
156
+ dc.flush
157
+ resp = dc.get_multi(%w(a b c d e f))
158
+ assert_equal({}, resp)
159
+
160
+ dc.set('a', 'foo')
161
+ dc.set('b', 123)
162
+ dc.set('c', %w(a b c))
163
+ resp = dc.get_multi(%w(a b c d e f))
164
+ assert_equal({ 'a' => 'foo', 'b' => 123, 'c' => %w(a b c) }, resp)
165
+
166
+ # Perform a huge multi-get with 10,000 elements.
167
+ arr = []
168
+ dc.multi do
169
+ 10_000.times do |idx|
170
+ dc.set idx, idx
171
+ arr << idx
172
+ end
173
+ end
174
+
175
+ result = dc.get_multi(arr)
176
+ assert_equal(10_000, result.size)
177
+ assert_equal(1000, result['1000'])
178
+ end
179
+ end
180
+
181
+ should 'support raw incr/decr' do
182
+ memcached do |client|
183
+ client.flush
184
+
185
+ assert_equal true, client.set('fakecounter', 0, 0, :raw => true)
186
+ assert_equal 1, client.incr('fakecounter', 1)
187
+ assert_equal 2, client.incr('fakecounter', 1)
188
+ assert_equal 3, client.incr('fakecounter', 1)
189
+ assert_equal 1, client.decr('fakecounter', 2)
190
+ assert_equal "1", client.get('fakecounter', :raw => true)
191
+
192
+ resp = client.incr('mycounter', 0)
193
+ assert_nil resp
194
+
195
+ resp = client.incr('mycounter', 1, 0, 2)
196
+ assert_equal 2, resp
197
+ resp = client.incr('mycounter', 1)
198
+ assert_equal 3, resp
199
+
200
+ resp = client.set('rawcounter', 10, 0, :raw => true)
201
+ assert_equal true, resp
202
+
203
+ resp = client.get('rawcounter', :raw => true)
204
+ assert_equal '10', resp
205
+
206
+ resp = client.incr('rawcounter', 1)
207
+ assert_equal 11, resp
208
+ end
209
+ end
210
+
211
+ should "support incr/decr operations" do
212
+ memcached do |dc|
213
+ dc.flush
214
+
215
+ resp = dc.decr('counter', 100, 5, 0)
216
+ assert_equal 0, resp
217
+
218
+ resp = dc.decr('counter', 10)
219
+ assert_equal 0, resp
220
+
221
+ resp = dc.incr('counter', 10)
222
+ assert_equal 10, resp
223
+
224
+ current = 10
225
+ 100.times do |x|
226
+ resp = dc.incr('counter', 10)
227
+ assert_equal current + ((x+1)*10), resp
228
+ end
229
+
230
+ resp = dc.decr('10billion', 0, 5, 10)
231
+ # go over the 32-bit mark to verify proper (un)packing
232
+ resp = dc.incr('10billion', 10_000_000_000)
233
+ assert_equal 10_000_000_010, resp
234
+
235
+ resp = dc.decr('10billion', 1)
236
+ assert_equal 10_000_000_009, resp
237
+
238
+ resp = dc.decr('10billion', 0)
239
+ assert_equal 10_000_000_009, resp
240
+
241
+ resp = dc.incr('10billion', 0)
242
+ assert_equal 10_000_000_009, resp
243
+
244
+ assert_nil dc.incr('DNE', 10)
245
+ assert_nil dc.decr('DNE', 10)
246
+
247
+ resp = dc.incr('big', 100, 5, 0xFFFFFFFFFFFFFFFE)
248
+ assert_equal 0xFFFFFFFFFFFFFFFE, resp
249
+ resp = dc.incr('big', 1)
250
+ assert_equal 0xFFFFFFFFFFFFFFFF, resp
251
+
252
+ # rollover the 64-bit value, we'll get something undefined.
253
+ resp = dc.incr('big', 1)
254
+ assert_not_equal 0x10000000000000000, resp
255
+ dc.reset
256
+ end
257
+ end
258
+
259
+ should 'support the append and prepend operations' do
260
+ memcached do |dc|
261
+ resp = dc.flush
262
+ assert_equal true, dc.set('456', 'xyz', 0, :raw => true)
263
+ assert_equal true, dc.prepend('456', '0')
264
+ assert_equal true, dc.append('456', '9')
265
+ assert_equal '0xyz9', dc.get('456', :raw => true)
266
+ assert_equal '0xyz9', dc.get('456')
267
+
268
+ assert_equal false, dc.append('nonexist', 'abc')
269
+ assert_equal false, dc.prepend('nonexist', 'abc')
270
+ end
271
+ end
272
+
273
+ should "pass a simple smoke test" do
274
+ memcached do |dc|
275
+ resp = dc.flush
276
+ assert_not_nil resp
277
+ assert_equal [true, true], resp
278
+
279
+ assert_equal true, dc.set(:foo, 'bar')
280
+ assert_equal 'bar', dc.get(:foo)
281
+
282
+ resp = dc.get('123')
283
+ assert_equal nil, resp
284
+
285
+ resp = dc.set('123', 'xyz')
286
+ assert_equal true, resp
287
+
288
+ resp = dc.get('123')
289
+ assert_equal 'xyz', resp
290
+
291
+ resp = dc.set('123', 'abc')
292
+ assert_equal true, resp
293
+
294
+ dc.prepend('123', '0')
295
+ dc.append('123', '0')
296
+
297
+ assert_raises Dalli::DalliError do
298
+ resp = dc.get('123')
299
+ end
300
+
301
+ dc.close
302
+ dc = nil
303
+
304
+ dc = Dalli::Client.new('localhost:19122')
305
+
306
+ resp = dc.set('456', 'xyz', 0, :raw => true)
307
+ assert_equal true, resp
308
+
309
+ resp = dc.prepend '456', '0'
310
+ assert_equal true, resp
311
+
312
+ resp = dc.append '456', '9'
313
+ assert_equal true, resp
314
+
315
+ resp = dc.get('456', :raw => true)
316
+ assert_equal '0xyz9', resp
317
+
318
+ resp = dc.stats
319
+ assert_equal Hash, resp.class
320
+
321
+ dc.close
322
+ end
323
+ end
324
+
325
+ should "support multithreaded access" do
326
+ memcached do |cache|
327
+ cache.flush
328
+ workers = []
329
+
330
+ cache.set('f', 'zzz')
331
+ assert_equal true, (cache.cas('f') do |value|
332
+ value << 'z'
333
+ end)
334
+ assert_equal 'zzzz', cache.get('f')
335
+
336
+ # Have a bunch of threads perform a bunch of operations at the same time.
337
+ # Verify the result of each operation to ensure the request and response
338
+ # are not intermingled between threads.
339
+ 10.times do
340
+ workers << Thread.new do
341
+ 100.times do
342
+ cache.set('a', 9)
343
+ cache.set('b', 11)
344
+ inc = cache.incr('cat', 10, 0, 10)
345
+ cache.set('f', 'zzz')
346
+ assert_not_nil(cache.cas('f') do |value|
347
+ value << 'z'
348
+ end)
349
+ assert_equal false, cache.add('a', 11)
350
+ assert_equal({ 'a' => 9, 'b' => 11 }, cache.get_multi(['a', 'b']))
351
+ inc = cache.incr('cat', 10)
352
+ assert_equal 0, inc % 5
353
+ dec = cache.decr('cat', 5)
354
+ assert_equal 11, cache.get('b')
355
+ end
356
+ end
357
+ end
358
+
359
+ workers.each { |w| w.join }
360
+ cache.flush
361
+ end
362
+ end
363
+
364
+ should "handle namespaced keys" do
365
+ memcached do |dc|
366
+ dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
367
+ dc.set('namespaced', 1)
368
+ dc2 = Dalli::Client.new('localhost:19122', :namespace => 'b')
369
+ dc2.set('namespaced', 2)
370
+ assert_equal 1, dc.get('namespaced')
371
+ assert_equal 2, dc2.get('namespaced')
372
+ end
373
+ end
374
+
375
+ should "handle namespaced keys in multi_get" do
376
+ memcached do |dc|
377
+ dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
378
+ dc.set('a', 1)
379
+ dc.set('b', 2)
380
+ assert_equal({'a' => 1, 'b' => 2}, dc.get_multi('a', 'b'))
381
+ end
382
+ end
383
+
384
+ should "handle application marshalling issues" do
385
+ memcached do |dc|
386
+ old = Dalli.logger
387
+ Dalli.logger = Logger.new(nil)
388
+ begin
389
+ assert_equal false, dc.set('a', Proc.new { true })
390
+ ensure
391
+ Dalli.logger = old
392
+ end
393
+ end
394
+ end
395
+
396
+ context 'with compression' do
397
+ should 'allow large values' do
398
+ memcached do |dc|
399
+ dalli = Dalli::Client.new(dc.instance_variable_get(:@servers), :compression => true)
400
+
401
+ value = "0"*1024*1024
402
+ assert_raise Dalli::DalliError, /too large/ do
403
+ dc.set('verylarge', value)
404
+ end
405
+ dalli.set('verylarge', value)
406
+ end
407
+ end
408
+ end
409
+
410
+ context 'in low memory conditions' do
411
+
412
+ should 'handle error response correctly' do
413
+ memcached(19125, '-m 1 -M') do |dc|
414
+ failed = false
415
+ value = "1234567890"*100
416
+ 1_000.times do |idx|
417
+ begin
418
+ assert_equal true, dc.set(idx, value)
419
+ rescue Dalli::DalliError
420
+ failed = true
421
+ assert((800..960).include?(idx), "unexpected failure on iteration #{idx}")
422
+ break
423
+ end
424
+ end
425
+ assert failed, 'did not fail under low memory conditions'
426
+ end
427
+ end
428
+
429
+ should 'fit more values with compression' do
430
+ memcached(19126, '-m 1 -M') do |dc|
431
+ dalli = Dalli::Client.new('localhost:19126', :compression => true)
432
+ failed = false
433
+ value = "1234567890"*1000
434
+ 10_000.times do |idx|
435
+ begin
436
+ assert_equal true, dalli.set(idx, value)
437
+ rescue Dalli::DalliError
438
+ failed = true
439
+ assert((6000..7800).include?(idx), "unexpected failure on iteration #{idx}")
440
+ break
441
+ end
442
+ end
443
+ assert failed, 'did not fail under low memory conditions'
444
+ end
445
+ end
446
+
447
+ end
448
+
449
+ end
450
+ end