dalli 2.7.0 → 2.7.11

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