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.

data/test/test_dalli.rb DELETED
@@ -1,625 +0,0 @@
1
- require 'helper'
2
- require 'memcached_mock'
3
-
4
- describe 'Dalli' do
5
- describe 'options parsing' do
6
- it 'handle deprecated options' do
7
- dc = Dalli::Client.new('foo', :compression => true)
8
- assert dc.instance_variable_get(:@options)[:compress]
9
- refute dc.instance_variable_get(:@options)[:compression]
10
- end
11
-
12
- it 'not warn about valid options' do
13
- dc = Dalli::Client.new('foo', :compress => true)
14
- # Rails.logger.expects :warn
15
- assert dc.instance_variable_get(:@options)[:compress]
16
- end
17
-
18
- it 'raises error with invalid expires_in' do
19
- bad_data = [{:bad => 'expires in data'}, Hash, [1,2,3]]
20
- bad_data.each do |bad|
21
- assert_raises ArgumentError do
22
- Dalli::Client.new('foo', {:expires_in => bad})
23
- end
24
- end
25
- end
26
-
27
- it 'return string type for namespace attribute' do
28
- dc = Dalli::Client.new('foo', :namespace => :wunderschoen)
29
- assert_equal "wunderschoen", dc.send(:namespace)
30
- dc.close
31
-
32
- dc = Dalli::Client.new('foo', :namespace => Proc.new{:wunderschoen})
33
- assert_equal "wunderschoen", dc.send(:namespace)
34
- dc.close
35
- end
36
- end
37
-
38
- describe 'key validation' do
39
- it 'not allow blanks' do
40
- memcached do |dc|
41
- dc.set ' ', 1
42
- assert_equal 1, dc.get(' ')
43
- dc.set "\t", 1
44
- assert_equal 1, dc.get("\t")
45
- dc.set "\n", 1
46
- assert_equal 1, dc.get("\n")
47
- assert_raises ArgumentError do
48
- dc.set "", 1
49
- end
50
- assert_raises ArgumentError do
51
- dc.set nil, 1
52
- end
53
- end
54
- end
55
-
56
- it 'allow namespace to be a symbol' do
57
- memcached(19122, '', :namespace => :wunderschoen) do |dc|
58
- dc.set "x" * 251, 1
59
- assert 1, dc.get("#{'x' * 200}:md5:#{Digest::MD5.hexdigest('x' * 251)}")
60
- end
61
- end
62
- end
63
-
64
- it "default to localhost:11211" do
65
- dc = Dalli::Client.new
66
- ring = dc.send(:ring)
67
- s1 = ring.servers.first.hostname
68
- assert_equal 1, ring.servers.size
69
- dc.close
70
-
71
- dc = Dalli::Client.new('localhost:11211')
72
- ring = dc.send(:ring)
73
- s2 = ring.servers.first.hostname
74
- assert_equal 1, ring.servers.size
75
- dc.close
76
-
77
- dc = Dalli::Client.new(['localhost:11211'])
78
- ring = dc.send(:ring)
79
- s3 = ring.servers.first.hostname
80
- assert_equal 1, ring.servers.size
81
- dc.close
82
-
83
- assert_equal '127.0.0.1', s1
84
- assert_equal s2, s3
85
- end
86
-
87
- it "accept comma separated string" do
88
- dc = Dalli::Client.new("server1.example.com:11211,server2.example.com:11211")
89
- ring = dc.send(:ring)
90
- assert_equal 2, ring.servers.size
91
- s1,s2 = ring.servers.map(&:hostname)
92
- assert_equal "server1.example.com", s1
93
- assert_equal "server2.example.com", s2
94
- end
95
-
96
- it "accept array of servers" do
97
- dc = Dalli::Client.new(["server1.example.com:11211","server2.example.com:11211"])
98
- ring = dc.send(:ring)
99
- assert_equal 2, ring.servers.size
100
- s1,s2 = ring.servers.map(&:hostname)
101
- assert_equal "server1.example.com", s1
102
- assert_equal "server2.example.com", s2
103
- end
104
-
105
- describe 'using a live server' do
106
-
107
- it "support get/set" do
108
- memcached do |dc|
109
- dc.flush
110
-
111
- val1 = "1234567890"*105000
112
- assert_equal false, dc.set('a', val1)
113
-
114
- val1 = "1234567890"*100000
115
- dc.set('a', val1)
116
- val2 = dc.get('a')
117
- assert_equal val1, val2
118
-
119
- assert op_addset_succeeds(dc.set('a', nil))
120
- assert_nil dc.get('a')
121
- end
122
- end
123
-
124
- it 'supports delete' do
125
- memcached do |dc|
126
- dc.set('some_key', 'some_value')
127
- assert_equal 'some_value', dc.get('some_key')
128
-
129
- dc.delete('some_key')
130
- assert_nil dc.get('some_key')
131
- end
132
- end
133
-
134
- it 'returns nil for nonexist key' do
135
- memcached do |dc|
136
- assert_equal nil, dc.get('notexist')
137
- end
138
- end
139
-
140
- it 'allows "Not found" as value' do
141
- memcached do |dc|
142
- dc.set('key1', 'Not found')
143
- assert_equal 'Not found', dc.get('key1')
144
- end
145
- end
146
-
147
- it "support stats" do
148
- memcached do |dc|
149
- # make sure that get_hits would not equal 0
150
- dc.get(:a)
151
-
152
- stats = dc.stats
153
- servers = stats.keys
154
- assert(servers.any? do |s|
155
- stats[s]["get_hits"].to_i != 0
156
- end, "general stats failed")
157
-
158
- stats_items = dc.stats(:items)
159
- servers = stats_items.keys
160
- assert(servers.all? do |s|
161
- stats_items[s].keys.any? do |key|
162
- key =~ /items:[0-9]+:number/
163
- end
164
- end, "stats items failed")
165
-
166
- stats_slabs = dc.stats(:slabs)
167
- servers = stats_slabs.keys
168
- assert(servers.all? do |s|
169
- stats_slabs[s].keys.any? do |key|
170
- key == "active_slabs"
171
- end
172
- end, "stats slabs failed")
173
-
174
- # reset_stats test
175
- results = dc.reset_stats
176
- assert(results.all? { |x| x })
177
- stats = dc.stats
178
- servers = stats.keys
179
-
180
- # check if reset was performed
181
- servers.each do |s|
182
- assert_equal 0, dc.stats[s]["get_hits"].to_i
183
- end
184
- end
185
- end
186
-
187
- it "support the fetch operation" do
188
- memcached do |dc|
189
- dc.flush
190
-
191
- expected = { 'blah' => 'blerg!' }
192
- executed = false
193
- value = dc.fetch('fetch_key') do
194
- executed = true
195
- expected
196
- end
197
- assert_equal expected, value
198
- assert_equal true, executed
199
-
200
- executed = false
201
- value = dc.fetch('fetch_key') do
202
- executed = true
203
- expected
204
- end
205
- assert_equal expected, value
206
- assert_equal false, executed
207
- end
208
- end
209
-
210
- it "support the fetch operation with falsey values" do
211
- memcached do |dc|
212
- dc.flush
213
-
214
- dc.set("fetch_key", false)
215
- res = dc.fetch("fetch_key") { flunk "fetch block called" }
216
- assert_equal false, res
217
-
218
- dc.set("fetch_key", nil)
219
- res = dc.fetch("fetch_key") { "bob" }
220
- assert_equal 'bob', res
221
- end
222
- end
223
-
224
- it "support the cas operation" do
225
- memcached do |dc|
226
- dc.flush
227
-
228
- expected = { 'blah' => 'blerg!' }
229
-
230
- resp = dc.cas('cas_key') do |value|
231
- fail('Value it not exist')
232
- end
233
- assert_nil resp
234
-
235
- mutated = { 'blah' => 'foo!' }
236
- dc.set('cas_key', expected)
237
- resp = dc.cas('cas_key') do |value|
238
- assert_equal expected, value
239
- mutated
240
- end
241
- assert op_cas_succeeds(resp)
242
-
243
- resp = dc.get('cas_key')
244
- assert_equal mutated, resp
245
- end
246
- end
247
-
248
- it "support multi-get" do
249
- memcached do |dc|
250
- dc.close
251
- dc.flush
252
- resp = dc.get_multi(%w(a b c d e f))
253
- assert_equal({}, resp)
254
-
255
- dc.set('a', 'foo')
256
- dc.set('b', 123)
257
- dc.set('c', %w(a b c))
258
- # Invocation without block
259
- resp = dc.get_multi(%w(a b c d e f))
260
- expected_resp = { 'a' => 'foo', 'b' => 123, 'c' => %w(a b c) }
261
- assert_equal(expected_resp, resp)
262
-
263
- # Invocation with block
264
- dc.get_multi(%w(a b c d e f)) do |k, v|
265
- assert(expected_resp.has_key?(k) && expected_resp[k] == v)
266
- expected_resp.delete(k)
267
- end
268
- assert expected_resp.empty?
269
-
270
- # Perform a big multi-get with 1000 elements.
271
- arr = []
272
- dc.multi do
273
- 1000.times do |idx|
274
- dc.set idx, idx
275
- arr << idx
276
- end
277
- end
278
-
279
- result = dc.get_multi(arr)
280
- assert_equal(1000, result.size)
281
- assert_equal(50, result['50'])
282
- end
283
- end
284
-
285
- it 'support raw incr/decr' do
286
- memcached do |client|
287
- client.flush
288
-
289
- assert op_addset_succeeds(client.set('fakecounter', 0, 0, :raw => true))
290
- assert_equal 1, client.incr('fakecounter', 1)
291
- assert_equal 2, client.incr('fakecounter', 1)
292
- assert_equal 3, client.incr('fakecounter', 1)
293
- assert_equal 1, client.decr('fakecounter', 2)
294
- assert_equal "1", client.get('fakecounter', :raw => true)
295
-
296
- resp = client.incr('mycounter', 0)
297
- assert_nil resp
298
-
299
- resp = client.incr('mycounter', 1, 0, 2)
300
- assert_equal 2, resp
301
- resp = client.incr('mycounter', 1)
302
- assert_equal 3, resp
303
-
304
- resp = client.set('rawcounter', 10, 0, :raw => true)
305
- assert op_cas_succeeds(resp)
306
-
307
- resp = client.get('rawcounter', :raw => true)
308
- assert_equal '10', resp
309
-
310
- resp = client.incr('rawcounter', 1)
311
- assert_equal 11, resp
312
- end
313
- end
314
-
315
- it "support incr/decr operations" do
316
- memcached do |dc|
317
- dc.flush
318
-
319
- resp = dc.decr('counter', 100, 5, 0)
320
- assert_equal 0, resp
321
-
322
- resp = dc.decr('counter', 10)
323
- assert_equal 0, resp
324
-
325
- resp = dc.incr('counter', 10)
326
- assert_equal 10, resp
327
-
328
- current = 10
329
- 100.times do |x|
330
- resp = dc.incr('counter', 10)
331
- assert_equal current + ((x+1)*10), resp
332
- end
333
-
334
- resp = dc.decr('10billion', 0, 5, 10)
335
- # go over the 32-bit mark to verify proper (un)packing
336
- resp = dc.incr('10billion', 10_000_000_000)
337
- assert_equal 10_000_000_010, resp
338
-
339
- resp = dc.decr('10billion', 1)
340
- assert_equal 10_000_000_009, resp
341
-
342
- resp = dc.decr('10billion', 0)
343
- assert_equal 10_000_000_009, resp
344
-
345
- resp = dc.incr('10billion', 0)
346
- assert_equal 10_000_000_009, resp
347
-
348
- assert_nil dc.incr('DNE', 10)
349
- assert_nil dc.decr('DNE', 10)
350
-
351
- resp = dc.incr('big', 100, 5, 0xFFFFFFFFFFFFFFFE)
352
- assert_equal 0xFFFFFFFFFFFFFFFE, resp
353
- resp = dc.incr('big', 1)
354
- assert_equal 0xFFFFFFFFFFFFFFFF, resp
355
-
356
- # rollover the 64-bit value, we'll get something undefined.
357
- resp = dc.incr('big', 1)
358
- refute_equal 0x10000000000000000, resp
359
- dc.reset
360
- end
361
- end
362
-
363
- it 'support the append and prepend operations' do
364
- memcached do |dc|
365
- dc.flush
366
- assert op_addset_succeeds(dc.set('456', 'xyz', 0, :raw => true))
367
- assert_equal true, dc.prepend('456', '0')
368
- assert_equal true, dc.append('456', '9')
369
- assert_equal '0xyz9', dc.get('456', :raw => true)
370
- assert_equal '0xyz9', dc.get('456')
371
-
372
- assert_equal false, dc.append('nonexist', 'abc')
373
- assert_equal false, dc.prepend('nonexist', 'abc')
374
- end
375
- end
376
-
377
- it 'supports replace operation' do
378
- memcached do |dc|
379
- dc.flush
380
- dc.set('key', 'value')
381
- assert op_replace_succeeds(dc.replace('key', 'value2'))
382
-
383
- assert_equal 'value2', dc.get('key')
384
- end
385
- end
386
-
387
- it 'support touch operation' do
388
- memcached do |dc|
389
- begin
390
- dc.flush
391
- dc.set 'key', 'value'
392
- assert_equal true, dc.touch('key', 10)
393
- assert_equal true, dc.touch('key')
394
- assert_equal 'value', dc.get('key')
395
- assert_nil dc.touch('notexist')
396
- rescue Dalli::DalliError => e
397
- # This will happen when memcached is in lesser version than 1.4.8
398
- assert_equal 'Response error 129: Unknown command', e.message
399
- end
400
- end
401
- end
402
-
403
- it 'support version operation' do
404
- memcached do |dc|
405
- v = dc.version
406
- servers = v.keys
407
- assert(servers.any? do |s|
408
- v[s] != nil
409
- end, "version failed")
410
- end
411
- end
412
-
413
- it 'allow TCP connections to be configured for keepalive' do
414
- memcached(19122, '', :keepalive => true) do |dc|
415
- dc.set(:a, 1)
416
- ring = dc.send(:ring)
417
- server = ring.servers.first
418
- socket = server.instance_variable_get('@sock')
419
-
420
- optval = socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE)
421
- optval = optval.unpack 'i'
422
-
423
- assert_equal true, (optval[0] != 0)
424
- end
425
- end
426
-
427
- it "pass a simple smoke test" do
428
- memcached do |dc|
429
- resp = dc.flush
430
- refute_nil resp
431
- assert_equal [true, true], resp
432
-
433
- assert op_addset_succeeds(dc.set(:foo, 'bar'))
434
- assert_equal 'bar', dc.get(:foo)
435
-
436
- resp = dc.get('123')
437
- assert_equal nil, resp
438
-
439
- assert op_addset_succeeds(dc.set('123', 'xyz'))
440
-
441
- resp = dc.get('123')
442
- assert_equal 'xyz', resp
443
-
444
- assert op_addset_succeeds(dc.set('123', 'abc'))
445
-
446
- dc.prepend('123', '0')
447
- dc.append('123', '0')
448
-
449
- assert_raises Dalli::UnmarshalError do
450
- resp = dc.get('123')
451
- end
452
-
453
- dc.close
454
- dc = nil
455
-
456
- dc = Dalli::Client.new('localhost:19122')
457
-
458
- assert op_addset_succeeds(dc.set('456', 'xyz', 0, :raw => true))
459
-
460
- resp = dc.prepend '456', '0'
461
- assert_equal true, resp
462
-
463
- resp = dc.append '456', '9'
464
- assert_equal true, resp
465
-
466
- resp = dc.get('456', :raw => true)
467
- assert_equal '0xyz9', resp
468
-
469
- assert op_addset_succeeds(dc.set('456', false))
470
-
471
- resp = dc.get('456')
472
- assert_equal false, resp
473
-
474
- resp = dc.stats
475
- assert_equal Hash, resp.class
476
-
477
- dc.close
478
- end
479
- end
480
-
481
- it "support multithreaded access" do
482
- memcached do |cache|
483
- cache.flush
484
- workers = []
485
-
486
- cache.set('f', 'zzz')
487
- assert op_cas_succeeds((cache.cas('f') do |value|
488
- value << 'z'
489
- end))
490
- assert_equal 'zzzz', cache.get('f')
491
-
492
- # Have a bunch of threads perform a bunch of operations at the same time.
493
- # Verify the result of each operation to ensure the request and response
494
- # are not intermingled between threads.
495
- 10.times do
496
- workers << Thread.new do
497
- 100.times do
498
- cache.set('a', 9)
499
- cache.set('b', 11)
500
- inc = cache.incr('cat', 10, 0, 10)
501
- cache.set('f', 'zzz')
502
- res = cache.cas('f') do |value|
503
- value << 'z'
504
- end
505
- refute_nil res
506
- assert_equal false, cache.add('a', 11)
507
- assert_equal({ 'a' => 9, 'b' => 11 }, cache.get_multi(['a', 'b']))
508
- inc = cache.incr('cat', 10)
509
- assert_equal 0, inc % 5
510
- cache.decr('cat', 5)
511
- assert_equal 11, cache.get('b')
512
-
513
- assert_equal %w(a b), cache.get_multi('a', 'b', 'c').keys.sort
514
-
515
- end
516
- end
517
- end
518
-
519
- workers.each { |w| w.join }
520
- cache.flush
521
- end
522
- end
523
-
524
- it "handle namespaced keys" do
525
- memcached do |dc|
526
- dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
527
- dc.set('namespaced', 1)
528
- dc2 = Dalli::Client.new('localhost:19122', :namespace => 'b')
529
- dc2.set('namespaced', 2)
530
- assert_equal 1, dc.get('namespaced')
531
- assert_equal 2, dc2.get('namespaced')
532
- end
533
- end
534
-
535
- it "handle nil namespace" do
536
- memcached do |dc|
537
- dc = Dalli::Client.new('localhost:19122', :namespace => nil)
538
- assert_equal 'key', dc.send(:validate_key, 'key')
539
- end
540
- end
541
-
542
- it 'truncate cache keys that are too long' do
543
- memcached do
544
- dc = Dalli::Client.new('localhost:19122', :namespace => 'some:namspace')
545
- key = "this cache key is far too long so it must be hashed and truncated and stuff" * 10
546
- value = "some value"
547
- assert op_addset_succeeds(dc.set(key, value))
548
- assert_equal value, dc.get(key)
549
- end
550
- end
551
-
552
- it "handle namespaced keys in multi_get" do
553
- memcached do |dc|
554
- dc = Dalli::Client.new('localhost:19122', :namespace => 'a')
555
- dc.set('a', 1)
556
- dc.set('b', 2)
557
- assert_equal({'a' => 1, 'b' => 2}, dc.get_multi('a', 'b'))
558
- end
559
- end
560
-
561
- it "handle application marshalling issues" do
562
- memcached do |dc|
563
- old = Dalli.logger
564
- Dalli.logger = Logger.new(nil)
565
- begin
566
- assert_equal false, dc.set('a', Proc.new { true })
567
- ensure
568
- Dalli.logger = old
569
- end
570
- end
571
- end
572
-
573
- describe 'with compression' do
574
- it 'allow large values' do
575
- memcached do |dc|
576
- dalli = Dalli::Client.new(dc.instance_variable_get(:@servers), :compress => true)
577
-
578
- value = "0"*1024*1024
579
- assert_equal false, dc.set('verylarge', value)
580
- dalli.set('verylarge', value)
581
- end
582
- end
583
- end
584
-
585
- describe 'in low memory conditions' do
586
-
587
- it 'handle error response correctly' do
588
- memcached(19125, '-m 1 -M') do |dc|
589
- failed = false
590
- value = "1234567890"*100
591
- 1_000.times do |idx|
592
- begin
593
- assert op_addset_succeeds(dc.set(idx, value))
594
- rescue Dalli::DalliError
595
- failed = true
596
- assert((800..960).include?(idx), "unexpected failure on iteration #{idx}")
597
- break
598
- end
599
- end
600
- assert failed, 'did not fail under low memory conditions'
601
- end
602
- end
603
-
604
- it 'fit more values with compression' do
605
- memcached(19126, '-m 1 -M') do |dc|
606
- dalli = Dalli::Client.new('localhost:19126', :compress => true)
607
- failed = false
608
- value = "1234567890"*1000
609
- 10_000.times do |idx|
610
- begin
611
- assert op_addset_succeeds(dalli.set(idx, value))
612
- rescue Dalli::DalliError
613
- failed = true
614
- assert((6000..7800).include?(idx), "unexpected failure on iteration #{idx}")
615
- break
616
- end
617
- end
618
- assert failed, 'did not fail under low memory conditions'
619
- end
620
- end
621
-
622
- end
623
-
624
- end
625
- end
@@ -1,32 +0,0 @@
1
- # encoding: utf-8
2
- require 'helper'
3
- require 'memcached_mock'
4
-
5
- describe 'Encoding' do
6
-
7
- describe 'using a live server' do
8
- it 'support i18n content' do
9
- memcached do |dc|
10
- key = 'foo'
11
- utf_key = utf8 = 'ƒ©åÍÎ'
12
-
13
- assert dc.set(key, utf8)
14
- assert_equal utf8, dc.get(key)
15
-
16
- dc.set(utf_key, utf8)
17
- assert_equal utf8, dc.get(utf_key)
18
- end
19
- end
20
-
21
- it 'support content expiry' do
22
- memcached do |dc|
23
- key = 'foo'
24
- assert dc.set(key, 'bar', 1)
25
- assert_equal 'bar', dc.get(key)
26
- sleep 1.2
27
- assert_equal nil, dc.get(key)
28
- end
29
- end
30
-
31
- end
32
- end