ninjudd-ninjudd-memcache-client 1.5.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,744 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ require 'test/zentest_assertions'
5
+
6
+ $TESTING = true
7
+
8
+ require 'memcache'
9
+
10
+ class MemCache
11
+
12
+ attr_writer :namespace
13
+
14
+ end
15
+
16
+ class FakeSocket
17
+
18
+ attr_reader :written, :data
19
+
20
+ def initialize
21
+ @written = StringIO.new
22
+ @data = StringIO.new
23
+ end
24
+
25
+ def write(data)
26
+ @written.write data
27
+ end
28
+
29
+ def gets
30
+ @data.gets
31
+ end
32
+
33
+ def read(arg)
34
+ @data.read arg
35
+ end
36
+
37
+ end
38
+
39
+ class FakeServer
40
+
41
+ attr_reader :host, :port, :socket
42
+
43
+ def initialize(socket = nil)
44
+ @closed = false
45
+ @host = 'example.com'
46
+ @port = 11211
47
+ @socket = socket || FakeSocket.new
48
+ end
49
+
50
+ def close
51
+ @closed = true
52
+ end
53
+
54
+ def alive?
55
+ !@closed
56
+ end
57
+
58
+ end
59
+
60
+ class TestMemCache < Test::Unit::TestCase
61
+
62
+ def setup
63
+ @cache = MemCache.new 'localhost:1', :namespace => 'my_namespace'
64
+ end
65
+
66
+ def test_cache_get
67
+ server = util_setup_fake_server
68
+
69
+ assert_equal "\004\b\"\0170123456789",
70
+ @cache.cache_get(server, 'my_namespace:key')
71
+
72
+ assert_equal "get my_namespace:key\r\n",
73
+ server.socket.written.string
74
+ end
75
+
76
+ def test_cache_get_EOF
77
+ server = util_setup_fake_server
78
+ server.socket.data.string = ''
79
+
80
+ e = assert_raise MemCache::MemCacheError do
81
+ @cache.cache_get server, 'my_namespace:key'
82
+ end
83
+
84
+ assert_equal "lost connection to example.com:11211", e.message
85
+ end
86
+
87
+ def test_cache_get_bad_state
88
+ server = FakeServer.new
89
+ server.socket.data.write "bogus response\r\n"
90
+ server.socket.data.rewind
91
+
92
+ @cache.servers = []
93
+ @cache.servers << server
94
+
95
+ e = assert_raise MemCache::MemCacheError do
96
+ @cache.cache_get(server, 'my_namespace:key')
97
+ end
98
+
99
+ assert_equal "unexpected response \"bogus response\\r\\n\"", e.message
100
+
101
+ deny server.alive?
102
+
103
+ assert_equal "get my_namespace:key\r\n",
104
+ server.socket.written.string
105
+ end
106
+
107
+ def test_cache_get_miss
108
+ socket = FakeSocket.new
109
+ socket.data.write "END\r\n"
110
+ socket.data.rewind
111
+ server = FakeServer.new socket
112
+
113
+ assert_equal nil, @cache.cache_get(server, 'my_namespace:key')
114
+
115
+ assert_equal "get my_namespace:key\r\n",
116
+ socket.written.string
117
+ end
118
+
119
+ def test_cache_get_multi
120
+ server = util_setup_fake_server
121
+ server.socket.data.write "VALUE foo 0 7\r\n"
122
+ server.socket.data.write "\004\b\"\bfoo\r\n"
123
+ server.socket.data.write "VALUE bar 0 7\r\n"
124
+ server.socket.data.write "\004\b\"\bbar\r\n"
125
+ server.socket.data.write "END\r\n"
126
+ server.socket.data.rewind
127
+
128
+ result = @cache.cache_get_multi server, 'foo bar baz'
129
+
130
+ assert_equal 2, result.length
131
+ assert_equal "\004\b\"\bfoo", result['foo']
132
+ assert_equal "\004\b\"\bbar", result['bar']
133
+ end
134
+
135
+ def test_cache_get_multi_EOF
136
+ server = util_setup_fake_server
137
+ server.socket.data.string = ''
138
+
139
+ e = assert_raise MemCache::MemCacheError do
140
+ @cache.cache_get_multi server, 'my_namespace:key'
141
+ end
142
+
143
+ assert_equal "lost connection to example.com:11211", e.message
144
+ end
145
+
146
+ def test_cache_get_multi_bad_state
147
+ server = FakeServer.new
148
+ server.socket.data.write "bogus response\r\n"
149
+ server.socket.data.rewind
150
+
151
+ @cache.servers = []
152
+ @cache.servers << server
153
+
154
+ e = assert_raise MemCache::MemCacheError do
155
+ @cache.cache_get_multi server, 'my_namespace:key'
156
+ end
157
+
158
+ assert_equal "unexpected response \"bogus response\\r\\n\"", e.message
159
+
160
+ deny server.alive?
161
+
162
+ assert_equal "get my_namespace:key\r\n",
163
+ server.socket.written.string
164
+ end
165
+
166
+ def test_crc32_ITU_T
167
+ assert_equal 0, ''.crc32_ITU_T
168
+ assert_equal 1260851911, 'my_namespace:key'.crc32_ITU_T
169
+ end
170
+
171
+ def test_initialize
172
+ cache = MemCache.new :namespace => 'my_namespace', :readonly => true
173
+
174
+ assert_equal 'my_namespace', cache.namespace
175
+ assert_equal true, cache.readonly?
176
+ assert_equal true, cache.servers.empty?
177
+ end
178
+
179
+ def test_initialize_compatible
180
+ cache = MemCache.new ['localhost:11211', 'localhost:11212'],
181
+ :namespace => 'my_namespace', :readonly => true
182
+
183
+ assert_equal 'my_namespace', cache.namespace
184
+ assert_equal true, cache.readonly?
185
+ assert_equal false, cache.servers.empty?
186
+ end
187
+
188
+ def test_initialize_compatible_no_hash
189
+ cache = MemCache.new ['localhost:11211', 'localhost:11212']
190
+
191
+ assert_equal nil, cache.namespace
192
+ assert_equal false, cache.readonly?
193
+ assert_equal false, cache.servers.empty?
194
+ end
195
+
196
+ def test_initialize_compatible_one_server
197
+ cache = MemCache.new 'localhost:11211'
198
+
199
+ assert_equal nil, cache.namespace
200
+ assert_equal false, cache.readonly?
201
+ assert_equal false, cache.servers.empty?
202
+ end
203
+
204
+ def test_initialize_compatible_bad_arg
205
+ e = assert_raise ArgumentError do
206
+ cache = MemCache.new Object.new
207
+ end
208
+
209
+ assert_equal 'first argument must be Array, Hash or String', e.message
210
+ end
211
+
212
+ def test_initialize_multiple_servers
213
+ cache = MemCache.new %w[localhost:11211 localhost:11212],
214
+ :namespace => 'my_namespace', :readonly => true
215
+
216
+ assert_equal 'my_namespace', cache.namespace
217
+ assert_equal true, cache.readonly?
218
+ assert_equal false, cache.servers.empty?
219
+ deny_empty cache.instance_variable_get(:@buckets)
220
+ end
221
+
222
+ def test_initialize_too_many_args
223
+ assert_raises ArgumentError do
224
+ MemCache.new 1, 2, 3
225
+ end
226
+ end
227
+
228
+ def test_decr
229
+ server = FakeServer.new
230
+ server.socket.data.write "5\r\n"
231
+ server.socket.data.rewind
232
+
233
+ @cache.servers = []
234
+ @cache.servers << server
235
+
236
+ value = @cache.decr 'key'
237
+
238
+ assert_equal "decr my_namespace:key 1\r\n",
239
+ @cache.servers.first.socket.written.string
240
+
241
+ assert_equal 5, value
242
+ end
243
+
244
+ def test_decr_not_found
245
+ server = FakeServer.new
246
+ server.socket.data.write "NOT_FOUND\r\n"
247
+ server.socket.data.rewind
248
+
249
+ @cache.servers = []
250
+ @cache.servers << server
251
+
252
+ value = @cache.decr 'key'
253
+
254
+ assert_equal "decr my_namespace:key 1\r\n",
255
+ @cache.servers.first.socket.written.string
256
+
257
+ assert_equal nil, value
258
+ end
259
+
260
+ def test_decr_space_padding
261
+ server = FakeServer.new
262
+ server.socket.data.write "5 \r\n"
263
+ server.socket.data.rewind
264
+
265
+ @cache.servers = []
266
+ @cache.servers << server
267
+
268
+ value = @cache.decr 'key'
269
+
270
+ assert_equal "decr my_namespace:key 1\r\n",
271
+ @cache.servers.first.socket.written.string
272
+
273
+ assert_equal 5, value
274
+ end
275
+
276
+ def test_get
277
+ util_setup_fake_server
278
+
279
+ value = @cache.get 'key'
280
+
281
+ assert_equal "get my_namespace:key\r\n",
282
+ @cache.servers.first.socket.written.string
283
+
284
+ assert_equal '0123456789', value
285
+ end
286
+
287
+ def test_get_bad_key
288
+ util_setup_fake_server
289
+ assert_raise ArgumentError do @cache.get 'k y' end
290
+
291
+ util_setup_fake_server
292
+ assert_raise ArgumentError do @cache.get 'k' * 250 end
293
+ end
294
+
295
+ def test_get_cache_get_IOError
296
+ socket = Object.new
297
+ def socket.write(arg) raise IOError, 'some io error'; end
298
+ server = FakeServer.new socket
299
+
300
+ @cache.servers = []
301
+ @cache.servers << server
302
+
303
+ e = assert_raise MemCache::MemCacheError do
304
+ @cache.get 'my_namespace:key'
305
+ end
306
+
307
+ assert_equal 'some io error', e.message
308
+ end
309
+
310
+ def test_get_cache_get_SystemCallError
311
+ socket = Object.new
312
+ def socket.write(arg) raise SystemCallError, 'some syscall error'; end
313
+ server = FakeServer.new socket
314
+
315
+ @cache.servers = []
316
+ @cache.servers << server
317
+
318
+ e = assert_raise MemCache::MemCacheError do
319
+ @cache.get 'my_namespace:key'
320
+ end
321
+
322
+ assert_equal 'unknown error - some syscall error', e.message
323
+ end
324
+
325
+ def test_get_no_connection
326
+ @cache.servers = 'localhost:1'
327
+ e = assert_raise MemCache::MemCacheError do
328
+ @cache.get 'key'
329
+ end
330
+
331
+ assert_match /^No connection to server/, e.message
332
+ end
333
+
334
+ def test_get_no_servers
335
+ @cache.servers = []
336
+ e = assert_raise MemCache::MemCacheError do
337
+ @cache.get 'key'
338
+ end
339
+
340
+ assert_equal 'No active servers', e.message
341
+ end
342
+
343
+ def test_get_multi
344
+ server = FakeServer.new
345
+ server.socket.data.write "VALUE my_namespace:key 0 14\r\n"
346
+ server.socket.data.write "\004\b\"\0170123456789\r\n"
347
+ server.socket.data.write "VALUE my_namespace:keyb 0 14\r\n"
348
+ server.socket.data.write "\004\b\"\0179876543210\r\n"
349
+ server.socket.data.write "END\r\n"
350
+ server.socket.data.rewind
351
+
352
+ @cache.servers = []
353
+ @cache.servers << server
354
+
355
+ values = @cache.get_multi 'key', 'keyb'
356
+
357
+ assert_equal "get my_namespace:key my_namespace:keyb\r\n",
358
+ server.socket.written.string
359
+
360
+ expected = { 'key' => '0123456789', 'keyb' => '9876543210' }
361
+
362
+ assert_equal expected.sort, values.sort
363
+ end
364
+
365
+ def test_get_raw
366
+ server = FakeServer.new
367
+ server.socket.data.write "VALUE my_namespace:key 0 10\r\n"
368
+ server.socket.data.write "0123456789\r\n"
369
+ server.socket.data.write "END\r\n"
370
+ server.socket.data.rewind
371
+
372
+ @cache.servers = []
373
+ @cache.servers << server
374
+
375
+
376
+ value = @cache.get 'key', true
377
+
378
+ assert_equal "get my_namespace:key\r\n",
379
+ @cache.servers.first.socket.written.string
380
+
381
+ assert_equal '0123456789', value
382
+ end
383
+
384
+ def test_get_server_for_key
385
+ server = @cache.get_server_for_key 'key'
386
+ assert_equal 'localhost', server.host
387
+ assert_equal 1, server.port
388
+ end
389
+
390
+ def test_get_server_for_key_multiple
391
+ s1 = util_setup_server @cache, 'one.example.com', ''
392
+ s2 = util_setup_server @cache, 'two.example.com', ''
393
+ @cache.instance_variable_set :@servers, [s1, s2]
394
+ @cache.instance_variable_set :@buckets, [s1, s2]
395
+
396
+ server = @cache.get_server_for_key 'keya'
397
+ assert_equal 'two.example.com', server.host
398
+ server = @cache.get_server_for_key 'keyb'
399
+ assert_equal 'one.example.com', server.host
400
+ end
401
+
402
+ def test_get_server_for_key_no_servers
403
+ @cache.servers = []
404
+
405
+ e = assert_raise MemCache::MemCacheError do
406
+ @cache.get_server_for_key 'key'
407
+ end
408
+
409
+ assert_equal 'No servers available', e.message
410
+ end
411
+
412
+ def test_get_server_for_key_spaces
413
+ e = assert_raise ArgumentError do
414
+ @cache.get_server_for_key 'space key'
415
+ end
416
+ assert_equal 'illegal character in key "space key"', e.message
417
+ end
418
+
419
+ def test_get_server_for_key_length
420
+ @cache.get_server_for_key 'x' * 250
421
+ long_key = 'x' * 251
422
+ e = assert_raise ArgumentError do
423
+ @cache.get_server_for_key long_key
424
+ end
425
+ assert_equal "key too long #{long_key.inspect}", e.message
426
+ end
427
+
428
+ def test_incr
429
+ server = FakeServer.new
430
+ server.socket.data.write "5\r\n"
431
+ server.socket.data.rewind
432
+
433
+ @cache.servers = []
434
+ @cache.servers << server
435
+
436
+ value = @cache.incr 'key'
437
+
438
+ assert_equal "incr my_namespace:key 1\r\n",
439
+ @cache.servers.first.socket.written.string
440
+
441
+ assert_equal 5, value
442
+ end
443
+
444
+ def test_incr_not_found
445
+ server = FakeServer.new
446
+ server.socket.data.write "NOT_FOUND\r\n"
447
+ server.socket.data.rewind
448
+
449
+ @cache.servers = []
450
+ @cache.servers << server
451
+
452
+ value = @cache.incr 'key'
453
+
454
+ assert_equal "incr my_namespace:key 1\r\n",
455
+ @cache.servers.first.socket.written.string
456
+
457
+ assert_equal nil, value
458
+ end
459
+
460
+ def test_incr_space_padding
461
+ server = FakeServer.new
462
+ server.socket.data.write "5 \r\n"
463
+ server.socket.data.rewind
464
+
465
+ @cache.servers = []
466
+ @cache.servers << server
467
+
468
+ value = @cache.incr 'key'
469
+
470
+ assert_equal "incr my_namespace:key 1\r\n",
471
+ @cache.servers.first.socket.written.string
472
+
473
+ assert_equal 5, value
474
+ end
475
+
476
+ def test_make_cache_key
477
+ assert_equal 'my_namespace:key', @cache.make_cache_key('key')
478
+ @cache.namespace = nil
479
+ assert_equal 'key', @cache.make_cache_key('key')
480
+ end
481
+
482
+ def test_servers
483
+ server = FakeServer.new
484
+ @cache.servers = []
485
+ @cache.servers << server
486
+ assert_equal [server], @cache.servers
487
+ end
488
+
489
+ def test_servers_equals_type_error
490
+ e = assert_raise TypeError do
491
+ @cache.servers = [Object.new]
492
+ end
493
+
494
+ assert_equal 'cannot convert Object into MemCache::Server', e.message
495
+ end
496
+
497
+ def test_set
498
+ server = FakeServer.new
499
+ server.socket.data.write "STORED\r\n"
500
+ server.socket.data.rewind
501
+ @cache.servers = []
502
+ @cache.servers << server
503
+
504
+ @cache.set 'key', 'value'
505
+
506
+ expected = "set my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
507
+ assert_equal expected, server.socket.written.string
508
+ end
509
+
510
+ def test_set_expiry
511
+ server = FakeServer.new
512
+ server.socket.data.write "STORED\r\n"
513
+ server.socket.data.rewind
514
+ @cache.servers = []
515
+ @cache.servers << server
516
+
517
+ @cache.set 'key', 'value', 5
518
+
519
+ expected = "set my_namespace:key 0 5 9\r\n\004\b\"\nvalue\r\n"
520
+ assert_equal expected, server.socket.written.string
521
+ end
522
+
523
+ def test_set_raw
524
+ server = FakeServer.new
525
+ server.socket.data.write "STORED\r\n"
526
+ server.socket.data.rewind
527
+ @cache.servers = []
528
+ @cache.servers << server
529
+
530
+ @cache.set 'key', 'value', 0, true
531
+
532
+ expected = "set my_namespace:key 0 0 5\r\nvalue\r\n"
533
+ assert_equal expected, server.socket.written.string
534
+ end
535
+
536
+ def test_set_readonly
537
+ cache = MemCache.new :readonly => true
538
+
539
+ e = assert_raise MemCache::MemCacheError do
540
+ cache.set 'key', 'value'
541
+ end
542
+
543
+ assert_equal 'Update of readonly cache', e.message
544
+ end
545
+
546
+ def test_set_too_big
547
+ server = FakeServer.new
548
+ server.socket.data.write "SERVER_ERROR object too large for cache\r\n"
549
+ server.socket.data.rewind
550
+ @cache.servers = []
551
+ @cache.servers << server
552
+
553
+ e = assert_raise MemCache::MemCacheError do
554
+ @cache.set 'key', 'v'
555
+ end
556
+
557
+ assert_equal 'object too large for cache', e.message
558
+ end
559
+
560
+ def test_add
561
+ server = FakeServer.new
562
+ server.socket.data.write "STORED\r\n"
563
+ server.socket.data.rewind
564
+ @cache.servers = []
565
+ @cache.servers << server
566
+
567
+ @cache.add 'key', 'value'
568
+
569
+ expected = "add my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
570
+ assert_equal expected, server.socket.written.string
571
+ end
572
+
573
+ def test_add_exists
574
+ server = FakeServer.new
575
+ server.socket.data.write "NOT_STORED\r\n"
576
+ server.socket.data.rewind
577
+ @cache.servers = []
578
+ @cache.servers << server
579
+
580
+ @cache.add 'key', 'value'
581
+
582
+ expected = "add my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
583
+ assert_equal expected, server.socket.written.string
584
+ end
585
+
586
+ def test_add_expiry
587
+ server = FakeServer.new
588
+ server.socket.data.write "STORED\r\n"
589
+ server.socket.data.rewind
590
+ @cache.servers = []
591
+ @cache.servers << server
592
+
593
+ @cache.add 'key', 'value', 5
594
+
595
+ expected = "add my_namespace:key 0 5 9\r\n\004\b\"\nvalue\r\n"
596
+ assert_equal expected, server.socket.written.string
597
+ end
598
+
599
+ def test_add_raw
600
+ server = FakeServer.new
601
+ server.socket.data.write "STORED\r\n"
602
+ server.socket.data.rewind
603
+ @cache.servers = []
604
+ @cache.servers << server
605
+
606
+ @cache.add 'key', 'value', 0, true
607
+
608
+ expected = "add my_namespace:key 0 0 5\r\nvalue\r\n"
609
+ assert_equal expected, server.socket.written.string
610
+ end
611
+
612
+ def test_add_readonly
613
+ cache = MemCache.new :readonly => true
614
+
615
+ e = assert_raise MemCache::MemCacheError do
616
+ cache.add 'key', 'value'
617
+ end
618
+
619
+ assert_equal 'Update of readonly cache', e.message
620
+ end
621
+
622
+ def test_delete
623
+ server = FakeServer.new
624
+ @cache.servers = []
625
+ @cache.servers << server
626
+
627
+ @cache.delete 'key'
628
+
629
+ expected = "delete my_namespace:key 0\r\n"
630
+ assert_equal expected, server.socket.written.string
631
+ end
632
+
633
+ def test_delete_with_expiry
634
+ server = FakeServer.new
635
+ @cache.servers = []
636
+ @cache.servers << server
637
+
638
+ @cache.delete 'key', 300
639
+
640
+ expected = "delete my_namespace:key 300\r\n"
641
+ assert_equal expected, server.socket.written.string
642
+ end
643
+
644
+ def test_flush_all
645
+ @cache.servers = []
646
+ 3.times { @cache.servers << FakeServer.new }
647
+
648
+ @cache.flush_all
649
+
650
+ expected = "flush_all\r\n"
651
+ @cache.servers.each do |server|
652
+ assert_equal expected, server.socket.written.string
653
+ end
654
+ end
655
+
656
+ def test_flush_all_failure
657
+ socket = FakeSocket.new
658
+ socket.data.write "ERROR\r\n"
659
+ socket.data.rewind
660
+ server = FakeServer.new socket
661
+ def server.host() "localhost"; end
662
+ def server.port() 11211; end
663
+
664
+ @cache.servers = []
665
+ @cache.servers << server
666
+
667
+ assert_raise MemCache::MemCacheError do
668
+ @cache.flush_all
669
+ end
670
+
671
+ assert_equal "flush_all\r\n", socket.written.string
672
+ end
673
+
674
+ def test_stats
675
+ socket = FakeSocket.new
676
+ socket.data.write "STAT pid 20188\r\nSTAT total_items 32\r\nSTAT version 1.2.3\r\nSTAT rusage_user 1:300\r\nSTAT dummy ok\r\nEND\r\n"
677
+ socket.data.rewind
678
+ server = FakeServer.new socket
679
+ def server.host() 'localhost'; end
680
+ def server.port() 11211; end
681
+
682
+ @cache.servers = []
683
+ @cache.servers << server
684
+
685
+ expected = {
686
+ 'localhost:11211' => {
687
+ 'pid' => 20188, 'total_items' => 32, 'version' => '1.2.3',
688
+ 'rusage_user' => 1.0003, 'dummy' => 'ok'
689
+ }
690
+ }
691
+ assert_equal expected, @cache.stats
692
+
693
+ assert_equal "stats\r\n", socket.written.string
694
+ end
695
+
696
+ def test_basic_threaded_operations_should_work
697
+ cache = MemCache.new :multithread => true,
698
+ :namespace => 'my_namespace',
699
+ :readonly => false
700
+ server = util_setup_server cache, 'example.com', "OK\r\n"
701
+ cache.instance_variable_set :@servers, [server]
702
+
703
+ assert_nothing_raised do
704
+ cache.set "test", "test value"
705
+ end
706
+ end
707
+
708
+ def test_basic_unthreaded_operations_should_work
709
+ cache = MemCache.new :multithread => false,
710
+ :namespace => 'my_namespace',
711
+ :readonly => false
712
+ server = util_setup_server cache, 'example.com', "OK\r\n"
713
+ cache.instance_variable_set :@servers, [server]
714
+
715
+ assert_nothing_raised do
716
+ cache.set "test", "test value"
717
+ end
718
+ end
719
+
720
+ def util_setup_fake_server
721
+ server = FakeServer.new
722
+ server.socket.data.write "VALUE my_namespace:key 0 14\r\n"
723
+ server.socket.data.write "\004\b\"\0170123456789\r\n"
724
+ server.socket.data.write "END\r\n"
725
+ server.socket.data.rewind
726
+
727
+ @cache.servers = []
728
+ @cache.servers << server
729
+
730
+ return server
731
+ end
732
+
733
+ def util_setup_server(memcache, host, responses)
734
+ server = MemCache::Server.new memcache, host
735
+ server.instance_variable_set :@sock, StringIO.new(responses)
736
+
737
+ @cache.servers = []
738
+ @cache.servers << server
739
+
740
+ return server
741
+ end
742
+
743
+ end
744
+