memcached 0.10 → 0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,7 +44,7 @@ class Bench
44
44
  {
45
45
  :buffer_requests => false,
46
46
  :no_block => false,
47
- :namespace => "benchmark_namespace"
47
+ :namespace => "namespace"
48
48
  }
49
49
  ]
50
50
  @key1 = "Short"
@@ -8,7 +8,7 @@ require 'ruby-prof'
8
8
 
9
9
  @cache = Memcached.new(
10
10
  '127.0.0.1:43042', '127.0.0.1:43043'],
11
- :namespace => "benchmark_namespace"
11
+ :namespace => "namespace"
12
12
  )
13
13
 
14
14
  result = RubyProf.profile do
@@ -21,7 +21,7 @@ class Worker
21
21
  {
22
22
  :buffer_requests => false,
23
23
  :no_block => false,
24
- :namespace => "benchmark_namespace"
24
+ :namespace => "namespace"
25
25
  }
26
26
  ]
27
27
  system("ruby #{HERE}/../setup.rb")
@@ -4,18 +4,20 @@ require "#{File.dirname(__FILE__)}/../test_helper"
4
4
  class MemcachedTest < Test::Unit::TestCase
5
5
 
6
6
  def setup
7
- @servers = ['127.0.0.1:43042', '127.0.0.1:43043']
8
- @namespace = 'memcached_test_namespace'
7
+ @servers = ['localhost:43042', 'localhost:43043']
8
+
9
+ # Maximum allowed prefix key size
10
+ @prefix_key = 'prefix_key_'
9
11
 
10
12
  @options = {
11
- :namespace => @namespace,
13
+ :prefix_key => @prefix_key,
12
14
  :hash => :default,
13
15
  :distribution => :modula
14
16
  }
15
17
  @cache = Memcached.new(@servers, @options)
16
18
 
17
19
  @nb_options = {
18
- :namespace => @namespace,
20
+ :prefix_key => @prefix_key,
19
21
  :no_block => true,
20
22
  :buffer_requests => true,
21
23
  :hash => :default
@@ -25,24 +27,30 @@ class MemcachedTest < Test::Unit::TestCase
25
27
  @value = OpenStruct.new(:a => 1, :b => 2, :c => GenericClass)
26
28
  @marshalled_value = Marshal.dump(@value)
27
29
  end
28
-
29
- def teardown
30
- ObjectSpace.each_object(Memcached) do |cache|
31
- cache.destroy rescue Memcached::ClientError
32
- end
33
- end
34
-
30
+
35
31
  # Initialize
36
32
 
37
33
  def test_initialize
38
- cache = Memcached.new @servers, :namespace => 'test'
39
- assert_equal 'test', cache.options[:namespace]
34
+ cache = Memcached.new @servers, :prefix_key => 'test'
35
+ assert_equal 'test', cache.options[:prefix_key]
40
36
  assert_equal 2, cache.send(:server_structs).size
37
+ assert_equal 'localhost', cache.send(:server_structs).first.hostname
38
+ assert_equal 'localhost', cache.send(:server_structs).last.hostname
39
+ assert_equal 43043, cache.send(:server_structs).last.port
40
+ end
41
+
42
+ def test_initialize_with_ip_addresses
43
+ cache = Memcached.new ['127.0.0.1:43042', '127.0.0.1:43043'], :prefix_key => 'test'
41
44
  assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
42
45
  assert_equal '127.0.0.1', cache.send(:server_structs).last.hostname
43
- assert_equal 43043, cache.send(:server_structs).last.port
44
46
  end
45
47
 
48
+ def test_initialize_without_port
49
+ cache = Memcached.new ['localhost'], :prefix_key => 'test'
50
+ assert_equal 'localhost', cache.send(:server_structs).first.hostname
51
+ assert_equal 11211, cache.send(:server_structs).first.port
52
+ end
53
+
46
54
  def test_options_are_set
47
55
  Memcached::DEFAULTS.merge(@nb_options).each do |key, expected|
48
56
  value = @nb_cache.options[key]
@@ -55,19 +63,29 @@ class MemcachedTest < Test::Unit::TestCase
55
63
  @cache.options[:no_block] = true
56
64
  end
57
65
  end
58
-
59
- def test_destroy
60
- cache = Memcached.new @servers, :namespace => 'test'
61
- cache.destroy
62
- assert_raise(Memcached::ClientError) do
63
- cache.get key
66
+
67
+ def test_behaviors_are_set
68
+ Memcached::BEHAVIORS.keys.each do |key, value|
69
+ assert_not_nil @cache.send(:get_behavior, key)
64
70
  end
65
71
  end
66
-
72
+
67
73
  def test_initialize_with_invalid_server_strings
68
- assert_raise(ArgumentError) { Memcached.new "localhost:43042" }
69
- assert_raise(ArgumentError) { Memcached.new "127.0.0.1:memcached" }
70
- assert_raise(ArgumentError) { Memcached.new "127.0.0.1:43043:1" }
74
+ assert_raise(ArgumentError) { Memcached.new ":43042" }
75
+ assert_raise(ArgumentError) { Memcached.new "localhost:memcached" }
76
+ assert_raise(ArgumentError) { Memcached.new "local host:43043:1" }
77
+ end
78
+
79
+ if ENV['USER'] == "eweaver"
80
+ def test_initialize_with_resolvable_hosts
81
+ `hostname` =~ /(chloe|mackenzie)/
82
+ host = "#{$1}.lan"
83
+ cache = Memcached.new ["#{host}:43042"]
84
+ assert_equal host, cache.send(:server_structs).first.hostname
85
+
86
+ cache.set(key, @value)
87
+ assert_equal @value, cache.get(key)
88
+ end
71
89
  end
72
90
 
73
91
  def test_initialize_with_invalid_options
@@ -75,10 +93,16 @@ class MemcachedTest < Test::Unit::TestCase
75
93
  Memcached.new @servers, :sort_hosts => true, :distribution => :consistent
76
94
  end
77
95
  end
96
+
97
+ def test_initialize_with_invalid_prefix_key
98
+ assert_raise(ArgumentError) do
99
+ Memcached.new @servers, :prefix_key => "prefix_key__"
100
+ end
101
+ end
78
102
 
79
- def test_initialize_without_namespace
103
+ def test_initialize_without_prefix_key
80
104
  cache = Memcached.new @servers
81
- assert_equal nil, cache.options[:namespace]
105
+ assert_equal nil, cache.options[:prefix_key]
82
106
  assert_equal 2, cache.send(:server_structs).size
83
107
  end
84
108
 
@@ -120,7 +144,6 @@ class MemcachedTest < Test::Unit::TestCase
120
144
  )
121
145
  assert_equal @servers.sort,
122
146
  cache.servers
123
- cache.destroy
124
147
 
125
148
  # Original with sort_hosts
126
149
  cache = Memcached.new(@servers.sort,
@@ -129,7 +152,6 @@ class MemcachedTest < Test::Unit::TestCase
129
152
  )
130
153
  assert_equal @servers.sort,
131
154
  cache.servers
132
- cache.destroy
133
155
 
134
156
  # Reversed
135
157
  cache = Memcached.new(@servers.sort.reverse,
@@ -138,7 +160,6 @@ class MemcachedTest < Test::Unit::TestCase
138
160
  )
139
161
  assert_equal @servers.sort.reverse,
140
162
  cache.servers
141
- cache.destroy
142
163
 
143
164
  # Reversed with sort_hosts
144
165
  cache = Memcached.new(@servers.sort.reverse,
@@ -147,12 +168,11 @@ class MemcachedTest < Test::Unit::TestCase
147
168
  )
148
169
  assert_equal @servers.sort,
149
170
  cache.servers
150
- cache.destroy
151
171
  end
152
172
 
153
173
  def test_initialize_single_server
154
- cache = Memcached.new '127.0.0.1:43042'
155
- assert_equal nil, cache.options[:namespace]
174
+ cache = Memcached.new 'localhost:43042'
175
+ assert_equal nil, cache.options[:prefix_key]
156
176
  assert_equal 1, cache.send(:server_structs).size
157
177
  end
158
178
 
@@ -167,16 +187,6 @@ class MemcachedTest < Test::Unit::TestCase
167
187
  result = @cache.get key
168
188
  assert_equal @value, result
169
189
  end
170
-
171
- def test_get_with_namespace
172
- @cache.set key, @value
173
- result = @cache.get key, false
174
- direct_result = Rlibmemcached.memcached_get(
175
- @cache.instance_variable_get("@struct"),
176
- "#{@namespace}#{key}"
177
- ).first
178
- assert_equal result, direct_result
179
- end
180
190
 
181
191
  def test_get_nil
182
192
  @cache.set key, nil, 0
@@ -190,6 +200,29 @@ class MemcachedTest < Test::Unit::TestCase
190
200
  result = @cache.get key
191
201
  end
192
202
  end
203
+
204
+ def test_get_with_prefix_key
205
+ # Prefix_key
206
+ cache = Memcached.new(
207
+ # We can only use one server because the key is hashed separately from the prefix key
208
+ @servers.first,
209
+ :prefix_key => @prefix_key,
210
+ :hash => :default,
211
+ :distribution => :modula
212
+ )
213
+ cache.set key, @value
214
+ assert_equal @value, cache.get(key)
215
+
216
+ # No prefix_key specified
217
+ cache = Memcached.new(
218
+ @servers.first,
219
+ :hash => :default,
220
+ :distribution => :modula
221
+ )
222
+ assert_nothing_raised do
223
+ assert_equal @value, cache.get("#{@prefix_key}#{key}")
224
+ end
225
+ end
193
226
 
194
227
  def test_values_with_null_characters_are_not_truncated
195
228
  value = OpenStruct.new(:a => Object.new) # Marshals with a null \000
@@ -197,7 +230,7 @@ class MemcachedTest < Test::Unit::TestCase
197
230
  result = @cache.get key, false
198
231
  non_wrapped_result = Rlibmemcached.memcached_get(
199
232
  @cache.instance_variable_get("@struct"),
200
- "#{@namespace}#{key}"
233
+ key
201
234
  ).first
202
235
  assert result.size > non_wrapped_result.size
203
236
  end
@@ -268,7 +301,7 @@ class MemcachedTest < Test::Unit::TestCase
268
301
  assert_nothing_raised do
269
302
  @cache.get key
270
303
  end
271
- sleep(1)
304
+ sleep(2)
272
305
  assert_raise(Memcached::NotFound) do
273
306
  @cache.get key
274
307
  end
@@ -434,7 +467,7 @@ class MemcachedTest < Test::Unit::TestCase
434
467
  def test_cas
435
468
  cache = Memcached.new(
436
469
  @servers,
437
- :namespace => @namespace,
470
+ :prefix_key => @prefix_key,
438
471
  :support_cas => true
439
472
  )
440
473
  value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
@@ -468,81 +501,60 @@ class MemcachedTest < Test::Unit::TestCase
468
501
  current
469
502
  end
470
503
  end
471
-
472
- cache.destroy
473
504
  end
474
-
475
- # Namespace and key validation
476
-
477
- def test_ns
478
- assert_equal "#{@namespace}i_have_a_space",
479
- Rlibmemcached.ns(@namespace, "i have a space")
480
-
481
- # STR2CSTR doesn't handle strings with nulls very well, so this is what happens
482
- assert_equal "#{@namespace}with_____",
483
- Rlibmemcached.ns(@namespace, "with\000null")
484
-
485
- assert_equal "#{@namespace}ch__teau",
486
- Rlibmemcached.ns(@namespace, "ch\303\242teau")
487
-
488
- assert_equal "#{@namespace}#{'x'*251}"[0..249],
489
- Rlibmemcached.ns(@namespace, 'x'*251)
490
- end
491
-
505
+
492
506
  # Error states
493
507
 
494
508
  def test_key_with_spaces
495
- value = "value"
496
509
  key = "i have a space"
497
- assert_nothing_raised do
498
- @cache.set key, value
510
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
511
+ @cache.set key, @value
499
512
  end
500
- assert_nothing_raised do
501
- assert_equal(value, @cache.get(key))
513
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
514
+ @cache.get(key)
502
515
  end
503
- # Spaces were stripped
504
- assert_not_equal(key,
505
- @cache.get([key]).keys.first)
506
516
  end
507
517
 
508
518
  def test_key_with_null
509
- value = "value"
510
519
  key = "with\000null"
511
- assert_nothing_raised do
512
- @cache.set key, value
520
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
521
+ @cache.set key, @value
513
522
  end
514
- assert_nothing_raised do
515
- assert_equal(value, @cache.get(key))
523
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
524
+ @cache.get(key)
525
+ end
526
+
527
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
528
+ response = @cache.get([key])
516
529
  end
517
- # Multiget returns
518
- response = @cache.get([key])
519
- assert_equal 1, response.size
520
- # Nulls were stripped
521
- assert_not_equal(key, response.keys.first)
522
530
  end
523
531
 
524
- def test_key_with_valid_control_characters
525
- value = "value"
532
+ def test_key_with_invalid_control_characters
526
533
  key = "ch\303\242teau"
527
- @cache.set key, value
528
- assert_equal(value,
529
- @cache.get(key))
530
- assert_not_equal(key,
531
- @cache.get([key]).keys.first)
534
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
535
+ @cache.set key, @value
536
+ end
537
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
538
+ @cache.get(key)
539
+ end
540
+
541
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
542
+ response = @cache.get([key])
543
+ end
532
544
  end
533
545
 
534
546
  def test_key_too_long
535
547
  key = "x"*251
536
- assert_nothing_raised do
548
+ assert_raises(Memcached::ClientError) do
537
549
  @cache.set key, @value
538
550
  end
539
- assert_nothing_raised do
540
- assert_equal(@value,
541
- @cache.get(key))
551
+ assert_raises(Memcached::ClientError) do
552
+ @cache.get(key)
553
+ end
554
+
555
+ assert_raises(Memcached::ClientError) do
556
+ @cache.get([key])
542
557
  end
543
- # Key was truncated
544
- assert_not_equal(key,
545
- @cache.get([key]).keys.first)
546
558
  end
547
559
 
548
560
  def test_set_object_too_large
@@ -568,7 +580,9 @@ class MemcachedTest < Test::Unit::TestCase
568
580
  assert_not_equal cache, @cache
569
581
 
570
582
  # Definitely check that the structs are unlinked
571
- cache.destroy
583
+ assert_not_equal @cache.instance_variable_get('@struct').object_id,
584
+ cache.instance_variable_get('@struct').object_id
585
+
572
586
  assert_nothing_raised do
573
587
  @cache.set key, @value
574
588
  end
@@ -584,7 +598,7 @@ class MemcachedTest < Test::Unit::TestCase
584
598
  end
585
599
  ret = Rlibmemcached.memcached_set(
586
600
  cache.instance_variable_get("@struct"),
587
- "#{@namespace}#{key}",
601
+ key,
588
602
  @marshalled_value,
589
603
  0,
590
604
  Memcached::FLAGS
@@ -598,7 +612,7 @@ class MemcachedTest < Test::Unit::TestCase
598
612
  end
599
613
  ret = Rlibmemcached.memcached_set(
600
614
  @nb_cache.instance_variable_get("@struct"),
601
- "#{@namespace}#{key}",
615
+ key,
602
616
  @marshalled_value,
603
617
  0,
604
618
  Memcached::FLAGS
@@ -614,7 +628,7 @@ class MemcachedTest < Test::Unit::TestCase
614
628
  end
615
629
 
616
630
  def test_no_block_set_invalid_key
617
- assert_nothing_raised do
631
+ assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
618
632
  @nb_cache.set "I'm so bad", @value
619
633
  end
620
634
  end
@@ -636,40 +650,47 @@ class MemcachedTest < Test::Unit::TestCase
636
650
  # Server removal and consistent hashing
637
651
 
638
652
  def test_missing_server
639
- # XXX Does this test actually do anything? :hash behaves oddly
640
653
  cache = Memcached.new(
641
- [@servers.last, '127.0.0.1:43041'], # Use a server that isn't running
642
- :namespace => @namespace,
654
+ [@servers.last, 'localhost:43041'], # Use a server that isn't running
655
+ :prefix_key => @prefix_key,
643
656
  :failover => true,
644
657
  :hash => :md5
645
658
  )
646
659
 
647
- # Verify that the second server is the hash target
660
+ # Hit first server
648
661
  key = 'test_missing_server3'
649
- assert_equal 1, cache.send(:hash, key)
650
-
662
+ cache.set(key, @value)
663
+ cache.get(key) == @value
664
+
665
+ # Hit second server
666
+ key = 'test_missing_server'
651
667
  assert_raise(Memcached::SystemError) do
652
668
  cache.set(key, @value)
653
669
  cache.get(key)
654
670
  end
655
671
 
656
- # Verify that we are targeting the first server now
657
- assert_equal 0, cache.send(:hash, key)
658
-
672
+ # Hit first server on retry
659
673
  assert_nothing_raised do
660
674
  cache.set(key, @value)
661
675
  cache.get(key)
662
676
  end
663
677
  end
664
678
 
679
+ def test_sweep_servers_with_missing_server_first
680
+ cache = Memcached.new(['127.0.0.1:00000'] + @servers)
681
+ assert_nothing_raised do
682
+ cache.send(:sweep_servers)
683
+ end
684
+ end
685
+
665
686
  def test_consistent_hashing
666
687
 
667
688
  keys = %w(EN6qtgMW n6Oz2W4I ss4A8Brr QShqFLZt Y3hgP9bs CokDD4OD Nd3iTSE1 24vBV4AU H9XBUQs5 E5j8vUq1 AzSh8fva PYBlK2Pi Ke3TgZ4I AyAIYanO oxj8Xhyd eBFnE6Bt yZyTikWQ pwGoU7Pw 2UNDkKRN qMJzkgo2 keFXbQXq pBl2QnIg ApRl3mWY wmalTJW1 TLueug8M wPQL4Qfg uACwus23 nmOk9R6w lwgZJrzJ v1UJtKdG RK629Cra U2UXFRqr d9OQLNl8 KAm1K3m5 Z13gKZ1v tNVai1nT LhpVXuVx pRib1Itj I1oLUob7 Z1nUsd5Q ZOwHehUa aXpFX29U ZsnqxlGz ivQRjOdb mB3iBEAj)
668
689
 
669
690
  # Five servers
670
691
  cache = Memcached.new(
671
- @servers + ['127.0.0.1:43044', '127.0.0.1:43045', '127.0.0.1:43046'],
672
- :namespace => @namespace
692
+ @servers + ['localhost:43044', 'localhost:43045', 'localhost:43046'],
693
+ :prefix_key => @prefix_key
673
694
  )
674
695
 
675
696
  cache.flush
@@ -679,8 +700,8 @@ class MemcachedTest < Test::Unit::TestCase
679
700
 
680
701
  # Pull a server
681
702
  cache = Memcached.new(
682
- @servers + ['127.0.0.1:43044', '127.0.0.1:43046'],
683
- :namespace => @namespace
703
+ @servers + ['localhost:43044', 'localhost:43046'],
704
+ :prefix_key => @prefix_key
684
705
  )
685
706
 
686
707
  failed = 0
@@ -721,13 +742,7 @@ class MemcachedTest < Test::Unit::TestCase
721
742
  assert_not_equal original_struct,
722
743
  @cache.instance_variable_get("@struct")
723
744
  end
724
-
725
- # Private hash generation method
726
-
727
- def test_hash_generation
728
- assert [0, 1].include?(@cache.send(:hash, key))
729
- end
730
-
745
+
731
746
  private
732
747
 
733
748
  def key