PageRenderTime 3ms CodeModel.GetById 6ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/gems/memcache-client-1.5.0/test/test_mem_cache.rb

https://github.com/mnutt/hydraproject
Ruby | 744 lines | 688 code | 56 blank | 0 comment | 1 complexity | b0af50de7f6e230ac3529dedc2cbad2d MD5 | raw file
  1require 'stringio'
  2require 'test/unit'
  3require 'rubygems'
  4require 'test/zentest_assertions'
  5
  6$TESTING = true
  7
  8require 'memcache'
  9
 10class MemCache
 11
 12  attr_writer :namespace
 13
 14end
 15
 16class 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
 37end
 38
 39class 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
 58end
 59
 60class 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_equal '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
743end
744